diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/integration/node_unit_tests.rs | 1 | ||||
-rw-r--r-- | tests/node_compat/config.jsonc | 8 | ||||
-rw-r--r-- | tests/node_compat/runner/TODO.md | 1 | ||||
-rw-r--r-- | tests/node_compat/test.ts | 16 | ||||
-rw-r--r-- | tests/node_compat/test/fixtures/sample.png | bin | 0 -> 9416 bytes | |||
-rw-r--r-- | tests/node_compat/test/parallel/test-crypto-hash.js | 285 | ||||
-rw-r--r-- | tests/unit_node/crypto/crypto_hash_test.ts | 26 | ||||
-rw-r--r-- | tests/unit_node/crypto/crypto_misc_test.ts | 18 |
8 files changed, 326 insertions, 29 deletions
diff --git a/tests/integration/node_unit_tests.rs b/tests/integration/node_unit_tests.rs index b067f3121..d0b6d1fbd 100644 --- a/tests/integration/node_unit_tests.rs +++ b/tests/integration/node_unit_tests.rs @@ -61,6 +61,7 @@ util::unit_test_factory!( crypto_cipher_gcm_test = crypto / crypto_cipher_gcm_test, crypto_hash_test = crypto / crypto_hash_test, crypto_key_test = crypto / crypto_key_test, + crypto_misc_test = crypto / crypto_misc_test, crypto_sign_test = crypto / crypto_sign_test, events_test, dgram_test, diff --git a/tests/node_compat/config.jsonc b/tests/node_compat/config.jsonc index 0a661c0a9..83d91eac1 100644 --- a/tests/node_compat/config.jsonc +++ b/tests/node_compat/config.jsonc @@ -132,16 +132,17 @@ "tmpdir.js" ], "fixtures": [ - "GH-1899-output.js", "a.js", - "child-process-spawn-node.js", "child_process_should_emit_error.js", + "child-process-spawn-node.js", "echo.js", "elipses.txt", "empty.txt", "exit.js", + "GH-1899-output.js", "loop.js", "print-chars.js", + "sample.png", "x.txt" ], "fixtures/keys": ["agent1-cert.pem", "agent1-key.pem", "ca1-cert.pem"], @@ -253,6 +254,7 @@ "test-console-tty-colors.js", "test-crypto-dh-shared.js", "test-crypto-dh.js", + "test-crypto-hash.js", "test-crypto-hkdf.js", "test-crypto-hmac.js", "test-crypto-prime.js", @@ -701,8 +703,8 @@ "test-zlib-zero-windowBits.js" ], "pseudo-tty": [ - "console-dumb-tty.js", "console_colors.js", + "console-dumb-tty.js", "no_dropped_stdio.js", "no_interleaved_stdio.js", "test-tty-color-support-warning-2.js", diff --git a/tests/node_compat/runner/TODO.md b/tests/node_compat/runner/TODO.md index d5dd2fc7b..24618dc88 100644 --- a/tests/node_compat/runner/TODO.md +++ b/tests/node_compat/runner/TODO.md @@ -464,7 +464,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-crypto-from-binary.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-from-binary.js) - [parallel/test-crypto-getcipherinfo.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-getcipherinfo.js) - [parallel/test-crypto-hash-stream-pipe.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-hash-stream-pipe.js) -- [parallel/test-crypto-hash.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-hash.js) - [parallel/test-crypto-key-objects-messageport.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-key-objects-messageport.js) - [parallel/test-crypto-key-objects.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-key-objects.js) - [parallel/test-crypto-keygen-async-dsa-key-object.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-crypto-keygen-async-dsa-key-object.js) diff --git a/tests/node_compat/test.ts b/tests/node_compat/test.ts index 6f15f2d0b..939fdf52a 100644 --- a/tests/node_compat/test.ts +++ b/tests/node_compat/test.ts @@ -16,7 +16,7 @@ import { magenta } from "@std/fmt/colors.ts"; import { pooledMap } from "@std/async/pool.ts"; import { dirname, fromFileUrl, join } from "@std/path/mod.ts"; -import { fail } from "@std/assert/mod.ts"; +import { assertEquals, fail } from "@std/assert/mod.ts"; import { config, getPathsFromTestSuites, @@ -169,12 +169,14 @@ Deno.test("Node.js compatibility", async (t) => { function checkConfigTestFilesOrder(testFileLists: Array<string[]>) { for (const testFileList of testFileLists) { const sortedTestList = JSON.parse(JSON.stringify(testFileList)); - sortedTestList.sort(); - if (JSON.stringify(testFileList) !== JSON.stringify(sortedTestList)) { - throw new Error( - `File names in \`config.json\` are not correct order.`, - ); - } + sortedTestList.sort((a: string, b: string) => + a.toLowerCase().localeCompare(b.toLowerCase()) + ); + assertEquals( + testFileList, + sortedTestList, + "File names in `config.json` are not correct order.", + ); } } diff --git a/tests/node_compat/test/fixtures/sample.png b/tests/node_compat/test/fixtures/sample.png Binary files differnew file mode 100644 index 000000000..258622019 --- /dev/null +++ b/tests/node_compat/test/fixtures/sample.png diff --git a/tests/node_compat/test/parallel/test-crypto-hash.js b/tests/node_compat/test/parallel/test-crypto-hash.js new file mode 100644 index 000000000..18c57dab7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-hash.js @@ -0,0 +1,285 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); +const fs = require('fs'); + +const fixtures = require('../common/fixtures'); + +let cryptoType; +let digest; + +// Test hashing +const a1 = crypto.createHash('sha1').update('Test123').digest('hex'); +const a2 = crypto.createHash('sha256').update('Test123').digest('base64'); +const a3 = crypto.createHash('sha512').update('Test123').digest(); // buffer +const a4 = crypto.createHash('sha1').update('Test123').digest('buffer'); + +// stream interface +let a5 = crypto.createHash('sha512'); +a5.end('Test123'); +a5 = a5.read(); + +let a6 = crypto.createHash('sha512'); +a6.write('Te'); +a6.write('st'); +a6.write('123'); +a6.end(); +a6 = a6.read(); + +let a7 = crypto.createHash('sha512'); +a7.end(); +a7 = a7.read(); + +let a8 = crypto.createHash('sha512'); +a8.write(''); +a8.end(); +a8 = a8.read(); + +if (!common.hasFipsCrypto) { + cryptoType = 'md5'; + digest = 'latin1'; + const a0 = crypto.createHash(cryptoType).update('Test123').digest(digest); + assert.strictEqual( + a0, + 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca\u00bd\u008c', + `${cryptoType} with ${digest} digest failed to evaluate to expected hash` + ); +} +cryptoType = 'md5'; +digest = 'hex'; +assert.strictEqual( + a1, + '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', + `${cryptoType} with ${digest} digest failed to evaluate to expected hash`); +cryptoType = 'sha256'; +digest = 'base64'; +assert.strictEqual( + a2, + '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=', + `${cryptoType} with ${digest} digest failed to evaluate to expected hash`); +cryptoType = 'sha512'; +digest = 'latin1'; +assert.deepStrictEqual( + a3, + Buffer.from( + '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' + + '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' + + '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' + + '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' + + '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'', + 'latin1'), + `${cryptoType} with ${digest} digest failed to evaluate to expected hash`); +cryptoType = 'sha1'; +digest = 'hex'; +assert.deepStrictEqual( + a4, + Buffer.from('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'), + `${cryptoType} with ${digest} digest failed to evaluate to expected hash` +); + +// Stream interface should produce the same result. +assert.deepStrictEqual(a5, a3); +assert.deepStrictEqual(a6, a3); +assert.notStrictEqual(a7, undefined); +assert.notStrictEqual(a8, undefined); + +// Test multiple updates to same hash +const h1 = crypto.createHash('sha1').update('Test123').digest('hex'); +const h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex'); +assert.strictEqual(h1, h2); + +// Test hashing for binary files +const fn = fixtures.path('sample.png'); +const sha1Hash = crypto.createHash('sha1'); +const fileStream = fs.createReadStream(fn); +fileStream.on('data', function(data) { + sha1Hash.update(data); +}); +fileStream.on('close', common.mustCall(function() { + // Test SHA1 of sample.png + assert.strictEqual(sha1Hash.digest('hex'), + '22723e553129a336ad96e10f6aecdf0f45e4149e'); +})); + +// Issue https://github.com/nodejs/node-v0.x-archive/issues/2227: unknown digest +// method should throw an error. +assert.throws(function() { + crypto.createHash('xyzzy'); +}, /Digest method not supported/); + +// Issue https://github.com/nodejs/node/issues/9819: throwing encoding used to +// segfault. +assert.throws( + () => crypto.createHash('sha256').digest({ + toString: () => { throw new Error('boom'); }, + }), + { + name: 'Error', + message: 'boom' + }); + +// Issue https://github.com/nodejs/node/issues/25487: error message for invalid +// arg type to update method should include all possible types +assert.throws( + () => crypto.createHash('sha256').update(), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + +// Default UTF-8 encoding +const hutf8 = crypto.createHash('sha512').update('УТФ-8 text').digest('hex'); +assert.strictEqual( + hutf8, + '4b21bbd1a68e690a730ddcb5a8bc94ead9879ffe82580767ad7ec6fa8ba2dea6' + + '43a821af66afa9a45b6a78c712fecf0e56dc7f43aef4bcfc8eb5b4d8dca6ea5b'); + +assert.notStrictEqual( + hutf8, + crypto.createHash('sha512').update('УТФ-8 text', 'latin1').digest('hex')); + +const h3 = crypto.createHash('sha256'); +h3.digest(); + +assert.throws( + () => h3.digest(), + { + code: 'ERR_CRYPTO_HASH_FINALIZED', + name: 'Error' + }); + +assert.throws( + () => h3.update('foo'), + { + code: 'ERR_CRYPTO_HASH_FINALIZED', + name: 'Error' + }); + +assert.strictEqual( + crypto.createHash('sha256').update('test').digest('ucs2'), + crypto.createHash('sha256').update('test').digest().toString('ucs2')); + +assert.throws( + () => crypto.createHash(), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "algorithm" argument must be of type string. ' + + 'Received undefined' + } +); + +{ + const Hash = crypto.Hash; + const instance = crypto.Hash('sha256'); + assert(instance instanceof Hash, 'Hash is expected to return a new instance' + + ' when called without `new`'); +} + +// Test XOF hash functions and the outputLength option. +{ + // Default outputLengths. + assert.strictEqual(crypto.createHash('shake128').digest('hex'), + '7f9c2ba4e88f827d616045507605853e'); + assert.strictEqual(crypto.createHash('shake128', null).digest('hex'), + '7f9c2ba4e88f827d616045507605853e'); + assert.strictEqual(crypto.createHash('shake256').digest('hex'), + '46b9dd2b0ba88d13233b3feb743eeb24' + + '3fcd52ea62b81b82b50c27646ed5762f'); + assert.strictEqual(crypto.createHash('shake256', { outputLength: 0 }) + .copy() // Default outputLength. + .digest('hex'), + '46b9dd2b0ba88d13233b3feb743eeb24' + + '3fcd52ea62b81b82b50c27646ed5762f'); + + // Short outputLengths. + assert.strictEqual(crypto.createHash('shake128', { outputLength: 0 }) + .digest('hex'), + ''); + assert.strictEqual(crypto.createHash('shake128', { outputLength: 5 }) + .copy({ outputLength: 0 }) + .digest('hex'), + ''); + assert.strictEqual(crypto.createHash('shake128', { outputLength: 5 }) + .digest('hex'), + '7f9c2ba4e8'); + assert.strictEqual(crypto.createHash('shake128', { outputLength: 0 }) + .copy({ outputLength: 5 }) + .digest('hex'), + '7f9c2ba4e8'); + assert.strictEqual(crypto.createHash('shake128', { outputLength: 15 }) + .digest('hex'), + '7f9c2ba4e88f827d61604550760585'); + assert.strictEqual(crypto.createHash('shake256', { outputLength: 16 }) + .digest('hex'), + '46b9dd2b0ba88d13233b3feb743eeb24'); + + // Large outputLengths. + assert.strictEqual(crypto.createHash('shake128', { outputLength: 128 }) + .digest('hex'), + '7f9c2ba4e88f827d616045507605853e' + + 'd73b8093f6efbc88eb1a6eacfa66ef26' + + '3cb1eea988004b93103cfb0aeefd2a68' + + '6e01fa4a58e8a3639ca8a1e3f9ae57e2' + + '35b8cc873c23dc62b8d260169afa2f75' + + 'ab916a58d974918835d25e6a435085b2' + + 'badfd6dfaac359a5efbb7bcc4b59d538' + + 'df9a04302e10c8bc1cbf1a0b3a5120ea'); + const superLongHash = crypto.createHash('shake256', { + outputLength: 1024 * 1024 + }).update('The message is shorter than the hash!') + .digest('hex'); + assert.strictEqual(superLongHash.length, 2 * 1024 * 1024); + assert.ok(superLongHash.endsWith('193414035ddba77bf7bba97981e656ec')); + assert.ok(superLongHash.startsWith('a2a28dbc49cfd6e5d6ceea3d03e77748')); + + // Non-XOF hash functions should accept valid outputLength options as well. + assert.strictEqual(crypto.createHash('sha224', { outputLength: 28 }) + .digest('hex'), + 'd14a028c2a3a2bc9476102bb288234c4' + + '15a2b01f828ea62ac5b3e42f'); + + // Passing invalid sizes should throw during creation. + assert.throws(() => { + crypto.createHash('sha256', { outputLength: 28 }); + }, { + code: 'ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH' + }); + + for (const outputLength of [null, {}, 'foo', false]) { + assert.throws(() => crypto.createHash('sha256', { outputLength }), + { code: 'ERR_INVALID_ARG_TYPE' }); + } + + for (const outputLength of [-1, .5, Infinity, 2 ** 90]) { + assert.throws(() => crypto.createHash('sha256', { outputLength }), + { code: 'ERR_OUT_OF_RANGE' }); + } +} + +{ + const h = crypto.createHash('sha512'); + h.digest(); + assert.throws(() => h.copy(), { code: 'ERR_CRYPTO_HASH_FINALIZED' }); + assert.throws(() => h.digest(), { code: 'ERR_CRYPTO_HASH_FINALIZED' }); +} + +{ + const a = crypto.createHash('sha512').update('abc'); + const b = a.copy(); + const c = b.copy().update('def'); + const d = crypto.createHash('sha512').update('abcdef'); + assert.strictEqual(a.digest('hex'), b.digest('hex')); + assert.strictEqual(c.digest('hex'), d.digest('hex')); +} diff --git a/tests/unit_node/crypto/crypto_hash_test.ts b/tests/unit_node/crypto/crypto_hash_test.ts index 74223067e..96bc1d51b 100644 --- a/tests/unit_node/crypto/crypto_hash_test.ts +++ b/tests/unit_node/crypto/crypto_hash_test.ts @@ -1,11 +1,5 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { - createHash, - createHmac, - getHashes, - randomFillSync, - randomUUID, -} from "node:crypto"; +import { createHash, createHmac, getHashes } from "node:crypto"; import { Buffer } from "node:buffer"; import { Readable } from "node:stream"; import { assert, assertEquals } from "@std/assert/mod.ts"; @@ -123,17 +117,13 @@ Deno.test("[node/crypto.getHashes]", () => { } }); -Deno.test("[node/crypto.getRandomUUID] works the same way as Web Crypto API", () => { - assertEquals(randomUUID().length, crypto.randomUUID().length); - assertEquals(typeof randomUUID(), typeof crypto.randomUUID()); +Deno.test("[node/crypto.hash] supports buffer args", () => { + const buffer = Buffer.from("abc"); + const d = createHash("sha1").update(buffer).digest("hex"); + assertEquals(d, "a9993e364706816aba3e25717850c26c9cd0d89d"); }); -Deno.test("[node/crypto.randomFillSync] supported arguments", () => { - const buf = new Uint8Array(10); - - assert(randomFillSync(buf)); - assert(randomFillSync(buf, 0)); - // @ts-ignore: arraybuffer arguments are valid. - assert(randomFillSync(buf.buffer)); - assert(randomFillSync(new DataView(buf.buffer))); +Deno.test("[node/crypto.hash] does not leak", () => { + const hasher = createHash("sha1"); + hasher.update("abc"); }); diff --git a/tests/unit_node/crypto/crypto_misc_test.ts b/tests/unit_node/crypto/crypto_misc_test.ts new file mode 100644 index 000000000..8132f2e99 --- /dev/null +++ b/tests/unit_node/crypto/crypto_misc_test.ts @@ -0,0 +1,18 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { randomFillSync, randomUUID } from "node:crypto"; +import { assert, assertEquals } from "../../unit/test_util.ts"; + +Deno.test("[node/crypto.getRandomUUID] works the same way as Web Crypto API", () => { + assertEquals(randomUUID().length, crypto.randomUUID().length); + assertEquals(typeof randomUUID(), typeof crypto.randomUUID()); +}); + +Deno.test("[node/crypto.randomFillSync] supported arguments", () => { + const buf = new Uint8Array(10); + + assert(randomFillSync(buf)); + assert(randomFillSync(buf, 0)); + // @ts-ignore: arraybuffer arguments are valid. + assert(randomFillSync(buf.buffer)); + assert(randomFillSync(new DataView(buf.buffer))); +}); |