summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2012-08-14 22:25:52 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2012-08-14 23:00:09 +0200
commit786e1e87129611523cd7cbf255a479fe36dcba66 (patch)
tree1ecbf677665c7da8e1c94afa70b5940daa625724
parent100e163dda5ea0d16bb1c2f69e9ae75815978f12 (diff)
downloadnode-786e1e87129611523cd7cbf255a479fe36dcba66.tar.gz
buffer, crypto: fix buffer decoding
Before this commit, DecodeWrite() mistakenly tried to convert buffers to UTF-8 strings which: a) produced invalid character sequences when the buffer contained octets > 127, and b) lead to spurious test failures because DecodeWrite() wrote less bytes than DecodeBytes() said it would, with the remainder either containing zeros or garbage Fix that by simply copying the buffer's data to the target buffer when the encoding is BINARY or by converting the buffer to a binary string when it's UTF8 or ASCII. Fixes #3651, #3866.
-rw-r--r--src/node.cc20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/node.cc b/src/node.cc
index a1e9fd847..309fc9638 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1184,7 +1184,25 @@ ssize_t DecodeWrite(char *buf,
return -1;
}
- Local<String> str = val->ToString();
+ bool is_buffer = Buffer::HasInstance(val);
+
+ if (is_buffer && encoding == BINARY) { // fast path, copy buffer data
+ const char* data = Buffer::Data(val.As<Object>());
+ size_t size = Buffer::Length(val.As<Object>());
+ size_t len = size < buflen ? size : buflen;
+ memcpy(buf, data, len);
+ return len;
+ }
+
+ Local<String> str;
+
+ if (is_buffer) { // slow path, convert to binary string
+ Local<Value> arg = String::New("binary");
+ str = MakeCallback(val.As<Object>(), "toString", 1, &arg)->ToString();
+ }
+ else {
+ str = val->ToString();
+ }
if (encoding == UTF8) {
str->WriteUtf8(buf, buflen, NULL, String::HINT_MANY_WRITES_EXPECTED);