diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2012-08-14 22:25:52 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2012-08-14 23:00:09 +0200 |
commit | 786e1e87129611523cd7cbf255a479fe36dcba66 (patch) | |
tree | 1ecbf677665c7da8e1c94afa70b5940daa625724 | |
parent | 100e163dda5ea0d16bb1c2f69e9ae75815978f12 (diff) | |
download | node-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.cc | 20 |
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); |