Browse Source

src: don't call DecodeWrite() on Buffers

Don't call DecodeWrite() with a Buffer as its argument because it in
turn calls StringBytes::Write() and that method expects a Local<String>.

"Why then does that function take a Local<Value>?" I hear you ask.
Good question but I don't have the answer.  I added a CHECK for good
measure and what do you know, all of a sudden a large number of crypto
tests started failing.

Calling DecodeWrite(BINARY) on a buffer is nonsensical anyway: if you
want the contents of the buffer, just copy out the data, there is no
need to decode it - and that's exactly what this commit does.

Fixes a great many instances of the following run-time error in debug
builds:

    FATAL ERROR: v8::String::Cast() Could not convert to string
v0.11.13-release
Ben Noordhuis 11 years ago
committed by Fedor Indutny
parent
commit
c30cc4e3a5
  1. 35
      src/node_crypto.cc
  2. 1
      src/string_bytes.cc

35
src/node_crypto.cc

@ -764,20 +764,9 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
if (args.Length() >= 2) { if (args.Length() >= 2) {
ASSERT_IS_BUFFER(args[1]); ASSERT_IS_BUFFER(args[1]);
size_t passlen = Buffer::Length(args[1]);
int passlen = Buffer::Length(args[1]);
if (passlen < 0) {
BIO_free_all(in);
return env->ThrowTypeError("Bad password");
}
pass = new char[passlen + 1]; pass = new char[passlen + 1];
int pass_written = DecodeWrite(env->isolate(), memcpy(pass, Buffer::Data(args[1]), passlen);
pass,
passlen,
args[1],
BINARY);
assert(pass_written == passlen);
pass[passlen] = '\0'; pass[passlen] = '\0';
} }
@ -1167,18 +1156,12 @@ void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
} }
ASSERT_IS_BUFFER(args[0]); ASSERT_IS_BUFFER(args[0]);
ssize_t slen = Buffer::Length(args[0]); size_t slen = Buffer::Length(args[0]);
if (slen < 0)
return env->ThrowTypeError("Bad argument");
char* sbuf = new char[slen]; char* sbuf = new char[slen];
memcpy(sbuf, Buffer::Data(args[0]), slen);
ssize_t wlen = DecodeWrite(env->isolate(), sbuf, slen, args[0], BINARY);
assert(wlen == slen);
const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf); const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, wlen); SSL_SESSION* sess = d2i_SSL_SESSION(NULL, &p, slen);
delete[] sbuf; delete[] sbuf;
@ -3810,8 +3793,6 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
ssize_t passlen = -1; ssize_t passlen = -1;
ssize_t saltlen = -1; ssize_t saltlen = -1;
ssize_t keylen = -1; ssize_t keylen = -1;
ssize_t pass_written = -1;
ssize_t salt_written = -1;
ssize_t iter = -1; ssize_t iter = -1;
PBKDF2Request* req = NULL; PBKDF2Request* req = NULL;
Local<Object> obj; Local<Object> obj;
@ -3832,8 +3813,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
if (pass == NULL) { if (pass == NULL) {
FatalError("node::PBKDF2()", "Out of Memory"); FatalError("node::PBKDF2()", "Out of Memory");
} }
pass_written = DecodeWrite(env->isolate(), pass, passlen, args[0], BINARY); memcpy(pass, Buffer::Data(args[0]), passlen);
assert(pass_written == passlen);
ASSERT_IS_BUFFER(args[1]); ASSERT_IS_BUFFER(args[1]);
saltlen = Buffer::Length(args[1]); saltlen = Buffer::Length(args[1]);
@ -3846,8 +3826,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
if (salt == NULL) { if (salt == NULL) {
FatalError("node::PBKDF2()", "Out of Memory"); FatalError("node::PBKDF2()", "Out of Memory");
} }
salt_written = DecodeWrite(env->isolate(), salt, saltlen, args[1], BINARY); memcpy(salt, Buffer::Data(args[1]), saltlen);
assert(salt_written == saltlen);
if (!args[2]->IsNumber()) { if (!args[2]->IsNumber()) {
type_error = "Iterations not a number"; type_error = "Iterations not a number";

1
src/string_bytes.cc

@ -301,6 +301,7 @@ size_t StringBytes::Write(Isolate* isolate,
size_t len = 0; size_t len = 0;
bool is_extern = GetExternalParts(isolate, val, &data, &len); bool is_extern = GetExternalParts(isolate, val, &data, &len);
CHECK(val->IsString() == true);
Local<String> str = val.As<String>(); Local<String> str = val.As<String>();
len = len < buflen ? len : buflen; len = len < buflen ? len : buflen;

Loading…
Cancel
Save