improve windows absolute path detection

This commit is contained in:
Tobias Koppers 2020-07-03 10:18:41 +02:00
parent e14e14b4b2
commit a11922fea3
2 changed files with 42 additions and 6 deletions

View File

@ -11,6 +11,7 @@ const { getMimetype: getDataUrlMimetype } = require("./DataURI");
/** @typedef {(error: Error|null, result?: Buffer) => void} ErrorFirstCallback */
const backSlashCharCode = "\\".charCodeAt(0);
const slashCharCode = "/".charCodeAt(0);
const aLowerCaseCharCode = "a".charCodeAt(0);
const zLowerCaseCharCode = "z".charCodeAt(0);
const aUpperCaseCharCode = "A".charCodeAt(0);
@ -20,6 +21,8 @@ const _9CharCode = "9".charCodeAt(0);
const plusCharCode = "+".charCodeAt(0);
const hyphenCharCode = "-".charCodeAt(0);
const colonCharCode = ":".charCodeAt(0);
const hashCharCode = "#".charCodeAt(0);
const queryCharCode = "?".charCodeAt(0);
/**
* Get scheme if specifier is an absolute URL specifier
* e.g. Absolute specifiers like 'file:///user/webpack/index.js'
@ -34,8 +37,9 @@ function getScheme(specifier) {
if (
(start < aLowerCaseCharCode || start > zLowerCaseCharCode) &&
(start < aUpperCaseCharCode || start > zUpperCaseCharCode)
)
) {
return undefined;
}
let i = 1;
let ch = specifier.charCodeAt(i);
@ -53,8 +57,21 @@ function getScheme(specifier) {
// Scheme must end with colon
if (ch !== colonCharCode) return undefined;
// Check for Windows absolute path
if (specifier.charCodeAt(i + 1) === backSlashCharCode) return undefined;
// https://url.spec.whatwg.org/#url-miscellaneous
if (i === 1) {
const nextChar = i + 1 < specifier.length ? specifier.charCodeAt(i + 1) : 0;
if (
nextChar === 0 ||
nextChar === backSlashCharCode ||
nextChar === slashCharCode ||
nextChar === hashCharCode ||
nextChar === queryCharCode
) {
return undefined;
}
}
return specifier.slice(0, i).toLowerCase();
}
@ -64,7 +81,8 @@ function getScheme(specifier) {
* @returns {string|null} protocol if absolute URL specifier provided
*/
function getProtocol(specifier) {
return getScheme(specifier) + ":";
const scheme = getScheme(specifier);
return scheme === undefined ? undefined : scheme + ":";
}
/**

View File

@ -47,12 +47,28 @@ const samples = [
{
specifier: "D:\\path\\file.js",
expected: undefined
},
{
specifier: "d:/path/file.js",
expected: undefined
},
{
specifier: "z:#foo",
expected: undefined
},
{
specifier: "Z:?query",
expected: undefined
},
{
specifier: "C:",
expected: undefined
}
];
describe("getScheme", () => {
samples.forEach(({ specifier, expected }, i) => {
it(`sample #${i + 1}`, () => {
it(`should handle ${specifier}`, () => {
expect(getScheme(specifier)).toBe(expected);
});
});
@ -60,8 +76,10 @@ describe("getScheme", () => {
describe("getProtocol", () => {
samples.forEach(({ specifier, expected }, i) => {
it(`sample #${i + 1}`, () => {
expect(getProtocol(specifier)).toBe(expected + ":");
it(`should handle ${specifier}`, () => {
expect(getProtocol(specifier)).toBe(
expected ? expected + ":" : undefined
);
});
});
});