diff --git a/.github/workflows/CI-CD.yaml b/.github/workflows/CI-CD.yaml index 826d62a1..fe84644e 100644 --- a/.github/workflows/CI-CD.yaml +++ b/.github/workflows/CI-CD.yaml @@ -67,7 +67,7 @@ jobs: matrix: os: - ubuntu-latest # Chrome, Firefox - - windows-latest # Internet Explorer + - windows-latest # Edge steps: - name: Checkout source diff --git a/lib/resolve-external.js b/lib/resolve-external.js index 074785c8..9e17ed6f 100644 --- a/lib/resolve-external.js +++ b/lib/resolve-external.js @@ -75,11 +75,7 @@ function crawl (obj, path, $refs, options, external, seen) { if (external && $Ref.is$Ref(obj)) { /* Correct the reference in the external document so we can resolve it */ let withoutHash = url.stripHash(path); - const isFileUrl = withoutHash.substr(0, 7).toLowerCase() === "file://"; - if (isFileUrl) { - // Strip-off the protocol - withoutHash = withoutHash.substr(7); - } + withoutHash = url.removeFileProtocol(withoutHash); obj.$ref = withoutHash + obj.$ref; } diff --git a/lib/util/url.js b/lib/util/url.js index d77763bd..0abadd15 100644 --- a/lib/util/url.js +++ b/lib/util/url.js @@ -240,6 +240,34 @@ exports.toFileSystemPath = function toFileSystemPath (path, keepFileProtocol) { return path; }; +/** + * Removes file protocol from path. + * + * @param {string} path + * @returns {string} + */ +exports.removeFileProtocol = function removeFileProtocol (path) { + // Step 1: `decodeURI` will decode characters such as Cyrillic characters, spaces, etc. + path = decodeURI(path); + + // Step 2: Manually decode characters that are not decoded by `decodeURI`. + // This includes characters such as "#" and "?", which have special meaning in URLs, + // but are just normal characters in a filesystem path. + for (let i = 0; i < urlDecodePatterns.length; i += 2) { + path = path.replace(urlDecodePatterns[i], urlDecodePatterns[i + 1]); + } + + // Step 3: If it's a "file://" URL, then format it consistently + // or convert it to a local filesystem path + let isFileUrl = path.substr(0, 7).toLowerCase() === "file://"; + if (isFileUrl) { + // Strip-off the protocol, and the initial "/", if there is one + path = path.substr(7); + } + + return path; +}; + /** * Converts a $ref pointer to a valid JSON Path. * diff --git a/test/utils/helper.js b/test/utils/helper.js index 6e0be22c..34ad71f2 100644 --- a/test/utils/helper.js +++ b/test/utils/helper.js @@ -83,7 +83,7 @@ const helper = (module.exports = { if (typeof entry.$ref === "string") { if (entry.$ref.startsWith("#")) { clonedExpected[i].$ref = - url.toFileSystemPath(filePath) + entry.$ref; + url.removeFileProtocol(filePath) + entry.$ref; } continue; } else {