From 36fcbdc962e07b6bd61fcf6c36ac787c2479ff2d Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Sun, 14 Mar 2021 13:29:30 +0000 Subject: [PATCH 1/2] fix(path): Enable and fix file URL tests --- path/_util.ts | 15 ++++++++++++ path/from_file_url_test.ts | 8 ++---- path/posix.ts | 5 +++- path/to_file_url_test.ts | 50 ++++++++++++++------------------------ path/win32.ts | 7 +++--- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/path/_util.ts b/path/_util.ts index 046c443378e1..c2a23ade61d7 100644 --- a/path/_util.ts +++ b/path/_util.ts @@ -115,3 +115,18 @@ export function _format( if (dir === pathObject.root) return dir + base; return dir + sep + base; } + +const WHITESPACE_ENCODINGS: Record = { + "\u0009": "%09", + "\u000A": "%0A", + "\u000B": "%0B", + "\u000C": "%0C", + "\u000D": "%0D", + "\u0020": "%20", +}; + +export function encodeWhitespace(string: string): string { + return string.replaceAll(/[\s]/g, (c) => { + return WHITESPACE_ENCODINGS[c] ?? c; + }); +} diff --git a/path/from_file_url_test.ts b/path/from_file_url_test.ts index aa230dcb66fa..0ca6e714a01a 100644 --- a/path/from_file_url_test.ts +++ b/path/from_file_url_test.ts @@ -25,18 +25,14 @@ Deno.test("[path] fromFileUrl", function () { ); }); -const isCanary = /\d\.\d\.\d\+[0-9a-f]{7}/.test(Deno.version.deno); - Deno.test("[path] fromFileUrl (win32)", function () { assertEquals(win32.fromFileUrl(new URL("file:///home/foo")), "\\home\\foo"); assertEquals(win32.fromFileUrl("file:///"), "\\"); assertEquals(win32.fromFileUrl("file:///home/foo"), "\\home\\foo"); assertEquals(win32.fromFileUrl("file:///home/foo%20bar"), "\\home\\foo bar"); assertEquals(win32.fromFileUrl("file:///%"), "\\%"); - // TODO(kt3k): Enable this assertion again in stable deno when 1.8.0 is landed. - if (isCanary) { - assertEquals(win32.fromFileUrl("file://localhost/foo"), "\\foo"); - } + assertEquals(win32.fromFileUrl("file://127.0.0.1/foo"), "\\\\127.0.0.1\\foo"); + assertEquals(win32.fromFileUrl("file://localhost/foo"), "\\foo"); assertEquals(win32.fromFileUrl("file:///C:"), "C:\\"); assertEquals(win32.fromFileUrl("file:///C:/"), "C:\\"); // Drop the hostname if a drive letter is parsed. diff --git a/path/posix.ts b/path/posix.ts index ed3649bd35a8..dd5777c23f29 100644 --- a/path/posix.ts +++ b/path/posix.ts @@ -8,6 +8,7 @@ import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./_constants.ts"; import { _format, assertPath, + encodeWhitespace, isPosixPathSeparator, normalizeString, } from "./_util.ts"; @@ -499,6 +500,8 @@ export function toFileUrl(path: string): URL { throw new TypeError("Must be an absolute path."); } const url = new URL("file:///"); - url.pathname = path.replace(/%/g, "%25").replace(/\\/g, "%5C"); + url.pathname = encodeWhitespace( + path.replace(/%/g, "%25").replace(/\\/g, "%5C"), + ); return url; } diff --git a/path/to_file_url_test.ts b/path/to_file_url_test.ts index 9d2287a24436..134c0ebcef57 100644 --- a/path/to_file_url_test.ts +++ b/path/to_file_url_test.ts @@ -2,14 +2,9 @@ import { posix, win32 } from "./mod.ts"; import { assertEquals, assertThrows } from "../testing/asserts.ts"; -const isCanary = /\d\.\d\.\d\+[0-9a-f]{7}/.test(Deno.version.deno); - Deno.test("[path] toFileUrl", function () { assertEquals(posix.toFileUrl("/home/foo").href, "file:///home/foo"); - // TODO(kt3k): Enable this assertion again in stable deno when 1.8.0 is landed. - if (isCanary) { - assertEquals(posix.toFileUrl("/home/ ").href, "file:///home/"); - } + assertEquals(posix.toFileUrl("/home/ ").href, "file:///home/%20"); assertEquals(posix.toFileUrl("/home/%20").href, "file:///home/%2520"); assertEquals(posix.toFileUrl("/home\\foo").href, "file:///home%5Cfoo"); assertThrows( @@ -22,23 +17,17 @@ Deno.test("[path] toFileUrl", function () { TypeError, "Must be an absolute path.", ); - // TODO(kt3k): Enable this assertion again in stable deno when 1.8.0 is landed. - if (isCanary) { - assertEquals( - posix.toFileUrl("//localhost/home/foo").href, - "file:///localhost/home/foo", - ); - assertEquals(posix.toFileUrl("//localhost/").href, "file:///localhost/"); - assertEquals(posix.toFileUrl("//:/home/foo").href, "file:///:/home/foo"); - } + assertEquals( + posix.toFileUrl("//localhost/home/foo").href, + "file:///localhost/home/foo", + ); + assertEquals(posix.toFileUrl("//localhost/").href, "file:///localhost/"); + assertEquals(posix.toFileUrl("//:/home/foo").href, "file:///:/home/foo"); }); Deno.test("[path] toFileUrl (win32)", function () { assertEquals(win32.toFileUrl("/home/foo").href, "file:///home/foo"); - // TODO(kt3k): Enable this assertion again in stable deno when 1.8.0 is landed. - if (isCanary) { - assertEquals(win32.toFileUrl("/home/ ").href, "file:///home/"); - } + assertEquals(win32.toFileUrl("/home/ ").href, "file:///home/%20"); assertEquals(win32.toFileUrl("/home/%20").href, "file:///home/%2520"); assertEquals(win32.toFileUrl("/home\\foo").href, "file:///home/foo"); assertThrows( @@ -47,19 +36,16 @@ Deno.test("[path] toFileUrl (win32)", function () { "Must be an absolute path.", ); assertEquals(win32.toFileUrl("C:/").href, "file:///C:/"); - // TODO(kt3k): Enable this assertion again in stable deno when 1.8.0 is landed. - if (isCanary) { - assertThrows( - () => - assertEquals( - win32.toFileUrl("//localhost/home/foo").href, - "file://localhost/home/foo", - ), - TypeError, - "Invalid hostname.", - ); - assertEquals(win32.toFileUrl("//localhost/").href, "file:///localhost/"); - } + assertEquals( + win32.toFileUrl("//localhost/home/foo").href, + "file:///home/foo", + ); + assertEquals( + win32.toFileUrl("//127.0.0.1/home/foo").href, + "file://127.0.0.1/home/foo", + ); + assertEquals(win32.toFileUrl("//localhost/").href, "file:///"); + assertEquals(win32.toFileUrl("//127.0.0.1/").href, "file://127.0.0.1/"); assertThrows( () => win32.toFileUrl("//:/home/foo").href, TypeError, diff --git a/path/win32.ts b/path/win32.ts index d456c68e44ea..273e168a02d2 100644 --- a/path/win32.ts +++ b/path/win32.ts @@ -13,6 +13,7 @@ import { import { _format, assertPath, + encodeWhitespace, isPathSeparator, isWindowsDeviceRoot, normalizeString, @@ -987,11 +988,11 @@ export function toFileUrl(path: string): URL { throw new TypeError("Must be an absolute path."); } const [, hostname, pathname] = path.match( - /^(?:[/\\]{2}([^/\\]+)(?=[/\\][^/\\]))?(.*)/, + /^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/, )!; const url = new URL("file:///"); - url.pathname = pathname.replace(/%/g, "%25"); - if (hostname != null) { + url.pathname = encodeWhitespace(pathname.replace(/%/g, "%25")); + if (hostname != null && hostname != "localhost") { url.hostname = hostname; if (!url.hostname) { throw new TypeError("Invalid hostname."); From 396738970f78e47cb56bc73e1db94eb5329d905e Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Sun, 14 Mar 2021 13:37:19 +0000 Subject: [PATCH 2/2] fixup! fix(path): Enable and fix file URL tests --- path/win32.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/path/win32.ts b/path/win32.ts index 273e168a02d2..3afafd1f28be 100644 --- a/path/win32.ts +++ b/path/win32.ts @@ -980,7 +980,7 @@ export function fromFileUrl(url: string | URL): string { * * toFileUrl("\\home\\foo"); // new URL("file:///home/foo") * toFileUrl("C:\\Users\\foo"); // new URL("file:///C:/Users/foo") - * toFileUrl("\\\\localhost\\home\\foo"); // new URL("file://localhost/home/foo") + * toFileUrl("\\\\127.0.0.1\\home\\foo"); // new URL("file://127.0.0.1/home/foo") * @param path to convert to file URL */ export function toFileUrl(path: string): URL {