diff --git a/benchmark/crypto/node-digest.js b/benchmark/crypto/node-digest.js index feace3017da4122..75fcb490d88db44 100644 --- a/benchmark/crypto/node-digest.js +++ b/benchmark/crypto/node-digest.js @@ -27,7 +27,7 @@ function main({ length, type, method, n }) { } const hash = digest ? - (method, input) => digest(method, input, { outputEncoding: 'hex' }) : + (method, input) => digest(method, input, 'hex') : (method, input) => createHash(method).update(input).digest('hex'); const array = []; for (let i = 0; i < n; i++) { diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index bba81472d9e965f..e6c7d4b9295320f 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -192,24 +192,18 @@ async function asyncDigest(algorithm, data) { throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError'); } -function digest(algorithm, input, options) { +function digest(algorithm, input, outputEncoding = 'hex') { validateString(algorithm, 'algorithm'); if (typeof input !== 'string') { validateBuffer(input, 'input'); } - let inputEncoding = 'utf8'; - let outputEncoding = 'buffer'; - if (typeof options === 'object') { - if (typeof options.inputEncoding === 'string') { - inputEncoding = normalizeEncoding(options.inputEncoding) || inputEncoding; - } - if (typeof options.outputEncoding === 'string') { - outputEncoding = normalizeEncoding(options.outputEncoding) || outputEncoding; - } + // Fast case: if it's 'hex', we don't need to validate it further. + if (outputEncoding !== 'hex') { + validateString(outputEncoding); + outputEncoding = normalizeEncoding(outputEncoding) || outputEncoding; } return oneShotDigest(algorithm, getCachedHashId(algorithm), getHashCache(), - input, inputEncoding, encodingsMap[inputEncoding], - outputEncoding, encodingsMap[outputEncoding]); + input, outputEncoding, encodingsMap[outputEncoding]); } module.exports = { diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index a1f722b4e72aa01..72b0c0aa3800ae6 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -204,20 +204,17 @@ const EVP_MD* GetDigestImplementation(Environment* env, } // crypto.digest(algorithm, algorithmId, algorithmCache, -// input, inputEncoding, inputEncodingId, -// outputEncoding, outputEncodingId) +// input, outputEncoding, outputEncodingId) void Hash::OneShotDigest(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Isolate* isolate = env->isolate(); - CHECK_EQ(args.Length(), 8); + CHECK_EQ(args.Length(), 6); CHECK(args[0]->IsString()); // algorithm CHECK(args[1]->IsInt32()); // algorithmId CHECK(args[2]->IsObject()); // algorithmCache CHECK(args[3]->IsString() || args[3]->IsArrayBufferView()); // input - CHECK(args[4]->IsString()); // inputEncoding - CHECK(args[5]->IsUint32() || args[5]->IsUndefined()); // inputEncodingId - CHECK(args[6]->IsString()); // outputEncoding - CHECK(args[7]->IsUint32() || args[7]->IsUndefined()); // outputEncodingId + CHECK(args[4]->IsString()); // outputEncoding + CHECK(args[5]->IsUint32() || args[5]->IsUndefined()); // outputEncodingId const EVP_MD* md = GetDigestImplementation(env, args[0], args[1], args[2]); if (md == nullptr) { @@ -227,8 +224,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo& args) { return ThrowCryptoError(env, ERR_get_error(), message.c_str()); } - enum encoding input_enc = ParseEncoding(isolate, args[4], args[5], UTF8); - enum encoding output_enc = ParseEncoding(isolate, args[6], args[7], BUFFER); + enum encoding output_enc = ParseEncoding(isolate, args[4], args[5], HEX); int md_len = EVP_MD_size(md); unsigned int result_size; @@ -241,15 +237,9 @@ void Hash::OneShotDigest(const FunctionCallbackInfo& args) { // in the future. // https://github.com/openssl/openssl/issues/19612 if (args[3]->IsString()) { - StringBytes::InlineDecoder decoder; - // Input is a string so it must be decodable. - decoder.Decode(env, args[3].As(), input_enc).Check(); - if (UNLIKELY(decoder.size() > INT_MAX)) { - return THROW_ERR_OUT_OF_RANGE(env, "data is too long"); - } - - success = EVP_Digest(decoder.out(), - decoder.size(), + Utf8Value utf8(isolate, args[3]); + success = EVP_Digest(utf8.out(), + utf8.length(), output.data(), &result_size, md,