From b7bc8a8e4be0937c53d43a12b4c2ce26782c04dd Mon Sep 17 00:00:00 2001 From: anshikakalpana Date: Thu, 7 May 2026 01:12:41 +0530 Subject: [PATCH 1/2] crypto: runtime-deprecate calling Hmac.digest() more than once Signed-off-by: anshikakalpana --- doc/api/deprecations.md | 5 ++++- lib/internal/crypto/hash.js | 8 ++++++++ test/parallel/test-crypto-dep0206.js | 19 +++++++++++++++++++ test/parallel/test-crypto-hmac.js | 6 ++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-crypto-dep0206.js diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 68dd5a4a36561c..e1da58ccfb696b 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -4562,12 +4562,15 @@ removed in a future version of Node.js. -Type: Documentation-only +Type: Runtime Calling `hmac.digest()` more than once returns an empty buffer instead of throwing an error. This behavior is inconsistent with `hash.digest()` and diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index 857753c2b39f9c..8c496374d281e0 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -87,6 +87,13 @@ const maybeEmitDeprecationWarning = getDeprecationWarningEmitter( }, ); +const emitHmacDoubleDigestDeprecation = getDeprecationWarningEmitter( + 'DEP0206', + 'Calling digest() on an already-finalized Hmac instance is deprecated.', + undefined, + false, +); + function Hash(algorithm, options) { if (!new.target) return new Hash(algorithm, options); @@ -183,6 +190,7 @@ Hmac.prototype.digest = function digest(outputEncoding) { const state = this[kState]; if (state[kFinalized]) { + emitHmacDoubleDigestDeprecation(); const buf = Buffer.from(''); if (outputEncoding && outputEncoding !== 'buffer') return buf.toString(outputEncoding); diff --git a/test/parallel/test-crypto-dep0206.js b/test/parallel/test-crypto-dep0206.js new file mode 100644 index 00000000000000..62f10e6db20b91 --- /dev/null +++ b/test/parallel/test-crypto-dep0206.js @@ -0,0 +1,19 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { createHmac } = require('crypto'); + +common.expectWarning({ + DeprecationWarning: { + DEP0206: 'Calling digest() on an already-finalized Hmac instance is deprecated.', + }, +}); + +const hmac = createHmac('sha256', 'key').update('data'); +hmac.digest(); +const second = hmac.digest(); +assert.deepStrictEqual(second, Buffer.from('')); diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index afb5f74cbf076b..57b2b5db344ba3 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -7,6 +7,12 @@ if (!common.hasCrypto) { const assert = require('assert'); const crypto = require('crypto'); +common.expectWarning({ + DeprecationWarning: { + DEP0206: 'Calling digest() on an already-finalized Hmac instance is deprecated.', + }, +}); + { const Hmac = crypto.Hmac; const instance = crypto.Hmac('sha256', 'Node'); From dc1a02122b3ebd8316311a9bd9e0eec1a99bf382 Mon Sep 17 00:00:00 2001 From: Soul Lee Date: Tue, 12 May 2026 23:06:03 +0900 Subject: [PATCH 2/2] test: fix expectWarning conflict in test-crypto-hmac The existing inline `expectWarning` block at the bottom of the file overwrites the top-of-file registration added by the previous commit, because `expectWarning` stores expectations keyed by warning name (`DeprecationWarning`) and the second call replaces the first. Consolidate both DEP0181 and DEP0206 expectations into the single top-of-file call and drop the now-redundant inline block. The `crypto.Hmac('sha256', 'Node')` call earlier in the file already exercises the constructor-without-`new` path that triggers DEP0181. --- test/parallel/test-crypto-hmac.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index 57b2b5db344ba3..1d2808018a0e31 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -9,6 +9,7 @@ const crypto = require('crypto'); common.expectWarning({ DeprecationWarning: { + DEP0181: 'crypto.Hmac constructor is deprecated.', DEP0206: 'Calling digest() on an already-finalized Hmac instance is deprecated.', }, }); @@ -466,13 +467,3 @@ assert.strictEqual( crypto.createHmac('sha256', keyObject).update('foo').digest(), ); } - -{ - crypto.Hmac('sha256', 'Node'); - common.expectWarning({ - DeprecationWarning: [ - ['crypto.Hmac constructor is deprecated.', - 'DEP0181'], - ] - }); -}