diff --git a/lib/internal/crypto/sig.js b/lib/internal/crypto/sig.js index 27930ce1acf793..7e3b7aa7ff394d 100644 --- a/lib/internal/crypto/sig.js +++ b/lib/internal/crypto/sig.js @@ -9,7 +9,7 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_OPT_VALUE } = require('internal/errors').codes; -const { validateString } = require('internal/validators'); +const { validateEncoding, validateString } = require('internal/validators'); const { Sign: _Sign, Verify: _Verify, @@ -50,8 +50,15 @@ Sign.prototype._write = function _write(chunk, encoding, callback) { Sign.prototype.update = function update(data, encoding) { encoding = encoding || getDefaultEncoding(); - data = getArrayBufferView(data, 'data', encoding); - this[kHandle].update(data); + + if (typeof data === 'string') { + validateEncoding(data, encoding); + } else if (!isArrayBufferView(data)) { + throw new ERR_INVALID_ARG_TYPE( + 'data', ['string', 'Buffer', 'TypedArray', 'DataView'], data); + } + + this[kHandle].update(data, encoding); return this; }; diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 1480eb04f8812d..3a1ff9de476a68 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4509,12 +4509,25 @@ void Sign::SignInit(const FunctionCallbackInfo& args) { void Sign::SignUpdate(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + Sign* sign; ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); Error err; - ArrayBufferViewContents buf(args[0]); - err = sign->Update(buf.data(), buf.length()); + + // Only copy the data if we have to, because it's a string + if (args[0]->IsString()) { + StringBytes::InlineDecoder decoder; + enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8); + + if (decoder.Decode(env, args[0].As(), enc).IsNothing()) + return; + err = sign->Update(decoder.out(), decoder.size()); + } else { + ArrayBufferViewContents buf(args[0]); + err = sign->Update(buf.data(), buf.length()); + } sign->CheckThrow(err); } @@ -4834,12 +4847,25 @@ void Verify::VerifyInit(const FunctionCallbackInfo& args) { void Verify::VerifyUpdate(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + Verify* verify; ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); Error err; - ArrayBufferViewContents buf(args[0]); - err = verify->Update(buf.data(), buf.length()); + + // Only copy the data if we have to, because it's a string + if (args[0]->IsString()) { + StringBytes::InlineDecoder decoder; + enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8); + + if (decoder.Decode(env, args[0].As(), enc).IsNothing()) + return; + err = verify->Update(decoder.out(), decoder.size()); + } else { + ArrayBufferViewContents buf(args[0]); + err = verify->Update(buf.data(), buf.length()); + } verify->CheckThrow(err); }