forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
url: return backslashes from fileURLToPath on win
PR-URL: nodejs#25349 Fixes: nodejs#25265 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com>
- Loading branch information
Showing
3 changed files
with
157 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
'use strict'; | ||
const { isWindows } = require('../common'); | ||
const assert = require('assert'); | ||
const url = require('url'); | ||
|
||
function testInvalidArgs(...args) { | ||
for (const arg of args) { | ||
assert.throws(() => url.fileURLToPath(arg), { | ||
code: 'ERR_INVALID_ARG_TYPE' | ||
}); | ||
} | ||
} | ||
|
||
// Input must be string or URL | ||
testInvalidArgs(null, undefined, 1, {}, true); | ||
|
||
// Input must be a file URL | ||
assert.throws(() => url.fileURLToPath('https://a/b/c'), { | ||
code: 'ERR_INVALID_URL_SCHEME' | ||
}); | ||
|
||
{ | ||
const withHost = new URL('file://host/a'); | ||
|
||
if (isWindows) { | ||
assert.strictEqual(url.fileURLToPath(withHost), '\\\\host\\a'); | ||
} else { | ||
assert.throws(() => url.fileURLToPath(withHost), { | ||
code: 'ERR_INVALID_FILE_URL_HOST' | ||
}); | ||
} | ||
} | ||
|
||
{ | ||
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' | ||
}); | ||
} | ||
} | ||
|
||
{ | ||
let testCases; | ||
if (isWindows) { | ||
testCases = [ | ||
// lowercase ascii alpha | ||
{ path: 'C:\\foo', fileURL: 'file:///C:/foo' }, | ||
// uppercase ascii alpha | ||
{ path: 'C:\\FOO', fileURL: 'file:///C:/FOO' }, | ||
// dir | ||
{ path: 'C:\\dir\\foo', fileURL: 'file:///C:/dir/foo' }, | ||
// trailing separator | ||
{ path: 'C:\\dir\\', fileURL: 'file:///C:/dir/' }, | ||
// dot | ||
{ path: 'C:\\foo.mjs', fileURL: 'file:///C:/foo.mjs' }, | ||
// space | ||
{ path: 'C:\\foo bar', fileURL: 'file:///C:/foo%20bar' }, | ||
// question mark | ||
{ path: 'C:\\foo?bar', fileURL: 'file:///C:/foo%3Fbar' }, | ||
// number sign | ||
{ path: 'C:\\foo#bar', fileURL: 'file:///C:/foo%23bar' }, | ||
// ampersand | ||
{ path: 'C:\\foo&bar', fileURL: 'file:///C:/foo&bar' }, | ||
// equals | ||
{ path: 'C:\\foo=bar', fileURL: 'file:///C:/foo=bar' }, | ||
// colon | ||
{ path: 'C:\\foo:bar', fileURL: 'file:///C:/foo:bar' }, | ||
// semicolon | ||
{ path: 'C:\\foo;bar', fileURL: 'file:///C:/foo;bar' }, | ||
// percent | ||
{ path: 'C:\\foo%bar', fileURL: 'file:///C:/foo%25bar' }, | ||
// backslash | ||
{ path: 'C:\\foo\\bar', fileURL: 'file:///C:/foo/bar' }, | ||
// backspace | ||
{ path: 'C:\\foo\bbar', fileURL: 'file:///C:/foo%08bar' }, | ||
// tab | ||
{ path: 'C:\\foo\tbar', fileURL: 'file:///C:/foo%09bar' }, | ||
// newline | ||
{ path: 'C:\\foo\nbar', fileURL: 'file:///C:/foo%0Abar' }, | ||
// carriage return | ||
{ path: 'C:\\foo\rbar', fileURL: 'file:///C:/foo%0Dbar' }, | ||
// latin1 | ||
{ path: 'C:\\fóóbàr', fileURL: 'file:///C:/f%C3%B3%C3%B3b%C3%A0r' }, | ||
// euro sign (BMP code point) | ||
{ path: 'C:\\€', fileURL: 'file:///C:/%E2%82%AC' }, | ||
// rocket emoji (non-BMP code point) | ||
{ path: 'C:\\🚀', fileURL: 'file:///C:/%F0%9F%9A%80' } | ||
]; | ||
} else { | ||
testCases = [ | ||
// lowercase ascii alpha | ||
{ path: '/foo', fileURL: 'file:///foo' }, | ||
// uppercase ascii alpha | ||
{ path: '/FOO', fileURL: 'file:///FOO' }, | ||
// dir | ||
{ path: '/dir/foo', fileURL: 'file:///dir/foo' }, | ||
// trailing separator | ||
{ path: '/dir/', fileURL: 'file:///dir/' }, | ||
// dot | ||
{ path: '/foo.mjs', fileURL: 'file:///foo.mjs' }, | ||
// space | ||
{ path: '/foo bar', fileURL: 'file:///foo%20bar' }, | ||
// question mark | ||
{ path: '/foo?bar', fileURL: 'file:///foo%3Fbar' }, | ||
// number sign | ||
{ path: '/foo#bar', fileURL: 'file:///foo%23bar' }, | ||
// ampersand | ||
{ path: '/foo&bar', fileURL: 'file:///foo&bar' }, | ||
// equals | ||
{ path: '/foo=bar', fileURL: 'file:///foo=bar' }, | ||
// colon | ||
{ path: '/foo:bar', fileURL: 'file:///foo:bar' }, | ||
// semicolon | ||
{ path: '/foo;bar', fileURL: 'file:///foo;bar' }, | ||
// percent | ||
{ path: '/foo%bar', fileURL: 'file:///foo%25bar' }, | ||
// backslash | ||
{ path: '/foo\\bar', fileURL: 'file:///foo%5Cbar' }, | ||
// backspace | ||
{ path: '/foo\bbar', fileURL: 'file:///foo%08bar' }, | ||
// tab | ||
{ path: '/foo\tbar', fileURL: 'file:///foo%09bar' }, | ||
// newline | ||
{ path: '/foo\nbar', fileURL: 'file:///foo%0Abar' }, | ||
// carriage return | ||
{ path: '/foo\rbar', fileURL: 'file:///foo%0Dbar' }, | ||
// latin1 | ||
{ path: '/fóóbàr', fileURL: 'file:///f%C3%B3%C3%B3b%C3%A0r' }, | ||
// euro sign (BMP code point) | ||
{ path: '/€', fileURL: 'file:///%E2%82%AC' }, | ||
// rocket emoji (non-BMP code point) | ||
{ path: '/🚀', fileURL: 'file:///%F0%9F%9A%80' }, | ||
]; | ||
} | ||
|
||
for (const { path, fileURL } of testCases) { | ||
const fromString = url.fileURLToPath(fileURL); | ||
assert.strictEqual(fromString, path); | ||
const fromURL = url.fileURLToPath(new URL(fileURL)); | ||
assert.strictEqual(fromURL, path); | ||
} | ||
} |