From 6bef80a50b5308c681ff214fc1a38217c40390e5 Mon Sep 17 00:00:00 2001 From: LiviaMedeiros Date: Tue, 18 Jul 2023 23:23:39 +0800 Subject: [PATCH 1/2] fs: make `mkdtemp` accept buffers and URL PR-URL: https://github.com/nodejs/node/pull/48828 Reviewed-By: Mohammed Keyvanzadeh Reviewed-By: Antoine du Hamel --- doc/api/fs.md | 15 ++++- lib/fs.js | 30 ++++++--- lib/internal/fs/promises.js | 14 ++-- lib/internal/fs/utils.js | 5 +- test/parallel/test-fs-mkdtemp.js | 110 ++++++++++++++++++++++++++----- 5 files changed, 139 insertions(+), 35 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 2eb490e8b5ce5d..114a51c15dc5d6 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1163,6 +1163,9 @@ makeDirectory().catch(console.error); -* `prefix` {string} +* `prefix` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` * Returns: {Promise} Fulfills with a string containing the file system path @@ -3254,6 +3257,9 @@ See the POSIX mkdir(2) documentation for more details. -* `prefix` {string} +* `prefix` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` * `callback` {Function} @@ -5566,6 +5572,9 @@ See the POSIX mkdir(2) documentation for more details. -* `prefix` {string} +* `prefix` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` * Returns: {string} diff --git a/lib/fs.js b/lib/fs.js index 2ce59432f8293d..34c58e22ad54a4 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -105,7 +105,6 @@ const { getValidatedPath, getValidMode, handleErrorFromBinding, - nullCheck, possiblyTransformPath, preprocessSymlinkDestination, Stats, @@ -2900,7 +2899,7 @@ realpath.native = (path, options, callback) => { /** * Creates a unique temporary directory. - * @param {string} prefix + * @param {string | Buffer | URL} prefix * @param {string | { encoding?: string; }} [options] * @param {( * err?: Error, @@ -2912,27 +2911,40 @@ function mkdtemp(prefix, options, callback) { callback = makeCallback(typeof options === 'function' ? options : callback); options = getOptions(options); - validateString(prefix, 'prefix'); - nullCheck(prefix, 'prefix'); + prefix = getValidatedPath(prefix, 'prefix'); warnOnNonPortableTemplate(prefix); + + let path; + if (typeof prefix === 'string') { + path = `${prefix}XXXXXX`; + } else { + path = Buffer.concat([prefix, Buffer.from('XXXXXX')]); + } + const req = new FSReqCallback(); req.oncomplete = callback; - binding.mkdtemp(`${prefix}XXXXXX`, options.encoding, req); + binding.mkdtemp(path, options.encoding, req); } /** * Synchronously creates a unique temporary directory. - * @param {string} prefix + * @param {string | Buffer | URL} prefix * @param {string | { encoding?: string; }} [options] * @returns {string} */ function mkdtempSync(prefix, options) { options = getOptions(options); - validateString(prefix, 'prefix'); - nullCheck(prefix, 'prefix'); + prefix = getValidatedPath(prefix, 'prefix'); warnOnNonPortableTemplate(prefix); - const path = `${prefix}XXXXXX`; + + let path; + if (typeof prefix === 'string') { + path = `${prefix}XXXXXX`; + } else { + path = Buffer.concat([prefix, Buffer.from('XXXXXX')]); + } + const ctx = { path }; const result = binding.mkdtemp(path, options.encoding, undefined, ctx); diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index a63575664509df..8f56baf77505f1 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -59,7 +59,6 @@ const { getStatsFromBinding, getValidatedPath, getValidMode, - nullCheck, preprocessSymlinkDestination, stringToFlags, stringToSymlinkType, @@ -997,10 +996,17 @@ async function realpath(path, options) { async function mkdtemp(prefix, options) { options = getOptions(options); - validateString(prefix, 'prefix'); - nullCheck(prefix); + prefix = getValidatedPath(prefix, 'prefix'); warnOnNonPortableTemplate(prefix); - return binding.mkdtemp(`${prefix}XXXXXX`, options.encoding, kUsePromises); + + let path; + if (typeof prefix === 'string') { + path = `${prefix}XXXXXX`; + } else { + path = Buffer.concat([prefix, Buffer.from('XXXXXX')]); + } + + return binding.mkdtemp(path, options.encoding, kUsePromises); } async function writeFile(path, data, options) { diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 763f39af62bbbb..26369b3613cd9c 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -20,6 +20,7 @@ const { StringPrototypeEndsWith, StringPrototypeIncludes, Symbol, + TypedArrayPrototypeAt, TypedArrayPrototypeIncludes, } = primordials; @@ -749,7 +750,9 @@ let nonPortableTemplateWarn = true; function warnOnNonPortableTemplate(template) { // Template strings passed to the mkdtemp() family of functions should not // end with 'X' because they are handled inconsistently across platforms. - if (nonPortableTemplateWarn && StringPrototypeEndsWith(template, 'X')) { + if (nonPortableTemplateWarn && + ((typeof template === 'string' && StringPrototypeEndsWith(template, 'X')) || + (typeof template !== 'string' && TypedArrayPrototypeAt(template, -1) === 0x58))) { process.emitWarning('mkdtemp() templates ending with X are not portable. ' + 'For details see: https://nodejs.org/api/fs.html'); nonPortableTemplateWarn = false; diff --git a/test/parallel/test-fs-mkdtemp.js b/test/parallel/test-fs-mkdtemp.js index 950a524368c00b..b7bb0bbafe0581 100644 --- a/test/parallel/test-fs-mkdtemp.js +++ b/test/parallel/test-fs-mkdtemp.js @@ -8,29 +8,103 @@ const path = require('path'); const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); -const tmpFolder = fs.mkdtempSync(path.join(tmpdir.path, 'foo.')); - -assert.strictEqual(path.basename(tmpFolder).length, 'foo.XXXXXX'.length); -assert(fs.existsSync(tmpFolder)); - -const utf8 = fs.mkdtempSync(path.join(tmpdir.path, '\u0222abc.')); -assert.strictEqual(Buffer.byteLength(path.basename(utf8)), - Buffer.byteLength('\u0222abc.XXXXXX')); -assert(fs.existsSync(utf8)); - function handler(err, folder) { assert.ifError(err); assert(fs.existsSync(folder)); assert.strictEqual(this, undefined); } -fs.mkdtemp(path.join(tmpdir.path, 'bar.'), common.mustCall(handler)); +// Test with plain string +{ + const tmpFolder = fs.mkdtempSync(path.join(tmpdir.path, 'foo.')); + + assert.strictEqual(path.basename(tmpFolder).length, 'foo.XXXXXX'.length); + assert(fs.existsSync(tmpFolder)); + + const utf8 = fs.mkdtempSync(path.join(tmpdir.path, '\u0222abc.')); + assert.strictEqual(Buffer.byteLength(path.basename(utf8)), + Buffer.byteLength('\u0222abc.XXXXXX')); + assert(fs.existsSync(utf8)); + + fs.mkdtemp(path.join(tmpdir.path, 'bar.'), common.mustCall(handler)); + + // Same test as above, but making sure that passing an options object doesn't + // affect the way the callback function is handled. + fs.mkdtemp(path.join(tmpdir.path, 'bar.'), {}, common.mustCall(handler)); + + const warningMsg = 'mkdtemp() templates ending with X are not portable. ' + + 'For details see: https://nodejs.org/api/fs.html'; + common.expectWarning('Warning', warningMsg); + fs.mkdtemp(path.join(tmpdir.path, 'bar.X'), common.mustCall(handler)); +} + +// Test with URL object +{ + tmpdir.url = new URL(`file://${tmpdir.path}`); + const urljoin = (base, path) => new URL(path, base); + + const tmpFolder = fs.mkdtempSync(urljoin(tmpdir.url, 'foo.')); + + assert.strictEqual(path.basename(tmpFolder).length, 'foo.XXXXXX'.length); + assert(fs.existsSync(tmpFolder)); + + const utf8 = fs.mkdtempSync(urljoin(tmpdir.url, '\u0222abc.')); + assert.strictEqual(Buffer.byteLength(path.basename(utf8)), + Buffer.byteLength('\u0222abc.XXXXXX')); + assert(fs.existsSync(utf8)); + + fs.mkdtemp(urljoin(tmpdir.url, 'bar.'), common.mustCall(handler)); + + // Same test as above, but making sure that passing an options object doesn't + // affect the way the callback function is handled. + fs.mkdtemp(urljoin(tmpdir.url, 'bar.'), {}, common.mustCall(handler)); + + // Warning fires only once + fs.mkdtemp(urljoin(tmpdir.url, 'bar.X'), common.mustCall(handler)); +} + +// Test with Buffer +{ + const tmpFolder = fs.mkdtempSync(Buffer.from(path.join(tmpdir.path, 'foo.'))); + + assert.strictEqual(path.basename(tmpFolder).length, 'foo.XXXXXX'.length); + assert(fs.existsSync(tmpFolder)); -// Same test as above, but making sure that passing an options object doesn't -// affect the way the callback function is handled. -fs.mkdtemp(path.join(tmpdir.path, 'bar.'), {}, common.mustCall(handler)); + const utf8 = fs.mkdtempSync(Buffer.from(path.join(tmpdir.path, '\u0222abc.'))); + assert.strictEqual(Buffer.byteLength(path.basename(utf8)), + Buffer.byteLength('\u0222abc.XXXXXX')); + assert(fs.existsSync(utf8)); + + fs.mkdtemp(Buffer.from(path.join(tmpdir.path, 'bar.')), common.mustCall(handler)); + + // Same test as above, but making sure that passing an options object doesn't + // affect the way the callback function is handled. + fs.mkdtemp(Buffer.from(path.join(tmpdir.path, 'bar.')), {}, common.mustCall(handler)); + + // Warning fires only once + fs.mkdtemp(Buffer.from(path.join(tmpdir.path, 'bar.X')), common.mustCall(handler)); +} -const warningMsg = 'mkdtemp() templates ending with X are not portable. ' + - 'For details see: https://nodejs.org/api/fs.html'; -common.expectWarning('Warning', warningMsg); -fs.mkdtemp(path.join(tmpdir.path, 'bar.X'), common.mustCall(handler)); +// Test with Uint8Array +{ + const encoder = new TextEncoder(); + + const tmpFolder = fs.mkdtempSync(encoder.encode(path.join(tmpdir.path, 'foo.'))); + + assert.strictEqual(path.basename(tmpFolder).length, 'foo.XXXXXX'.length); + assert(fs.existsSync(tmpFolder)); + + const utf8 = fs.mkdtempSync(encoder.encode(path.join(tmpdir.path, '\u0222abc.'))); + assert.strictEqual(Buffer.byteLength(path.basename(utf8)), + Buffer.byteLength('\u0222abc.XXXXXX')); + assert(fs.existsSync(utf8)); + + fs.mkdtemp(encoder.encode(path.join(tmpdir.path, 'bar.')), common.mustCall(handler)); + + // Same test as above, but making sure that passing an options object doesn't + // affect the way the callback function is handled. + fs.mkdtemp(encoder.encode(path.join(tmpdir.path, 'bar.')), {}, common.mustCall(handler)); + + // Warning fires only once + fs.mkdtemp(encoder.encode(path.join(tmpdir.path, 'bar.X')), common.mustCall(handler)); +} From 1eae568a7675157f136b0609452e3754384f1c52 Mon Sep 17 00:00:00 2001 From: LiviaMedeiros Date: Tue, 18 Jul 2023 23:24:44 +0800 Subject: [PATCH 2/2] fs: mention `URL` in NUL character error message PR-URL: https://github.com/nodejs/node/pull/48828 Reviewed-By: Mohammed Keyvanzadeh Reviewed-By: Antoine du Hamel --- lib/internal/fs/utils.js | 2 +- .../test-child-process-reject-null-bytes.js | 102 +++++++++--------- test/parallel/test-fs-whatwg-url.js | 9 -- 3 files changed, 52 insertions(+), 61 deletions(-) diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 26369b3613cd9c..b7354e30e9a6eb 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -376,7 +376,7 @@ const nullCheck = hideStackFrames((path, propName, throwError = true) => { const err = new ERR_INVALID_ARG_VALUE( propName, path, - 'must be a string or Uint8Array without null bytes', + 'must be a string, Uint8Array, or URL without null bytes', ); if (throwError) { throw err; diff --git a/test/parallel/test-child-process-reject-null-bytes.js b/test/parallel/test-child-process-reject-null-bytes.js index 7d84534f80c75f..b5239cdddcdd07 100644 --- a/test/parallel/test-child-process-reject-null-bytes.js +++ b/test/parallel/test-child-process-reject-null-bytes.js @@ -18,56 +18,56 @@ const { throws(() => exec(`${process.execPath} ${__filename} AAA BBB\0XXX CCC`, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'command' must be a string without null bytes/ + name: 'TypeError', }); throws(() => exec('BBB\0XXX AAA CCC', mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'command' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execSync(`${process.execPath} ${__filename} AAA BBB\0XXX CCC`), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'command' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execSync('BBB\0XXX AAA CCC'), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'command' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'file' argument throws(() => spawn('BBB\0XXX'), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'file' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFile('BBB\0XXX', mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'file' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFileSync('BBB\0XXX'), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'file' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawn('BBB\0XXX'), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'file' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawnSync('BBB\0XXX'), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'file' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'modulePath' argument throws(() => fork('BBB\0XXX'), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'modulePath' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); // Tests for the 'args' argument @@ -77,123 +77,123 @@ throws(() => fork('BBB\0XXX'), { throws(() => execFile(process.execPath, [__filename, 'AAA', 'BBB\0XXX', 'CCC'], mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'args\[2\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFileSync(process.execPath, [__filename, 'AAA', 'BBB\0XXX', 'CCC']), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'args\[2\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => fork(__filename, ['AAA', 'BBB\0XXX', 'CCC']), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'args\[2\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawn(process.execPath, [__filename, 'AAA', 'BBB\0XXX', 'CCC']), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'args\[2\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawnSync(process.execPath, [__filename, 'AAA', 'BBB\0XXX', 'CCC']), { code: 'ERR_INVALID_ARG_VALUE', - message: /The argument 'args\[2\]' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'options.cwd' argument throws(() => exec(process.execPath, { cwd: 'BBB\0XXX' }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); throws(() => execFile(process.execPath, { cwd: 'BBB\0XXX' }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); throws(() => execFileSync(process.execPath, { cwd: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); throws(() => execSync(process.execPath, { cwd: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); throws(() => fork(__filename, { cwd: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); throws(() => spawn(process.execPath, { cwd: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); throws(() => spawnSync(process.execPath, { cwd: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.cwd' must be a string or Uint8Array without null bytes/ + name: 'TypeError', }); // Tests for the 'options.argv0' argument throws(() => exec(process.execPath, { argv0: 'BBB\0XXX' }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFile(process.execPath, { argv0: 'BBB\0XXX' }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFileSync(process.execPath, { argv0: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execSync(process.execPath, { argv0: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); throws(() => fork(__filename, { argv0: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawn(process.execPath, { argv0: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawnSync(process.execPath, { argv0: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.argv0' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'options.shell' argument throws(() => exec(process.execPath, { shell: 'BBB\0XXX' }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.shell' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFile(process.execPath, { shell: 'BBB\0XXX' }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.shell' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFileSync(process.execPath, { shell: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.shell' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execSync(process.execPath, { shell: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.shell' must be a string without null bytes/ + name: 'TypeError', }); // Not testing fork() because it doesn't accept the shell option (internally it @@ -201,94 +201,94 @@ throws(() => execSync(process.execPath, { shell: 'BBB\0XXX' }), { throws(() => spawn(process.execPath, { shell: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.shell' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawnSync(process.execPath, { shell: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.shell' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'options.env' argument throws(() => exec(process.execPath, { env: { 'AAA': 'BBB\0XXX' } }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => exec(process.execPath, { env: { 'BBB\0XXX': 'AAA' } }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFile(process.execPath, { env: { 'AAA': 'BBB\0XXX' } }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFile(process.execPath, { env: { 'BBB\0XXX': 'AAA' } }, mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFileSync(process.execPath, { env: { 'AAA': 'BBB\0XXX' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execFileSync(process.execPath, { env: { 'BBB\0XXX': 'AAA' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execSync(process.execPath, { env: { 'AAA': 'BBB\0XXX' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => execSync(process.execPath, { env: { 'BBB\0XXX': 'AAA' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => fork(__filename, { env: { 'AAA': 'BBB\0XXX' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => fork(__filename, { env: { 'BBB\0XXX': 'AAA' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawn(process.execPath, { env: { 'AAA': 'BBB\0XXX' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawn(process.execPath, { env: { 'BBB\0XXX': 'AAA' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawnSync(process.execPath, { env: { 'AAA': 'BBB\0XXX' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['AAA'\]' must be a string without null bytes/ + name: 'TypeError', }); throws(() => spawnSync(process.execPath, { env: { 'BBB\0XXX': 'AAA' } }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.env\['BBB\0XXX'\]' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'options.execPath' argument throws(() => fork(__filename, { execPath: 'BBB\0XXX' }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.execPath' must be a string without null bytes/ + name: 'TypeError', }); // Tests for the 'options.execArgv' argument throws(() => fork(__filename, { execArgv: ['AAA', 'BBB\0XXX', 'CCC'] }), { code: 'ERR_INVALID_ARG_VALUE', - message: /The property 'options\.execArgv\[1\]' must be a string without null bytes/ + name: 'TypeError', }); diff --git a/test/parallel/test-fs-whatwg-url.js b/test/parallel/test-fs-whatwg-url.js index 829cfa92fafebd..7c99999a68dfad 100644 --- a/test/parallel/test-fs-whatwg-url.js +++ b/test/parallel/test-fs-whatwg-url.js @@ -5,7 +5,6 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); const path = require('path'); const fs = require('fs'); -const os = require('os'); function pathToFileURL(p) { if (!path.isAbsolute(p)) @@ -35,7 +34,6 @@ assert.throws( { code: 'ERR_INVALID_URL_SCHEME', name: 'TypeError', - message: 'The URL must be of scheme file' }); // pct-encoded characters in the path will be decoded and checked @@ -49,7 +47,6 @@ if (common.isWindows) { { code: 'ERR_INVALID_FILE_URL_PATH', name: 'TypeError', - message: 'File URL path must not include encoded \\ or / characters' } ); }); @@ -60,8 +57,6 @@ if (common.isWindows) { { code: 'ERR_INVALID_ARG_VALUE', name: 'TypeError', - message: 'The argument \'path\' must be a string or Uint8Array without ' + - "null bytes. Received 'c:\\\\tmp\\\\\\x00test'" } ); } else { @@ -74,7 +69,6 @@ if (common.isWindows) { { code: 'ERR_INVALID_FILE_URL_PATH', name: 'TypeError', - message: 'File URL path must not include encoded / characters' }); }); assert.throws( @@ -84,7 +78,6 @@ if (common.isWindows) { { code: 'ERR_INVALID_FILE_URL_HOST', name: 'TypeError', - message: `File URL host must be "localhost" or empty on ${os.platform()}` } ); assert.throws( @@ -94,8 +87,6 @@ if (common.isWindows) { { code: 'ERR_INVALID_ARG_VALUE', name: 'TypeError', - message: "The argument 'path' must be a string or Uint8Array without " + - "null bytes. Received '/tmp/\\x00test'" } ); }