From abf86372e2ee1ceeeccee0195c022b35f07cd6bd Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 3 Feb 2017 15:25:29 -0800 Subject: [PATCH 1/2] Revert "test: refactor test-fs-error-messages.js" This reverts commit 907ce8dd6c297661a21a8ef5b638b76352523aa2. --- test/parallel/test-fs-error-messages.js | 282 ++++++++++++++---------- 1 file changed, 164 insertions(+), 118 deletions(-) diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index 2d0a8230fb802d..f2ea85531bf463 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -9,156 +9,202 @@ const existingFile2 = path.join(common.fixturesDir, 'create-file.js'); const existingDir = path.join(common.fixturesDir, 'empty'); const existingDir2 = path.join(common.fixturesDir, 'keys'); -// Test all operations failing with ENOENT errors -function testEnoentError(file, endMessage, syscal, err) { - const sufix = (endMessage) ? endMessage : ''; +// ASYNC_CALL - assert(err instanceof Error); +fs.stat(fn, function(err) { assert.strictEqual(fn, err.path); - assert.strictEqual( - err.message, - `ENOENT: no such file or directory, ${syscal} '${file}'${sufix}` - ); - - return true; -} + assert.ok(0 <= err.message.indexOf(fn)); +}); -// Test all operations failing with EEXIST errors -function testEexistError(source, dest, syscal, err) { - const sufix = (dest) ? ` -> '${dest}'` : ''; +fs.lstat(fn, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); - assert(err instanceof Error); - assert.strictEqual(source, err.path); - assert.strictEqual( - err.message, - `EEXIST: file already exists, ${syscal} '${source}'${sufix}` - ); +fs.readlink(fn, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); - return true; -} +fs.link(fn, 'foo', function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -// Test all operations failing with ENOTEMPTY errors -function testEnoemptyError(source, dest, err) { - assert(err instanceof Error); - assert.strictEqual(source, err.path); - assert.strictEqual( - err.message, - `ENOTEMPTY: directory not empty, rename '${source}' ` + - `-> '${dest}'` - ); - - return true; -} +fs.link(existingFile, existingFile2, function(err) { + assert.ok(0 <= err.message.indexOf(existingFile)); + assert.ok(0 <= err.message.indexOf(existingFile2)); +}); -// Test all operations failing with ENOTDIR errors -function testEnotdirError(dir, err) { - assert(err instanceof Error); - assert.strictEqual(dir, err.path); - assert.strictEqual( - err.message, - `ENOTDIR: not a directory, rmdir '${dir}'` - ); +fs.symlink(existingFile, existingFile2, function(err) { + assert.ok(0 <= err.message.indexOf(existingFile)); + assert.ok(0 <= err.message.indexOf(existingFile2)); +}); - return true; -} +fs.unlink(fn, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -// Generating ENOENTS errors -fs.stat(fn, (err) => testEnoentError(fn, '', 'stat', err)); -fs.lstat(fn, (err) => testEnoentError(fn, '', 'lstat', err)); -fs.readlink(fn, (err) => testEnoentError(fn, '', 'readlink', err)); -fs.link(fn, 'foo', (err) => testEnoentError(fn, ' -> \'foo\'', 'link', err)); -fs.unlink(fn, (err) => testEnoentError(fn, '', 'unlink', err)); -fs.rmdir(fn, (err) => testEnoentError(fn, '', 'rmdir', err)); -fs.chmod(fn, 0o666, (err) => testEnoentError(fn, '', 'chmod', err)); -fs.open(fn, 'r', 0o666, (err) => testEnoentError(fn, '', 'open', err)); -fs.readFile(fn, (err) => testEnoentError(fn, '', 'open', err)); -fs.readdir(fn, (err) => testEnoentError(fn, '', 'scandir', err)); +fs.rename(fn, 'foo', function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -fs.rename(fn, 'foo', (err) => { - testEnoentError(fn, ' -> \'foo\'', 'rename', err); +fs.rename(existingDir, existingDir2, function(err) { + assert.ok(0 <= err.message.indexOf(existingDir)); + assert.ok(0 <= err.message.indexOf(existingDir2)); }); -assert.throws(() => { - fs.statSync(fn); -}, (err) => testEnoentError(fn, '', 'stat', err)); +fs.rmdir(fn, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -assert.throws(() => { - fs.lstatSync(fn); -}, (err) => testEnoentError(fn, '', 'lstat', err)); +fs.mkdir(existingFile, 0o666, function(err) { + assert.ok(0 <= err.message.indexOf(existingFile)); +}); -assert.throws(() => { - fs.readlinkSync(fn); -}, (err) => testEnoentError(fn, '', 'readlink', err)); +fs.rmdir(existingFile, function(err) { + assert.ok(0 <= err.message.indexOf(existingFile)); +}); -assert.throws(() => { - fs.linkSync(fn, 'foo'); -}, (err) => testEnoentError(fn, ' -> \'foo\'', 'link', err)); +fs.chmod(fn, 0o666, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -assert.throws(() => { - fs.unlinkSync(fn); -}, (err) => testEnoentError(fn, '', 'unlink', err)); +fs.open(fn, 'r', 0o666, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -assert.throws(() => { - fs.rmdirSync(fn); -}, (err) => testEnoentError(fn, '', 'rmdir', err)); +fs.readFile(fn, function(err) { + assert.ok(0 <= err.message.indexOf(fn)); +}); -assert.throws(() => { - fs.chmodSync(fn, 0o666); -}, (err) => testEnoentError(fn, '', 'chmod', err)); +// Sync -assert.throws(() => { - fs.openSync(fn, 'r'); -}, (err) => testEnoentError(fn, '', 'open', err)); +const errors = []; +let expected = 0; -assert.throws(() => { - fs.readFileSync(fn); -}, (err) => testEnoentError(fn, '', 'open', err)); +try { + ++expected; + fs.statSync(fn); +} catch (err) { + errors.push('stat'); + assert.ok(0 <= err.message.indexOf(fn)); +} -assert.throws(() => { - fs.readdirSync(fn); -}, (err) => testEnoentError(fn, '', 'scandir', err)); +try { + ++expected; + fs.mkdirSync(existingFile, 0o666); +} catch (err) { + errors.push('mkdir'); + assert.ok(0 <= err.message.indexOf(existingFile)); +} -assert.throws(() => { - fs.renameSync(fn, 'foo'); -}, (err) => testEnoentError(fn, ' -> \'foo\'', 'rename', err)); +try { + ++expected; + fs.chmodSync(fn, 0o666); +} catch (err) { + errors.push('chmod'); + assert.ok(0 <= err.message.indexOf(fn)); +} -// Generating EEXIST errors -fs.link(existingFile, existingFile2, (err) => { - testEexistError(existingFile, existingFile2, 'link', err); -}); +try { + ++expected; + fs.lstatSync(fn); +} catch (err) { + errors.push('lstat'); + assert.ok(0 <= err.message.indexOf(fn)); +} -fs.symlink(existingFile, existingFile2, (err) => { - testEexistError(existingFile, existingFile2, 'symlink', err); -}); +try { + ++expected; + fs.readlinkSync(fn); +} catch (err) { + errors.push('readlink'); + assert.ok(0 <= err.message.indexOf(fn)); +} -fs.mkdir(existingFile, 0o666, (err) => { - testEexistError(existingFile, null, 'mkdir', err); -}); +try { + ++expected; + fs.linkSync(fn, 'foo'); +} catch (err) { + errors.push('link'); + assert.ok(0 <= err.message.indexOf(fn)); +} -assert.throws(() => { +try { + ++expected; fs.linkSync(existingFile, existingFile2); -}, (err) => testEexistError(existingFile, existingFile2, 'link', err)); +} catch (err) { + errors.push('link'); + assert.ok(0 <= err.message.indexOf(existingFile)); + assert.ok(0 <= err.message.indexOf(existingFile2)); +} -assert.throws(() => { +try { + ++expected; fs.symlinkSync(existingFile, existingFile2); -}, (err) => testEexistError(existingFile, existingFile2, 'symlink', err)); +} catch (err) { + errors.push('symlink'); + assert.ok(0 <= err.message.indexOf(existingFile)); + assert.ok(0 <= err.message.indexOf(existingFile2)); +} -assert.throws(() => { - fs.mkdirSync(existingFile, 0o666); -}, (err) => testEexistError(existingFile, null, 'mkdir', err)); +try { + ++expected; + fs.unlinkSync(fn); +} catch (err) { + errors.push('unlink'); + assert.ok(0 <= err.message.indexOf(fn)); +} -// Generating ENOTEMPTY errors -fs.rename(existingDir, existingDir2, (err) => { - testEnoemptyError(existingDir, existingDir2, err); -}); +try { + ++expected; + fs.rmdirSync(fn); +} catch (err) { + errors.push('rmdir'); + assert.ok(0 <= err.message.indexOf(fn)); +} + +try { + ++expected; + fs.rmdirSync(existingFile); +} catch (err) { + errors.push('rmdir'); + assert.ok(0 <= err.message.indexOf(existingFile)); +} + +try { + ++expected; + fs.openSync(fn, 'r'); +} catch (err) { + errors.push('opens'); + assert.ok(0 <= err.message.indexOf(fn)); +} -assert.throws(() => { +try { + ++expected; + fs.renameSync(fn, 'foo'); +} catch (err) { + errors.push('rename'); + assert.ok(0 <= err.message.indexOf(fn)); +} + +try { + ++expected; fs.renameSync(existingDir, existingDir2); -}, (err) => testEnoemptyError(existingDir, existingDir2, err)); +} catch (err) { + errors.push('rename'); + assert.ok(0 <= err.message.indexOf(existingDir)); + assert.ok(0 <= err.message.indexOf(existingDir2)); +} -// Generating ENOTDIR errors -fs.rmdir(existingFile, (err) => testEnotdirError(existingFile, err)); +try { + ++expected; + fs.readdirSync(fn); +} catch (err) { + errors.push('readdir'); + assert.ok(0 <= err.message.indexOf(fn)); +} -assert.throws(() => { - fs.rmdirSync(existingFile); -}, (err) => testEnotdirError(existingFile, err)); +process.on('exit', function() { + assert.strictEqual(expected, errors.length, + 'Test fs sync exceptions raised, got ' + errors.length + + ' expected ' + expected); +}); From 3867bc5e6ea2191192de883be142de81f888950a Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 3 Feb 2017 16:18:44 -0800 Subject: [PATCH 2/2] Revert "fs: allow WHATWG URL and file: URLs as paths" This reverts commit 79400bfbfdea32e861a30cadeb2f7363e99bcaca. --- lib/fs.js | 92 +---------------------------- lib/internal/url.js | 63 -------------------- test/parallel/test-fs-null-bytes.js | 57 ------------------ test/parallel/test-fs-whatwg-url.js | 70 ---------------------- 4 files changed, 3 insertions(+), 279 deletions(-) delete mode 100644 test/parallel/test-fs-whatwg-url.js diff --git a/lib/fs.js b/lib/fs.js index fae2857e3fc759..27e1a2e79cd135 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -16,11 +16,9 @@ const EventEmitter = require('events'); const FSReqWrap = binding.FSReqWrap; const FSEvent = process.binding('fs_event_wrap').FSEvent; const internalFS = require('internal/fs'); -const internalURL = require('internal/url'); const assertEncoding = internalFS.assertEncoding; const stringToFlags = internalFS.stringToFlags; const SyncWriteStream = internalFS.SyncWriteStream; -const getPathFromURL = internalURL.getPathFromURL; Object.defineProperty(exports, 'constants', { configurable: false, @@ -204,16 +202,6 @@ fs.Stats.prototype.isSocket = function() { }); }); -function handleError(val, callback) { - if (val instanceof Error) { - if (typeof callback === 'function') { - process.nextTick(callback, val); - return true; - } else throw val; - } - return false; -} - fs.access = function(path, mode, callback) { if (typeof mode === 'function') { callback = mode; @@ -222,9 +210,6 @@ fs.access = function(path, mode, callback) { throw new TypeError('"callback" argument must be a function'); } - if (handleError((path = getPathFromURL(path)), callback)) - return; - if (!nullCheck(path, callback)) return; @@ -235,7 +220,6 @@ fs.access = function(path, mode, callback) { }; fs.accessSync = function(path, mode) { - handleError((path = getPathFromURL(path))); nullCheck(path); if (mode === undefined) @@ -247,8 +231,6 @@ fs.accessSync = function(path, mode) { }; fs.exists = function(path, callback) { - if (handleError((path = getPathFromURL(path)), cb)) - return; if (!nullCheck(path, cb)) return; var req = new FSReqWrap(); req.oncomplete = cb; @@ -260,7 +242,6 @@ fs.exists = function(path, callback) { fs.existsSync = function(path) { try { - handleError((path = getPathFromURL(path))); nullCheck(path); binding.stat(pathModule._makeLong(path)); return true; @@ -273,8 +254,6 @@ fs.readFile = function(path, options, callback) { callback = maybeCallback(arguments[arguments.length - 1]); options = getOptions(options, { flag: 'r' }); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; @@ -558,8 +537,6 @@ fs.open = function(path, flags, mode, callback_) { var callback = makeCallback(arguments[arguments.length - 1]); mode = modeNum(mode, 0o666); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); @@ -573,7 +550,6 @@ fs.open = function(path, flags, mode, callback_) { fs.openSync = function(path, flags, mode) { mode = modeNum(mode, 0o666); - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); }; @@ -669,12 +645,6 @@ fs.writeSync = function(fd, buffer, offset, length, position) { fs.rename = function(oldPath, newPath, callback) { callback = makeCallback(callback); - if (handleError((oldPath = getPathFromURL(oldPath)), callback)) - return; - - if (handleError((newPath = getPathFromURL(newPath)), callback)) - return; - if (!nullCheck(oldPath, callback)) return; if (!nullCheck(newPath, callback)) return; var req = new FSReqWrap(); @@ -685,8 +655,6 @@ fs.rename = function(oldPath, newPath, callback) { }; fs.renameSync = function(oldPath, newPath) { - handleError((oldPath = getPathFromURL(oldPath))); - handleError((newPath = getPathFromURL(newPath))); nullCheck(oldPath); nullCheck(newPath); return binding.rename(pathModule._makeLong(oldPath), @@ -758,8 +726,6 @@ fs.ftruncateSync = function(fd, len) { fs.rmdir = function(path, callback) { callback = maybeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -767,7 +733,6 @@ fs.rmdir = function(path, callback) { }; fs.rmdirSync = function(path) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.rmdir(pathModule._makeLong(path)); }; @@ -795,8 +760,6 @@ fs.fsyncSync = function(fd) { fs.mkdir = function(path, mode, callback) { if (typeof mode === 'function') callback = mode; callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -806,7 +769,6 @@ fs.mkdir = function(path, mode, callback) { }; fs.mkdirSync = function(path, mode) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.mkdir(pathModule._makeLong(path), modeNum(mode, 0o777)); @@ -815,8 +777,6 @@ fs.mkdirSync = function(path, mode) { fs.readdir = function(path, options, callback) { callback = makeCallback(typeof options === 'function' ? options : callback); options = getOptions(options, {}); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -825,7 +785,6 @@ fs.readdir = function(path, options, callback) { fs.readdirSync = function(path, options) { options = getOptions(options, {}); - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.readdir(pathModule._makeLong(path), options.encoding); }; @@ -838,8 +797,6 @@ fs.fstat = function(fd, callback) { fs.lstat = function(path, callback) { callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -848,8 +805,6 @@ fs.lstat = function(path, callback) { fs.stat = function(path, callback) { callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -861,13 +816,11 @@ fs.fstatSync = function(fd) { }; fs.lstatSync = function(path) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.lstat(pathModule._makeLong(path)); }; fs.statSync = function(path) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.stat(pathModule._makeLong(path)); }; @@ -875,8 +828,6 @@ fs.statSync = function(path) { fs.readlink = function(path, options, callback) { callback = makeCallback(typeof options === 'function' ? options : callback); options = getOptions(options, {}); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -885,7 +836,6 @@ fs.readlink = function(path, options, callback) { fs.readlinkSync = function(path, options) { options = getOptions(options, {}); - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.readlink(pathModule._makeLong(path), options.encoding); }; @@ -909,12 +859,6 @@ fs.symlink = function(target, path, type_, callback_) { var type = (typeof type_ === 'string' ? type_ : null); var callback = makeCallback(arguments[arguments.length - 1]); - if (handleError((target = getPathFromURL(target)), callback)) - return; - - if (handleError((path = getPathFromURL(path)), callback)) - return; - if (!nullCheck(target, callback)) return; if (!nullCheck(path, callback)) return; @@ -929,8 +873,7 @@ fs.symlink = function(target, path, type_, callback_) { fs.symlinkSync = function(target, path, type) { type = (typeof type === 'string' ? type : null); - handleError((target = getPathFromURL(target))); - handleError((path = getPathFromURL(path))); + nullCheck(target); nullCheck(path); @@ -941,13 +884,6 @@ fs.symlinkSync = function(target, path, type) { fs.link = function(existingPath, newPath, callback) { callback = makeCallback(callback); - - if (handleError((existingPath = getPathFromURL(existingPath)), callback)) - return; - - if (handleError((newPath = getPathFromURL(newPath)), callback)) - return; - if (!nullCheck(existingPath, callback)) return; if (!nullCheck(newPath, callback)) return; @@ -960,8 +896,6 @@ fs.link = function(existingPath, newPath, callback) { }; fs.linkSync = function(existingPath, newPath) { - handleError((existingPath = getPathFromURL(existingPath))); - handleError((newPath = getPathFromURL(newPath))); nullCheck(existingPath); nullCheck(newPath); return binding.link(pathModule._makeLong(existingPath), @@ -970,8 +904,6 @@ fs.linkSync = function(existingPath, newPath) { fs.unlink = function(path, callback) { callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -979,7 +911,6 @@ fs.unlink = function(path, callback) { }; fs.unlinkSync = function(path) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.unlink(pathModule._makeLong(path)); }; @@ -1036,8 +967,6 @@ if (constants.hasOwnProperty('O_SYMLINK')) { fs.chmod = function(path, mode, callback) { callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -1047,7 +976,6 @@ fs.chmod = function(path, mode, callback) { }; fs.chmodSync = function(path, mode) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.chmod(pathModule._makeLong(path), modeNum(mode)); }; @@ -1082,8 +1010,6 @@ fs.fchownSync = function(fd, uid, gid) { fs.chown = function(path, uid, gid, callback) { callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -1091,7 +1017,6 @@ fs.chown = function(path, uid, gid, callback) { }; fs.chownSync = function(path, uid, gid) { - handleError((path = getPathFromURL(path))); nullCheck(path); return binding.chown(pathModule._makeLong(path), uid, gid); }; @@ -1119,8 +1044,6 @@ fs._toUnixTimestamp = toUnixTimestamp; fs.utimes = function(path, atime, mtime, callback) { callback = makeCallback(callback); - if (handleError((path = getPathFromURL(path)), callback)) - return; if (!nullCheck(path, callback)) return; var req = new FSReqWrap(); req.oncomplete = callback; @@ -1131,7 +1054,6 @@ fs.utimes = function(path, atime, mtime, callback) { }; fs.utimesSync = function(path, atime, mtime) { - handleError((path = getPathFromURL(path))); nullCheck(path); atime = toUnixTimestamp(atime); mtime = toUnixTimestamp(mtime); @@ -1292,7 +1214,6 @@ FSWatcher.prototype.start = function(filename, persistent, recursive, encoding) { - handleError((filename = getPathFromURL(filename))); nullCheck(filename); var err = this._handle.start(pathModule._makeLong(filename), persistent, @@ -1311,7 +1232,6 @@ FSWatcher.prototype.close = function() { }; fs.watch = function(filename, options, listener) { - handleError((filename = getPathFromURL(filename))); nullCheck(filename); if (typeof options === 'function') { @@ -1372,7 +1292,6 @@ util.inherits(StatWatcher, EventEmitter); StatWatcher.prototype.start = function(filename, persistent, interval) { - handleError((filename = getPathFromURL(filename))); nullCheck(filename); this._handle.start(pathModule._makeLong(filename), persistent, interval); }; @@ -1386,7 +1305,6 @@ StatWatcher.prototype.stop = function() { const statWatchers = new Map(); fs.watchFile = function(filename, options, listener) { - handleError((filename = getPathFromURL(filename))); nullCheck(filename); filename = pathModule.resolve(filename); var stat; @@ -1423,7 +1341,6 @@ fs.watchFile = function(filename, options, listener) { }; fs.unwatchFile = function(filename, listener) { - handleError((filename = getPathFromURL(filename))); nullCheck(filename); filename = pathModule.resolve(filename); var stat = statWatchers.get(filename); @@ -1467,7 +1384,6 @@ function encodeRealpathResult(result, options) { fs.realpathSync = function realpathSync(p, options) { options = getOptions(options, {}); - handleError((p = getPathFromURL(p))); nullCheck(p); p = p.toString('utf8'); @@ -1571,8 +1487,6 @@ fs.realpathSync = function realpathSync(p, options) { fs.realpath = function realpath(p, options, callback) { callback = maybeCallback(typeof options === 'function' ? options : callback); options = getOptions(options, {}); - if (handleError((p = getPathFromURL(p)), callback)) - return; if (!nullCheck(p, callback)) return; @@ -1731,7 +1645,7 @@ function ReadStream(path, options) { Readable.call(this, options); - handleError((this.path = getPathFromURL(path))); + this.path = path; this.fd = options.fd === undefined ? null : options.fd; this.flags = options.flags === undefined ? 'r' : options.flags; this.mode = options.mode === undefined ? 0o666 : options.mode; @@ -1894,7 +1808,7 @@ function WriteStream(path, options) { Writable.call(this, options); - handleError((this.path = getPathFromURL(path))); + this.path = path; this.fd = options.fd === undefined ? null : options.fd; this.flags = options.flags === undefined ? 'w' : options.flags; this.mode = options.mode === undefined ? 0o666 : options.mode; diff --git a/lib/internal/url.js b/lib/internal/url.js index 49444880d1f491..3fe6e106d5b1fa 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -7,9 +7,6 @@ const cannotBeBase = Symbol('cannot-be-base'); const special = Symbol('special'); const searchParams = Symbol('query'); const querystring = require('querystring'); -const os = require('os'); - -const isWindows = process.platform === 'win32'; const kScheme = Symbol('scheme'); const kHost = Symbol('host'); @@ -1115,66 +1112,6 @@ function urlToOptions(url) { return options; } -function getPathFromURLWin32(url) { - var hostname = url.hostname; - var pathname = url.pathname; - for (var n = 0; n < pathname.length; n++) { - if (pathname[n] === '%') { - var third = pathname.codePointAt(n + 2) | 0x20; - if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F / - (pathname[n + 1] === '5' && third === 99)) { // 5c 5C \ - return new Error('Path must not include encoded \\ or / characters'); - } - } - } - pathname = decodeURIComponent(pathname); - if (hostname !== '') { - // If hostname is set, then we have a UNC path - // Pass the hostname through domainToUnicode just in case - // it is an IDN using punycode encoding. We do not need to worry - // about percent encoding because the URL parser will have - // already taken care of that for us. Note that this only - // causes IDNs with an appropriate `xn--` prefix to be decoded. - return `//${domainToUnicode(hostname)}${pathname}`; - } else { - // Otherwise, it's a local path that requires a drive letter - var letter = pathname.codePointAt(1) | 0x20; - var sep = pathname[2]; - if (letter < 97 || letter > 122 || // a..z A..Z - (sep !== ':')) { - return new Error('File URLs must specify absolute paths'); - } - return pathname.slice(1); - } -} - -function getPathFromURLPosix(url) { - if (url.hostname !== '') { - return new Error( - `File URLs on ${os.platform()} must use hostname 'localhost'` + - ' or not specify any hostname'); - } - var pathname = url.pathname; - for (var n = 0; n < pathname.length; n++) { - if (pathname[n] === '%') { - var third = pathname.codePointAt(n + 2) | 0x20; - if (pathname[n + 1] === '2' && third === 102) { - return new Error('Path must not include encoded / characters'); - } - } - } - return decodeURIComponent(pathname); -} - -function getPathFromURL(path) { - if (!(path instanceof URL)) - return path; - if (path.protocol !== 'file:') - return new Error('Only `file:` URLs are supported'); - return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path); -} - -exports.getPathFromURL = getPathFromURL; exports.URL = URL; exports.URLSearchParams = URLSearchParams; exports.domainToASCII = domainToASCII; diff --git a/test/parallel/test-fs-null-bytes.js b/test/parallel/test-fs-null-bytes.js index 39768489fbee6d..fa29e64c9b2382 100644 --- a/test/parallel/test-fs-null-bytes.js +++ b/test/parallel/test-fs-null-bytes.js @@ -2,7 +2,6 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); -const URL = require('url').URL; function check(async, sync) { const expected = /Path must be a string without null bytes/; @@ -49,62 +48,6 @@ check(null, fs.watch, 'foo\u0000bar', common.fail); check(null, fs.watchFile, 'foo\u0000bar', common.fail); check(fs.writeFile, fs.writeFileSync, 'foo\u0000bar'); -check(fs.access, fs.accessSync, new URL('file:///foo\u0000bar')); -check(fs.access, fs.accessSync, new URL('file:///foo\u0000bar'), fs.F_OK); -check(fs.appendFile, fs.appendFileSync, new URL('file:///foo\u0000bar')); -check(fs.chmod, fs.chmodSync, new URL('file:///foo\u0000bar'), '0644'); -check(fs.chown, fs.chownSync, new URL('file:///foo\u0000bar'), 12, 34); -check(fs.link, fs.linkSync, new URL('file:///foo\u0000bar'), 'foobar'); -check(fs.link, fs.linkSync, 'foobar', new URL('file:///foo\u0000bar')); -check(fs.lstat, fs.lstatSync, new URL('file:///foo\u0000bar')); -check(fs.mkdir, fs.mkdirSync, new URL('file:///foo\u0000bar'), '0755'); -check(fs.open, fs.openSync, new URL('file:///foo\u0000bar'), 'r'); -check(fs.readFile, fs.readFileSync, new URL('file:///foo\u0000bar')); -check(fs.readdir, fs.readdirSync, new URL('file:///foo\u0000bar')); -check(fs.readlink, fs.readlinkSync, new URL('file:///foo\u0000bar')); -check(fs.realpath, fs.realpathSync, new URL('file:///foo\u0000bar')); -check(fs.rename, fs.renameSync, new URL('file:///foo\u0000bar'), 'foobar'); -check(fs.rename, fs.renameSync, 'foobar', new URL('file:///foo\u0000bar')); -check(fs.rmdir, fs.rmdirSync, new URL('file:///foo\u0000bar')); -check(fs.stat, fs.statSync, new URL('file:///foo\u0000bar')); -check(fs.symlink, fs.symlinkSync, new URL('file:///foo\u0000bar'), 'foobar'); -check(fs.symlink, fs.symlinkSync, 'foobar', new URL('file:///foo\u0000bar')); -check(fs.truncate, fs.truncateSync, new URL('file:///foo\u0000bar')); -check(fs.unlink, fs.unlinkSync, new URL('file:///foo\u0000bar')); -check(null, fs.unwatchFile, new URL('file:///foo\u0000bar'), common.fail); -check(fs.utimes, fs.utimesSync, new URL('file:///foo\u0000bar'), 0, 0); -check(null, fs.watch, new URL('file:///foo\u0000bar'), common.fail); -check(null, fs.watchFile, new URL('file:///foo\u0000bar'), common.fail); -check(fs.writeFile, fs.writeFileSync, new URL('file:///foo\u0000bar')); - -check(fs.access, fs.accessSync, new URL('file:///foo%00bar')); -check(fs.access, fs.accessSync, new URL('file:///foo%00bar'), fs.F_OK); -check(fs.appendFile, fs.appendFileSync, new URL('file:///foo%00bar')); -check(fs.chmod, fs.chmodSync, new URL('file:///foo%00bar'), '0644'); -check(fs.chown, fs.chownSync, new URL('file:///foo%00bar'), 12, 34); -check(fs.link, fs.linkSync, new URL('file:///foo%00bar'), 'foobar'); -check(fs.link, fs.linkSync, 'foobar', new URL('file:///foo%00bar')); -check(fs.lstat, fs.lstatSync, new URL('file:///foo%00bar')); -check(fs.mkdir, fs.mkdirSync, new URL('file:///foo%00bar'), '0755'); -check(fs.open, fs.openSync, new URL('file:///foo%00bar'), 'r'); -check(fs.readFile, fs.readFileSync, new URL('file:///foo%00bar')); -check(fs.readdir, fs.readdirSync, new URL('file:///foo%00bar')); -check(fs.readlink, fs.readlinkSync, new URL('file:///foo%00bar')); -check(fs.realpath, fs.realpathSync, new URL('file:///foo%00bar')); -check(fs.rename, fs.renameSync, new URL('file:///foo%00bar'), 'foobar'); -check(fs.rename, fs.renameSync, 'foobar', new URL('file:///foo%00bar')); -check(fs.rmdir, fs.rmdirSync, new URL('file:///foo%00bar')); -check(fs.stat, fs.statSync, new URL('file:///foo%00bar')); -check(fs.symlink, fs.symlinkSync, new URL('file:///foo%00bar'), 'foobar'); -check(fs.symlink, fs.symlinkSync, 'foobar', new URL('file:///foo%00bar')); -check(fs.truncate, fs.truncateSync, new URL('file:///foo%00bar')); -check(fs.unlink, fs.unlinkSync, new URL('file:///foo%00bar')); -check(null, fs.unwatchFile, new URL('file:///foo%00bar'), common.fail); -check(fs.utimes, fs.utimesSync, new URL('file:///foo%00bar'), 0, 0); -check(null, fs.watch, new URL('file:///foo%00bar'), common.fail); -check(null, fs.watchFile, new URL('file:///foo%00bar'), common.fail); -check(fs.writeFile, fs.writeFileSync, new URL('file:///foo%00bar')); - // an 'error' for exists means that it doesn't exist. // one of many reasons why this file is the absolute worst. fs.exists('foo\u0000bar', common.mustCall((exists) => { diff --git a/test/parallel/test-fs-whatwg-url.js b/test/parallel/test-fs-whatwg-url.js deleted file mode 100644 index 7a94fd68d7e4fa..00000000000000 --- a/test/parallel/test-fs-whatwg-url.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - -const common = require('../common'); -const assert = require('assert'); -const path = require('path'); -const fs = require('fs'); -const os = require('os'); -const URL = require('url').URL; -const Buffer = require('buffer').Buffer; - -function pathToFileURL(p) { - if (!path.isAbsolute(p)) - throw new Error('Path must be absolute'); - if (common.isWindows && p.startsWith('\\\\')) - p = p.slice(2); - return new URL(`file://${p}`); -} - -const p = path.resolve(common.fixturesDir, 'a.js'); -const url = pathToFileURL(p); - -assert(url instanceof URL); - -// Check that we can pass in a URL object successfully -fs.readFile(url, common.mustCall((err, data) => { - assert.ifError(err); - assert(Buffer.isBuffer(data)); -})); - -// Check that using a non file:// URL reports an error -const httpUrl = new URL('http://example.org'); -fs.readFile(httpUrl, common.mustCall((err) => { - assert(err); - assert.strictEqual(err.message, - 'Only `file:` URLs are supported'); -})); - -// pct-encoded characters in the path will be decoded and checked -fs.readFile(new URL('file:///c:/tmp/%00test'), common.mustCall((err) => { - assert(err); - assert.strictEqual(err.message, - 'Path must be a string without null bytes'); -})); - -if (common.isWindows) { - // encoded back and forward slashes are not permitted on windows - ['%2f', '%2F', '%5c', '%5C'].forEach((i) => { - fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => { - assert(err); - assert.strictEqual(err.message, - 'Path must not include encoded \\ or / characters'); - })); - }); -} else { - // encoded forward slashes are not permitted on other platforms - ['%2f', '%2F'].forEach((i) => { - fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => { - assert(err); - assert.strictEqual(err.message, - 'Path must not include encoded / characters'); - })); - }); - - fs.readFile(new URL('file://hostname/a/b/c'), common.mustCall((err) => { - assert(err); - assert.strictEqual(err.message, - `File URLs on ${os.platform()} must use ` + - 'hostname \'localhost\' or not specify any hostname'); - })); -}