diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index 857753c2b39f9c..6742d75957482a 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -122,7 +122,8 @@ Hash.prototype.copy = function copy(options) { }; Hash.prototype._transform = function _transform(chunk, encoding, callback) { - this[kHandle].update(chunk, encoding); + if (!this[kHandle].update(chunk, encoding)) + return callback(new ERR_CRYPTO_HASH_UPDATE_FAILED()); callback(); }; diff --git a/test/parallel/test-crypto-hash-stream-error.js b/test/parallel/test-crypto-hash-stream-error.js new file mode 100644 index 00000000000000..ec4360f95429bf --- /dev/null +++ b/test/parallel/test-crypto-hash-stream-error.js @@ -0,0 +1,32 @@ +'use strict'; + +// Flags: --expose-internals + +const common = require('../common'); +if (!common.hasCrypto) common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); +const { kHandle } = require('internal/crypto/util'); + +/** + * This test verifies that the Hash stream properly surfaces an error + * when the underlying native update fails. + */ + +const h = crypto.createHash('sha256'); + +// Simulate native update failure by replacing the internal handle +const fakeHandle = { + update: () => false, + digest: () => Buffer.from('') +}; + +h[kHandle] = fakeHandle; + +h.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_CRYPTO_HASH_UPDATE_FAILED'); +})); + +h.write('test data'); +h.end();