Browse Source

crypto: better error message for createHash

calling digest or update on a hash object after digest has been called
now gives a topical error message instead of an error message saying that the
hash failed to initialize.

PR-URL: https://github.com/nodejs/node/pull/6042
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
process-exit-stdio-flushing
Calvin Metcalf 9 years ago
committed by James M Snell
parent
commit
1d9451bb5a
  1. 13
      src/node_crypto.cc
  2. 1
      src/node_crypto.h
  3. 12
      test/parallel/test-crypto-hash.js

13
src/node_crypto.cc

@ -3676,6 +3676,7 @@ bool Hash::HashInit(const char* hash_type) {
return false; return false;
} }
initialised_ = true; initialised_ = true;
finalized_ = false;
return true; return true;
} }
@ -3695,6 +3696,13 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Data"); THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Data");
if (!hash->initialised_) {
return env->ThrowError("Not initialized");
}
if (hash->finalized_) {
return env->ThrowError("Digest already called");
}
// Only copy the data if we have to, because it's a string // Only copy the data if we have to, because it's a string
bool r; bool r;
if (args[0]->IsString()) { if (args[0]->IsString()) {
@ -3722,6 +3730,9 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
if (!hash->initialised_) { if (!hash->initialised_) {
return env->ThrowError("Not initialized"); return env->ThrowError("Not initialized");
} }
if (hash->finalized_) {
return env->ThrowError("Digest already called");
}
enum encoding encoding = BUFFER; enum encoding encoding = BUFFER;
if (args.Length() >= 1) { if (args.Length() >= 1) {
@ -3735,7 +3746,7 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len); EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
EVP_MD_CTX_cleanup(&hash->mdctx_); EVP_MD_CTX_cleanup(&hash->mdctx_);
hash->initialised_ = false; hash->finalized_ = true;
Local<Value> rc = StringBytes::Encode(env->isolate(), Local<Value> rc = StringBytes::Encode(env->isolate(),
reinterpret_cast<const char*>(md_value), reinterpret_cast<const char*>(md_value),

1
src/node_crypto.h

@ -538,6 +538,7 @@ class Hash : public BaseObject {
EVP_MD_CTX mdctx_; /* coverity[member_decl] */ EVP_MD_CTX mdctx_; /* coverity[member_decl] */
const EVP_MD* md_; /* coverity[member_decl] */ const EVP_MD* md_; /* coverity[member_decl] */
bool initialised_; bool initialised_;
bool finalized_;
}; };
class SignBase : public BaseObject { class SignBase : public BaseObject {

12
test/parallel/test-crypto-hash.js

@ -98,3 +98,15 @@ assert.equal(
assert.notEqual( assert.notEqual(
hutf8, hutf8,
crypto.createHash('sha512').update('УТФ-8 text', 'binary').digest('hex')); crypto.createHash('sha512').update('УТФ-8 text', 'binary').digest('hex'));
var h3 = crypto.createHash('sha256');
h3.digest();
assert.throws(function() {
h3.digest();
},
/Digest already called/);
assert.throws(function() {
h3.update('foo');
},
/Digest already called/);

Loading…
Cancel
Save