Skip to content

Commit

Permalink
src: fix StringBytes::Write if string is external
Browse files Browse the repository at this point in the history
Signed-off-by: Fedor Indutny <fedor@indutny.com>
  • Loading branch information
refack authored and indutny committed May 12, 2014
1 parent 5344d0c commit 9b7888e
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/string_bytes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ size_t StringBytes::Write(Isolate* isolate,
const char* data = NULL;
size_t len = 0;
bool is_extern = GetExternalParts(isolate, val, &data, &len);
size_t extlen = len;

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

case BASE64:
if (is_extern) {
base64_decode(buf, buflen, data, len);
len = base64_decode(buf, buflen, data, extlen);
} else {
String::Value value(str);
len = base64_decode(buf, buflen, *value, value.length());
Expand All @@ -354,7 +355,7 @@ size_t StringBytes::Write(Isolate* isolate,

case HEX:
if (is_extern) {
hex_decode(buf, buflen, data, len);
len = hex_decode(buf, buflen, data, extlen);
} else {
String::Value value(str);
len = hex_decode(buf, buflen, *value, value.length());
Expand Down
67 changes: 67 additions & 0 deletions test/simple/test-crypto-from-binary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// This is the same as test/simple/test-crypto, but from before the shift
// to use buffers by default.


var common = require('../common');
var assert = require('assert');

try {
var crypto = require('crypto');
} catch (e) {
console.log('Not compiled with OPENSSL support.');
process.exit();
}

var EXTERN_APEX = 0xFBEE9;

// manually controlled string for checking binary output
var ucs2_control = 'a\u0000';

// grow the strings to proper length
while (ucs2_control.length <= EXTERN_APEX) {
ucs2_control += ucs2_control;
}


// check resultant buffer and output string
var b = new Buffer(ucs2_control + ucs2_control, 'ucs2');

//
// Test updating from birant data
//
(function() {
var datum1 = b.slice(700000);
var hash1_converted = crypto.createHash('sha1')
.update(datum1.toString('base64'), 'base64')
.digest('hex');
var hash1_direct = crypto.createHash('sha1').update(datum1).digest('hex');
assert.equal(hash1_direct, hash1_converted, 'should hash the same.');

var datum2 = b;
var hash2_converted = crypto.createHash('sha1')
.update(datum2.toString('base64'), 'base64')
.digest('hex');
var hash2_direct = crypto.createHash('sha1').update(datum2).digest('hex');
assert.equal(hash2_direct, hash2_converted, 'should hash the same.');
})();
60 changes: 60 additions & 0 deletions test/simple/test-stringbytes-external.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,63 @@ for (var i = 0; i < c_bin.length; i++) {
assert.equal(c_bin.toString('ucs2'), c_ucs.toString('ucs2'));
assert.equal(c_bin.toString('binary'), ucs2_control);
assert.equal(c_ucs.toString('binary'), ucs2_control);



// now let's test BASE64 and HEX ecoding/decoding
var RADIOS = 2;
var PRE_HALF_APEX = Math.ceil(EXTERN_APEX / 2) - RADIOS;
var PRE_3OF4_APEX = Math.ceil((EXTERN_APEX / 4) * 3) - RADIOS;

(function () {
for (var j = 0; j < RADIOS * 2; j += 1) {
var datum = b;
var slice = datum.slice(0, PRE_HALF_APEX + j);
var slice2 = datum.slice(0, PRE_HALF_APEX + j + 2);
var pumped_string = slice.toString('hex');
var pumped_string2 = slice2.toString('hex');
var decoded = new Buffer(pumped_string, 'hex');

var metadata = "\nEXTERN_APEX=1031913 - pumped_string.length="
metadata += pumped_string.length + '\n';

// the string are the same?
for (var k = 0; k < pumped_string.length; ++k) {
assert.equal(pumped_string[k], pumped_string2[k],
metadata + 'chars should be the same at ' + k);
}

// the recoded buffer is the same?
for (var i = 0; i < decoded.length; ++i) {
assert.equal(datum[i], decoded[i],
metadata + 'bytes should be the same at ' + i);
}
}
})();

(function () {
for (var j = 0; j < RADIOS * 2; j += 1) {
var datum = b;
var slice = datum.slice(0, PRE_3OF4_APEX + j);
var slice2 = datum.slice(0, PRE_3OF4_APEX + j + 2);
var pumped_string = slice.toString('base64');
var pumped_string2 = slice2.toString('base64');
var decoded = new Buffer(pumped_string, 'base64');

var metadata = "\nEXTERN_APEX=1031913 - data=" + slice.length
metadata += " pumped_string.length=" + pumped_string.length + '\n';

// the string are the same?
for (var k = 0; k < pumped_string.length - 3; ++k) {
assert.equal(pumped_string[k], pumped_string2[k],
metadata + 'chars should be the same for two slices at '
+ k + ' ' + pumped_string[k] + ' ' + pumped_string2[k]);
}

// the recoded buffer is the same?
for (var i = 0; i < decoded.length; ++i) {
assert.equal(datum[i], decoded[i],
metadata + 'bytes should be the same at ' + i);
}
}
})();

0 comments on commit 9b7888e

Please sign in to comment.