diff --git a/lib/internal/crypto/scrypt.js b/lib/internal/crypto/scrypt.js index 2705611832f03a..e2751f8fa58261 100644 --- a/lib/internal/crypto/scrypt.js +++ b/lib/internal/crypto/scrypt.js @@ -80,31 +80,31 @@ function check(password, salt, keylen, options) { if (options && options !== defaults) { let has_N, has_r, has_p; if (has_N = (options.N !== undefined)) { - validateUint32(options.N, 'N'); N = options.N; + validateUint32(N, 'N'); } if (options.cost !== undefined) { if (has_N) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER(); - validateUint32(options.cost, 'cost'); N = options.cost; + validateUint32(N, 'cost'); } if (has_r = (options.r !== undefined)) { - validateUint32(options.r, 'r'); r = options.r; + validateUint32(r, 'r'); } if (options.blockSize !== undefined) { if (has_r) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER(); - validateUint32(options.blockSize, 'blockSize'); r = options.blockSize; + validateUint32(r, 'blockSize'); } if (has_p = (options.p !== undefined)) { - validateUint32(options.p, 'p'); p = options.p; + validateUint32(p, 'p'); } if (options.parallelization !== undefined) { if (has_p) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER(); - validateUint32(options.parallelization, 'parallelization'); p = options.parallelization; + validateUint32(p, 'parallelization'); } if (options.maxmem !== undefined) { maxmem = options.maxmem; diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js index 63ddcdfb42af28..b5d6cbb4a8d4a6 100644 --- a/test/parallel/test-crypto-scrypt.js +++ b/test/parallel/test-crypto-scrypt.js @@ -235,3 +235,38 @@ for (const { args, expected } of badargs) { code: 'ERR_OUT_OF_RANGE' }); } + +{ + // Regression test for https://github.com/nodejs/node/issues/28836. + + function testParameter(name, value) { + let accessCount = 0; + + // Find out how often the value is accessed. + crypto.scryptSync('', '', 1, { + get [name]() { + accessCount++; + return value; + } + }); + + // Try to crash the process on the last access. + common.expectsError(() => { + crypto.scryptSync('', '', 1, { + get [name]() { + if (--accessCount === 0) + return ''; + return value; + } + }); + }, { + code: 'ERR_INVALID_ARG_TYPE' + }); + } + + [ + ['N', 16384], ['cost', 16384], + ['r', 8], ['blockSize', 8], + ['p', 1], ['parallelization', 1] + ].forEach((arg) => testParameter(...arg)); +}