From 9b7888ef882698512e924ca824937cba30a77187 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Fri, 9 May 2014 14:12:37 +0300 Subject: [PATCH] src: fix StringBytes::Write if string is external Signed-off-by: Fedor Indutny --- src/string_bytes.cc | 5 +- test/simple/test-crypto-from-binary.js | 67 ++++++++++++++++++++++++ test/simple/test-stringbytes-external.js | 60 +++++++++++++++++++++ 3 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 test/simple/test-crypto-from-binary.js diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 744021096..de41ec1d4 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -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 str = val.As(); @@ -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()); @@ -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()); diff --git a/test/simple/test-crypto-from-binary.js b/test/simple/test-crypto-from-binary.js new file mode 100644 index 000000000..203361700 --- /dev/null +++ b/test/simple/test-crypto-from-binary.js @@ -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.'); +})(); diff --git a/test/simple/test-stringbytes-external.js b/test/simple/test-stringbytes-external.js index 87823cd07..c7c716c83 100644 --- a/test/simple/test-stringbytes-external.js +++ b/test/simple/test-stringbytes-external.js @@ -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); + } + } +})(); -- 2.34.1