Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,9 @@ A Node.js API that consumes `file:` URLs (such as certain functions in the
[`fs`][] module) encountered a file URL with an incompatible path. The exact
semantics for determining whether a path can be used is platform-dependent.

The thrown error object includes an `input` property that contains the URL object
of the invalid `file:` URL.

<a id="ERR_INVALID_HANDLE_TYPE"></a>

### `ERR_INVALID_HANDLE_TYPE`
Expand Down
5 changes: 4 additions & 1 deletion lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,10 @@ E('ERR_INVALID_FD',
E('ERR_INVALID_FD_TYPE', 'Unsupported fd type: %s', TypeError);
E('ERR_INVALID_FILE_URL_HOST',
'File URL host must be "localhost" or empty on %s', TypeError);
E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s', TypeError);
E('ERR_INVALID_FILE_URL_PATH', function(reason, input) {
this.input = input;
return `File URL path ${reason}`;
}, TypeError);
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent', TypeError);
E('ERR_INVALID_HTTP_TOKEN', '%s must be a valid HTTP token ["%s"]', TypeError, HideStackFramesError);
E('ERR_INVALID_IP_ADDRESS', 'Invalid IP address: %s', TypeError);
Expand Down
7 changes: 4 additions & 3 deletions lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -1463,7 +1463,7 @@ function getPathFromURLWin32(url) {
if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F /
(pathname[n + 1] === '5' && third === 99)) { // 5c 5C \
throw new ERR_INVALID_FILE_URL_PATH(
'must not include encoded \\ or / characters',
'must not include encoded \\ or / characters', url,
);
}
}
Expand All @@ -1484,7 +1484,7 @@ function getPathFromURLWin32(url) {
const sep = StringPrototypeCharAt(pathname, 2);
if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z || // a..z A..Z
(sep !== ':')) {
throw new ERR_INVALID_FILE_URL_PATH('must be absolute');
throw new ERR_INVALID_FILE_URL_PATH('must be absolute', url);
}
return StringPrototypeSlice(pathname, 1);
}
Expand Down Expand Up @@ -1551,7 +1551,7 @@ function getPathBufferFromURLWin32(url) {

if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z || // a..z A..Z
(sep !== CHAR_COLON)) {
throw new ERR_INVALID_FILE_URL_PATH('must be absolute');
throw new ERR_INVALID_FILE_URL_PATH('must be absolute', url);
}

// Now, we'll just return everything except the first byte of
Expand All @@ -1570,6 +1570,7 @@ function getPathFromURLPosix(url) {
if (pathname[n + 1] === '2' && third === 102) {
throw new ERR_INVALID_FILE_URL_PATH(
'must not include encoded / characters',
url,
);
}
}
Expand Down
18 changes: 0 additions & 18 deletions test/parallel/test-url-fileurltopath.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,6 @@ test('fileURLToPath with host', () => {
}
});

test('fileURLToPath with invalid path', () => {
if (isWindows) {
assert.throws(() => url.fileURLToPath('file:///C:/a%2F/'), {
code: 'ERR_INVALID_FILE_URL_PATH'
});
assert.throws(() => url.fileURLToPath('file:///C:/a%5C/'), {
code: 'ERR_INVALID_FILE_URL_PATH'
});
assert.throws(() => url.fileURLToPath('file:///?:/'), {
code: 'ERR_INVALID_FILE_URL_PATH'
});
} else {
assert.throws(() => url.fileURLToPath('file:///a%2F/'), {
code: 'ERR_INVALID_FILE_URL_PATH'
});
}
});

const windowsTestCases = [
// Lowercase ascii alpha
{ path: 'C:\\foo', fileURL: 'file:///C:/foo' },
Expand Down
25 changes: 25 additions & 0 deletions test/parallel/test-url-invalid-file-url-path-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

// This tests that url.fileURLToPath() throws ERR_INVALID_FILE_URL_PATH
// for invalid file URL paths along with the input property.

const { isWindows } = require('../common');
const assert = require('assert');
const url = require('url');

const inputs = [];

if (isWindows) {
inputs.push('file:///C:/a%2F/', 'file:///C:/a%5C/', 'file:///?:/');
} else {
inputs.push('file:///a%2F/');
}

for (const input of inputs) {
assert.throws(() => url.fileURLToPath(input), (err) => {
assert.strictEqual(err.code, 'ERR_INVALID_FILE_URL_PATH');
assert(err.input instanceof URL);
assert.strictEqual(err.input.href, input);
return true;
});
}
Loading