Skip to content

Commit 3b9a403

Browse files
bnoordhuisaddaleax
authored andcommitted
crypto: optimize sign.update() and verify.update()
Use `StringBytes::InlineDecoder` to decode strings inputs in C++ land instead of decoding them to buffers in JS land before passing them on to the C++ layer. This is what the other update() methods already did. PR-URL: #31767 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent d09e1da commit 3b9a403

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

lib/internal/crypto/sig.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const {
99
ERR_INVALID_ARG_TYPE,
1010
ERR_INVALID_OPT_VALUE
1111
} = require('internal/errors').codes;
12-
const { validateString } = require('internal/validators');
12+
const { validateEncoding, validateString } = require('internal/validators');
1313
const {
1414
Sign: _Sign,
1515
Verify: _Verify,
@@ -50,8 +50,15 @@ Sign.prototype._write = function _write(chunk, encoding, callback) {
5050

5151
Sign.prototype.update = function update(data, encoding) {
5252
encoding = encoding || getDefaultEncoding();
53-
data = getArrayBufferView(data, 'data', encoding);
54-
this[kHandle].update(data);
53+
54+
if (typeof data === 'string') {
55+
validateEncoding(data, encoding);
56+
} else if (!isArrayBufferView(data)) {
57+
throw new ERR_INVALID_ARG_TYPE(
58+
'data', ['string', 'Buffer', 'TypedArray', 'DataView'], data);
59+
}
60+
61+
this[kHandle].update(data, encoding);
5562
return this;
5663
};
5764

src/node_crypto.cc

+30-4
Original file line numberDiff line numberDiff line change
@@ -4509,12 +4509,25 @@ void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
45094509

45104510

45114511
void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
4512+
Environment* env = Environment::GetCurrent(args);
4513+
45124514
Sign* sign;
45134515
ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
45144516

45154517
Error err;
4516-
ArrayBufferViewContents<char> buf(args[0]);
4517-
err = sign->Update(buf.data(), buf.length());
4518+
4519+
// Only copy the data if we have to, because it's a string
4520+
if (args[0]->IsString()) {
4521+
StringBytes::InlineDecoder decoder;
4522+
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
4523+
4524+
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
4525+
return;
4526+
err = sign->Update(decoder.out(), decoder.size());
4527+
} else {
4528+
ArrayBufferViewContents<char> buf(args[0]);
4529+
err = sign->Update(buf.data(), buf.length());
4530+
}
45184531

45194532
sign->CheckThrow(err);
45204533
}
@@ -4834,12 +4847,25 @@ void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
48344847

48354848

48364849
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
4850+
Environment* env = Environment::GetCurrent(args);
4851+
48374852
Verify* verify;
48384853
ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
48394854

48404855
Error err;
4841-
ArrayBufferViewContents<char> buf(args[0]);
4842-
err = verify->Update(buf.data(), buf.length());
4856+
4857+
// Only copy the data if we have to, because it's a string
4858+
if (args[0]->IsString()) {
4859+
StringBytes::InlineDecoder decoder;
4860+
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
4861+
4862+
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
4863+
return;
4864+
err = verify->Update(decoder.out(), decoder.size());
4865+
} else {
4866+
ArrayBufferViewContents<char> buf(args[0]);
4867+
err = verify->Update(buf.data(), buf.length());
4868+
}
48434869

48444870
verify->CheckThrow(err);
48454871
}

0 commit comments

Comments
 (0)