diff options
Diffstat (limited to 'std/path')
-rw-r--r-- | std/path/from_file_url_test.ts | 44 | ||||
-rw-r--r-- | std/path/posix.ts | 10 | ||||
-rw-r--r-- | std/path/win32.ts | 21 |
3 files changed, 51 insertions, 24 deletions
diff --git a/std/path/from_file_url_test.ts b/std/path/from_file_url_test.ts index 8fe47b27f..b1a1af99c 100644 --- a/std/path/from_file_url_test.ts +++ b/std/path/from_file_url_test.ts @@ -1,31 +1,49 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { posix, win32 } from "./mod.ts"; -import { assertEquals } from "../testing/asserts.ts"; +import { assertEquals, assertThrows } from "../testing/asserts.ts"; Deno.test("[path] fromFileUrl", function () { assertEquals(posix.fromFileUrl(new URL("file:///home/foo")), "/home/foo"); + assertEquals(posix.fromFileUrl("file:///"), "/"); assertEquals(posix.fromFileUrl("file:///home/foo"), "/home/foo"); assertEquals(posix.fromFileUrl("file:///home/foo%20bar"), "/home/foo bar"); - assertEquals(posix.fromFileUrl("https://example.com/foo"), "/foo"); - assertEquals(posix.fromFileUrl("file:///"), "/"); - // Drive letters are supported platform-independently to align with the WHATWG - // URL specification. - assertEquals(posix.fromFileUrl("file:///c:"), "c:/"); - assertEquals(posix.fromFileUrl("file:///c:/"), "c:/"); - assertEquals(posix.fromFileUrl("file:///C:/"), "C:/"); - assertEquals(posix.fromFileUrl("file:///C:/Users/"), "C:/Users/"); + assertEquals(posix.fromFileUrl("file://localhost/foo"), "/foo"); + assertEquals(posix.fromFileUrl("file:///C:"), "/C:"); + assertEquals(posix.fromFileUrl("file:///C:/"), "/C:/"); + assertEquals(posix.fromFileUrl("file:///C:/Users/"), "/C:/Users/"); assertEquals(posix.fromFileUrl("file:///C:foo/bar"), "/C:foo/bar"); + assertThrows( + () => posix.fromFileUrl("http://localhost/foo"), + TypeError, + "Must be a file URL.", + ); + assertThrows( + () => posix.fromFileUrl("abcd://localhost/foo"), + TypeError, + "Must be a file URL.", + ); }); 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("https://example.com/foo"), "\\foo"); - assertEquals(win32.fromFileUrl("file:///"), "\\"); - assertEquals(win32.fromFileUrl("file:///c:"), "c:\\"); - assertEquals(win32.fromFileUrl("file:///c:/"), "c:\\"); + assertEquals(win32.fromFileUrl("file://localhost/foo"), "\\\\localhost\\foo"); + assertEquals(win32.fromFileUrl("file:///C:"), "C:\\"); assertEquals(win32.fromFileUrl("file:///C:/"), "C:\\"); + // Drop the hostname if a drive letter is parsed. + assertEquals(win32.fromFileUrl("file://localhost/C:/"), "C:\\"); assertEquals(win32.fromFileUrl("file:///C:/Users/"), "C:\\Users\\"); assertEquals(win32.fromFileUrl("file:///C:foo/bar"), "\\C:foo\\bar"); + assertThrows( + () => win32.fromFileUrl("http://localhost/foo"), + TypeError, + "Must be a file URL.", + ); + assertThrows( + () => win32.fromFileUrl("abcd://localhost/foo"), + TypeError, + "Must be a file URL.", + ); }); diff --git a/std/path/posix.ts b/std/path/posix.ts index fca7f081b..afbc9303f 100644 --- a/std/path/posix.ts +++ b/std/path/posix.ts @@ -430,11 +430,11 @@ export function parse(path: string): ParsedPath { /** Converts a file URL to a path string. * * fromFileUrl("file:///home/foo"); // "/home/foo" - * - * Note that non-file URLs are treated as file URLs and irrelevant components - * are ignored. */ export function fromFileUrl(url: string | URL): string { - return decodeURIComponent((url instanceof URL ? url : new URL(url)).pathname - .replace(/^\/*([A-Za-z]:)(\/|$)/, "$1/")); + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + return decodeURIComponent(url.pathname); } diff --git a/std/path/win32.ts b/std/path/win32.ts index 0283f4b9c..eed1cbdb8 100644 --- a/std/path/win32.ts +++ b/std/path/win32.ts @@ -907,16 +907,25 @@ export function parse(path: string): ParsedPath { /** Converts a file URL to a path string. * - * fromFileUrl("file:///C:/Users/foo"); // "C:\\Users\\foo" * fromFileUrl("file:///home/foo"); // "\\home\\foo" - * - * Note that non-file URLs are treated as file URLs and irrelevant components - * are ignored. + * fromFileUrl("file:///C:/Users/foo"); // "C:\\Users\\foo" + * fromFileUrl("file://localhost/home/foo"); // "\\\\localhost\\home\\foo" */ export function fromFileUrl(url: string | URL): string { - return decodeURIComponent( - (url instanceof URL ? url : new URL(url)).pathname + url = url instanceof URL ? url : new URL(url); + if (url.protocol != "file:") { + throw new TypeError("Must be a file URL."); + } + let path = decodeURIComponent( + url.pathname .replace(/^\/*([A-Za-z]:)(\/|$)/, "$1/") .replace(/\//g, "\\"), ); + if (url.hostname != "") { + // Note: The `URL` implementation guarantees that the drive letter and + // hostname are mutually exclusive. Otherwise it would not have been valid + // to append the hostname and path like this. + path = `\\\\${url.hostname}${path}`; + } + return path; } |