diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index 5ec1d409ec05b9..96abe6a04b28e1 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -565,10 +565,13 @@ function normalizeAlgorithm(algorithm, op) { return { name: algName }; // 6. - const normalizedAlgorithm = webidl.converters[desiredType](algorithm, { - prefix: 'Failed to normalize algorithm', - context: 'passed algorithm', - }); + const normalizedAlgorithm = webidl.converters[desiredType]( + { __proto__: algorithm, name: algName }, + { + prefix: 'Failed to normalize algorithm', + context: 'passed algorithm', + }, + ); // 7. normalizedAlgorithm.name = algName; diff --git a/test/parallel/test-webcrypto-util.js b/test/parallel/test-webcrypto-util.js index b8d5361433fd0e..89d8575e20ddbd 100644 --- a/test/parallel/test-webcrypto-util.js +++ b/test/parallel/test-webcrypto-util.js @@ -17,3 +17,35 @@ const { assert.strictEqual(normalizeAlgorithm(algorithm, 'sign') !== algorithm, true); assert.deepStrictEqual(algorithm, { name: 'ECDSA', hash: 'SHA-256' }); } + +// The algorithm name getter should only be invoked once during +// normalizeAlgorithm, including for algorithms with a non-null desiredType +// where step 6 runs the specialized dictionary converter. +// Refs: https://github.com/web-platform-tests/wpt/pull/57614#pullrequestreview-3808145365 +{ + let nameReadCount = 0; + const algorithm = { + get name() { + nameReadCount++; + return 'AES-GCM'; + }, + iv: new Uint8Array(12), + }; + const normalized = normalizeAlgorithm(algorithm, 'encrypt'); + assert.strictEqual(normalized.name, 'AES-GCM'); + assert.strictEqual(nameReadCount, 1); +} + +{ + let nameReadCount = 0; + const algorithm = { + get name() { + nameReadCount++; + return 'ECDSA'; + }, + hash: 'SHA-256', + }; + const normalized = normalizeAlgorithm(algorithm, 'sign'); + assert.strictEqual(normalized.name, 'ECDSA'); + assert.strictEqual(nameReadCount, 1); +}