Skip to content

Commit 9b7888e

Browse files
refackindutny
authored andcommitted
src: fix StringBytes::Write if string is external
Signed-off-by: Fedor Indutny <fedor@indutny.com>
1 parent 5344d0c commit 9b7888e

3 files changed

Lines changed: 130 additions & 2 deletions

File tree

src/string_bytes.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ size_t StringBytes::Write(Isolate* isolate,
300300
const char* data = NULL;
301301
size_t len = 0;
302302
bool is_extern = GetExternalParts(isolate, val, &data, &len);
303+
size_t extlen = len;
303304

304305
CHECK(val->IsString() == true);
305306
Local<String> str = val.As<String>();
@@ -342,7 +343,7 @@ size_t StringBytes::Write(Isolate* isolate,
342343

343344
case BASE64:
344345
if (is_extern) {
345-
base64_decode(buf, buflen, data, len);
346+
len = base64_decode(buf, buflen, data, extlen);
346347
} else {
347348
String::Value value(str);
348349
len = base64_decode(buf, buflen, *value, value.length());
@@ -354,7 +355,7 @@ size_t StringBytes::Write(Isolate* isolate,
354355

355356
case HEX:
356357
if (is_extern) {
357-
hex_decode(buf, buflen, data, len);
358+
len = hex_decode(buf, buflen, data, extlen);
358359
} else {
359360
String::Value value(str);
360361
len = hex_decode(buf, buflen, *value, value.length());
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
// This is the same as test/simple/test-crypto, but from before the shift
23+
// to use buffers by default.
24+
25+
26+
var common = require('../common');
27+
var assert = require('assert');
28+
29+
try {
30+
var crypto = require('crypto');
31+
} catch (e) {
32+
console.log('Not compiled with OPENSSL support.');
33+
process.exit();
34+
}
35+
36+
var EXTERN_APEX = 0xFBEE9;
37+
38+
// manually controlled string for checking binary output
39+
var ucs2_control = 'a\u0000';
40+
41+
// grow the strings to proper length
42+
while (ucs2_control.length <= EXTERN_APEX) {
43+
ucs2_control += ucs2_control;
44+
}
45+
46+
47+
// check resultant buffer and output string
48+
var b = new Buffer(ucs2_control + ucs2_control, 'ucs2');
49+
50+
//
51+
// Test updating from birant data
52+
//
53+
(function() {
54+
var datum1 = b.slice(700000);
55+
var hash1_converted = crypto.createHash('sha1')
56+
.update(datum1.toString('base64'), 'base64')
57+
.digest('hex');
58+
var hash1_direct = crypto.createHash('sha1').update(datum1).digest('hex');
59+
assert.equal(hash1_direct, hash1_converted, 'should hash the same.');
60+
61+
var datum2 = b;
62+
var hash2_converted = crypto.createHash('sha1')
63+
.update(datum2.toString('base64'), 'base64')
64+
.digest('hex');
65+
var hash2_direct = crypto.createHash('sha1').update(datum2).digest('hex');
66+
assert.equal(hash2_direct, hash2_converted, 'should hash the same.');
67+
})();

test/simple/test-stringbytes-external.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,63 @@ for (var i = 0; i < c_bin.length; i++) {
7272
assert.equal(c_bin.toString('ucs2'), c_ucs.toString('ucs2'));
7373
assert.equal(c_bin.toString('binary'), ucs2_control);
7474
assert.equal(c_ucs.toString('binary'), ucs2_control);
75+
76+
77+
78+
// now let's test BASE64 and HEX ecoding/decoding
79+
var RADIOS = 2;
80+
var PRE_HALF_APEX = Math.ceil(EXTERN_APEX / 2) - RADIOS;
81+
var PRE_3OF4_APEX = Math.ceil((EXTERN_APEX / 4) * 3) - RADIOS;
82+
83+
(function () {
84+
for (var j = 0; j < RADIOS * 2; j += 1) {
85+
var datum = b;
86+
var slice = datum.slice(0, PRE_HALF_APEX + j);
87+
var slice2 = datum.slice(0, PRE_HALF_APEX + j + 2);
88+
var pumped_string = slice.toString('hex');
89+
var pumped_string2 = slice2.toString('hex');
90+
var decoded = new Buffer(pumped_string, 'hex');
91+
92+
var metadata = "\nEXTERN_APEX=1031913 - pumped_string.length="
93+
metadata += pumped_string.length + '\n';
94+
95+
// the string are the same?
96+
for (var k = 0; k < pumped_string.length; ++k) {
97+
assert.equal(pumped_string[k], pumped_string2[k],
98+
metadata + 'chars should be the same at ' + k);
99+
}
100+
101+
// the recoded buffer is the same?
102+
for (var i = 0; i < decoded.length; ++i) {
103+
assert.equal(datum[i], decoded[i],
104+
metadata + 'bytes should be the same at ' + i);
105+
}
106+
}
107+
})();
108+
109+
(function () {
110+
for (var j = 0; j < RADIOS * 2; j += 1) {
111+
var datum = b;
112+
var slice = datum.slice(0, PRE_3OF4_APEX + j);
113+
var slice2 = datum.slice(0, PRE_3OF4_APEX + j + 2);
114+
var pumped_string = slice.toString('base64');
115+
var pumped_string2 = slice2.toString('base64');
116+
var decoded = new Buffer(pumped_string, 'base64');
117+
118+
var metadata = "\nEXTERN_APEX=1031913 - data=" + slice.length
119+
metadata += " pumped_string.length=" + pumped_string.length + '\n';
120+
121+
// the string are the same?
122+
for (var k = 0; k < pumped_string.length - 3; ++k) {
123+
assert.equal(pumped_string[k], pumped_string2[k],
124+
metadata + 'chars should be the same for two slices at '
125+
+ k + ' ' + pumped_string[k] + ' ' + pumped_string2[k]);
126+
}
127+
128+
// the recoded buffer is the same?
129+
for (var i = 0; i < decoded.length; ++i) {
130+
assert.equal(datum[i], decoded[i],
131+
metadata + 'bytes should be the same at ' + i);
132+
}
133+
}
134+
})();

0 commit comments

Comments
 (0)