From f53ce16b8b43f78d6dffe271054f327899ea0e57 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Mon, 19 Aug 2024 23:55:09 -0400 Subject: [PATCH] OS.Path shim: Add Windows version of normalize() from Fx102 Should fix #4588 --- chrome/content/zotero/osfile.mjs | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/chrome/content/zotero/osfile.mjs b/chrome/content/zotero/osfile.mjs index 0c1892cdc5..1f7286ab6d 100644 --- a/chrome/content/zotero/osfile.mjs +++ b/chrome/content/zotero/osfile.mjs @@ -316,6 +316,59 @@ export let OS = { // From Firefox 102 normalize: function (path) { + if (Services.appinfo.OS == "WINNT") { + let stack = []; + + if (!path.startsWith("\\\\")) { + // Normalize "/" to "\\" + path = path.replace(/\//g, "\\"); + } + + // Remove the drive (we will put it back at the end) + let root = winGetDrive(path); + if (root) { + path = path.slice(root.length); + } + + // Remember whether we need to restore a leading "\\" or drive name. + let absolute = winIsAbsolute(path); + + // And now, fill |stack| from the components, + // popping whenever there is a ".." + path.split("\\").forEach(function loop(v) { + switch (v) { + case "": + case ".": // Ignore + break; + case "..": + if (!stack.length) { + if (absolute) { + throw new Error("Path is ill-formed: attempting to go past root"); + } else { + stack.push(".."); + } + } else if (stack[stack.length - 1] == "..") { + stack.push(".."); + } else { + stack.pop(); + } + break; + default: + stack.push(v); + } + }); + + // Put everything back together + let result = stack.join("\\"); + if (absolute || root) { + result = "\\" + result; + } + if (root) { + result = root + result; + } + return result; + } + let stack = []; let absolute; if (path.length >= 0 && path[0] == "/") { @@ -401,6 +454,11 @@ var winGetDrive = function (path) { return path.slice(0, index + 1); }; +var winIsAbsolute = function (path) { + let index = path.indexOf(":"); + return path.length > index + 1 && path[index + 1] == "\\"; +}; + function wrapWrite(func) { return async function () { try {