From 943dd5f9ed1857d9f04cdca77ed5139d69918173 Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Wed, 3 May 2017 09:24:42 +0200 Subject: [PATCH] url: handle windows drive letter in the file state `C|` should not satisfy the condition to not copy the base's path. It also synchronises WPT url test data to verify the update in upstream. PR-URL: https://github.com/nodejs/node/pull/12808 Refs: https://github.com/whatwg/url/pull/305 Refs: https://github.com/w3c/web-platform-tests/pull/5754 Reviewed-By: Refael Ackermann Reviewed-By: James M Snell Reviewed-By: Joyee Cheung Reviewed-By: Timothy Gu --- src/node_url.cc | 8 +-- test/fixtures/url-tests.js | 101 ++++++++++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/node_url.cc b/src/node_url.cc index 50a9380d379648..2bdc080953f294 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1169,6 +1169,7 @@ void URL::Parse(const char* input, while (p <= end) { const char ch = p < end ? p[0] : kEOL; + const size_t remaining = end == p ? 0 : (end - p - 1); if (IsASCIITabOrNewline(ch)) { if (state == kAuthority) { @@ -1653,9 +1654,10 @@ void URL::Parse(const char* input, state = kFragment; break; default: - if ((!IsWindowsDriveLetter(ch, p[1]) || - end - p == 1 || - (p[2] != '/' && + if ((remaining == 0 || + !IsWindowsDriveLetter(ch, p[1]) || + (remaining >= 2 && + p[2] != '/' && p[2] != '\\' && p[2] != '?' && p[2] != '#'))) { diff --git a/test/fixtures/url-tests.js b/test/fixtures/url-tests.js index 355388eaaf6baf..befe325f931c6c 100644 --- a/test/fixtures/url-tests.js +++ b/test/fixtures/url-tests.js @@ -1,7 +1,7 @@ 'use strict'; /* WPT Refs: - https://github.com/w3c/web-platform-tests/blob/3afae94/url/urltestdata.json + https://github.com/w3c/web-platform-tests/blob/28541bb/url/urltestdata.json License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html */ module.exports = @@ -5430,6 +5430,105 @@ module.exports = "search": "?chai", "hash": "" }, + "# Windows drive letter handling with the 'file:' base URL", + { + "input": "C|", + "base": "file://host/dir/file", + "href": "file:///C:", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C:", + "search": "", + "hash": "" + }, + { + "input": "C|#", + "base": "file://host/dir/file", + "href": "file:///C:#", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C:", + "search": "", + "hash": "" + }, + { + "input": "C|?", + "base": "file://host/dir/file", + "href": "file:///C:?", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C:", + "search": "", + "hash": "" + }, + { + "input": "C|/", + "base": "file://host/dir/file", + "href": "file:///C:/", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C:/", + "search": "", + "hash": "" + }, + { + "input": "C|\\", + "base": "file://host/dir/file", + "href": "file:///C:/", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C:/", + "search": "", + "hash": "" + }, + { + "input": "C", + "base": "file://host/dir/file", + "href": "file://host/dir/C", + "protocol": "file:", + "username": "", + "password": "", + "host": "host", + "hostname": "host", + "port": "", + "pathname": "/dir/C", + "search": "", + "hash": "" + }, + { + "input": "C|a", + "base": "file://host/dir/file", + "href": "file://host/dir/C|a", + "protocol": "file:", + "username": "", + "password": "", + "host": "host", + "hostname": "host", + "port": "", + "pathname": "/dir/C|a", + "search": "", + "hash": "" + }, "# Windows drive letter quirk with not empty host", { "input": "file://example.net/C:/",