From 768c98627f01aa2ad055b21479102b8d2e6d5a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sun, 2 Apr 2017 15:00:32 +0200 Subject: [PATCH] crypto: handle exceptions in hmac/hash.digest Forced conversion of the encoding parameter to a string within crypto.js, fixing segmentation faults in node_crypto.cc. Fixes: https://github.com/nodejs/node/issues/9819 --- lib/crypto.js | 3 ++- src/node.cc | 2 ++ src/node_crypto.cc | 18 +++++------------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/crypto.js b/lib/crypto.js index 3e7ed5e9c86960..ca3a5ce4711bc0 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -100,7 +100,8 @@ Hash.prototype.update = function update(data, encoding) { Hash.prototype.digest = function digest(outputEncoding) { outputEncoding = outputEncoding || exports.DEFAULT_ENCODING; - return this._handle.digest(outputEncoding); + // Explicit conversion for backward compatibility + return this._handle.digest(String(outputEncoding)); }; diff --git a/src/node.cc b/src/node.cc index 77e6a5826ee957..8b143c4b0f52b3 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1481,6 +1481,8 @@ enum encoding ParseEncoding(const char* encoding, enum encoding ParseEncoding(Isolate* isolate, Local encoding_v, enum encoding default_encoding) { + CHECK(!encoding_v.IsEmpty()); + if (!encoding_v->IsString()) return default_encoding; diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 45b06eaff50385..0c02e560cb0689 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3797,9 +3797,7 @@ void Hmac::HmacDigest(const FunctionCallbackInfo& args) { enum encoding encoding = BUFFER; if (args.Length() >= 1) { - encoding = ParseEncoding(env->isolate(), - args[0]->ToString(env->isolate()), - BUFFER); + encoding = ParseEncoding(env->isolate(), args[0], BUFFER); } unsigned char* md_value = nullptr; @@ -3921,9 +3919,7 @@ void Hash::HashDigest(const FunctionCallbackInfo& args) { enum encoding encoding = BUFFER; if (args.Length() >= 1) { - encoding = ParseEncoding(env->isolate(), - args[0]->ToString(env->isolate()), - BUFFER); + encoding = ParseEncoding(env->isolate(), args[0], BUFFER); } unsigned char md_value[EVP_MAX_MD_SIZE]; @@ -4201,10 +4197,8 @@ void Sign::SignFinal(const FunctionCallbackInfo& args) { unsigned int len = args.Length(); enum encoding encoding = BUFFER; - if (len >= 2 && args[1]->IsString()) { - encoding = ParseEncoding(env->isolate(), - args[1]->ToString(env->isolate()), - BUFFER); + if (len >= 2) { + encoding = ParseEncoding(env->isolate(), args[1], BUFFER); } node::Utf8Value passphrase(env->isolate(), args[2]); @@ -4452,9 +4446,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo& args) { enum encoding encoding = UTF8; if (args.Length() >= 3) { - encoding = ParseEncoding(env->isolate(), - args[2]->ToString(env->isolate()), - UTF8); + encoding = ParseEncoding(env->isolate(), args[2], UTF8); } ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);