diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-07-30 16:46:15 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-30 16:46:15 -0400 |
commit | fe884c557a76fd288f7457aa433052f65be70c81 (patch) | |
tree | 2e1c114eb128ce1baa1d7c8dc145423b8de86af7 | |
parent | 7a3810195de532bf360afcbf85a0d9cf6ef662be (diff) |
fix(compile/windows): handle cjs re-export of relative path with parent component (#24795)
Closes https://github.com/denoland/deno/issues/24785
7 files changed, 94 insertions, 1 deletions
diff --git a/ext/node_resolver/path.rs b/ext/node_resolver/path.rs index 8c33285db..ece270cd9 100644 --- a/ext/node_resolver/path.rs +++ b/ext/node_resolver/path.rs @@ -13,8 +13,31 @@ pub trait PathClean<T> { impl PathClean<PathBuf> for PathBuf { fn clean(&self) -> PathBuf { + fn is_clean_path(path: &Path) -> bool { + let path = path.to_string_lossy(); + let mut current_index = 0; + while let Some(index) = path[current_index..].find("\\.") { + let trailing_index = index + current_index + 2; + let mut trailing_chars = path[trailing_index..].chars(); + match trailing_chars.next() { + Some('.') => match trailing_chars.next() { + Some('/') | Some('\\') | None => { + return false; + } + _ => {} + }, + Some('/') | Some('\\') => { + return false; + } + _ => {} + } + current_index = trailing_index; + } + true + } + let path = path_clean::PathClean::clean(self); - if cfg!(windows) && path.to_string_lossy().contains("..\\") { + if cfg!(windows) && !is_clean_path(&path) { // temporary workaround because path_clean::PathClean::clean is // not good enough on windows let mut components = Vec::new(); @@ -105,6 +128,20 @@ pub fn strip_unc_prefix(path: PathBuf) -> PathBuf { mod test { #[cfg(windows)] #[test] + fn test_path_clean() { + use super::*; + + run_test("C:\\test\\./file.txt", "C:\\test\\file.txt"); + run_test("C:\\test\\../other/file.txt", "C:\\other\\file.txt"); + run_test("C:\\test\\../other\\file.txt", "C:\\other\\file.txt"); + + fn run_test(input: &str, expected: &str) { + assert_eq!(PathBuf::from(input).clean(), PathBuf::from(expected)); + } + } + + #[cfg(windows)] + #[test] fn test_strip_unc_prefix() { use std::path::PathBuf; diff --git a/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/dir/index.js b/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/dir/index.js new file mode 100644 index 000000000..3ab44b658 --- /dev/null +++ b/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/dir/index.js @@ -0,0 +1,7 @@ +"use strict"; +class Hello { + sayHello() { + console.log("Hi."); + } +} +exports.hello = new Hello(); diff --git a/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/package.json b/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/package.json new file mode 100644 index 000000000..ae69f6046 --- /dev/null +++ b/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/cjs-reexport-relative-parent", + "version": "1.0.0", + "main": "./sub_dir/index.js" +} diff --git a/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/sub_dir/index.js b/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/sub_dir/index.js new file mode 100644 index 000000000..1c52e5457 --- /dev/null +++ b/tests/registry/npm/@denotest/cjs-reexport-relative-parent/1.0.0/sub_dir/index.js @@ -0,0 +1,19 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +// collision will occur with __esModule in other_file.js +Object.defineProperty(exports, "__esModule", { value: true }); +const other_file_1 = __importDefault(require("../dir")); +__exportStar(require("../dir"), exports); +exports.default = other_file_1.default; diff --git a/tests/specs/compile/npm_cjs_reexport_relative_parent_component/__test__.jsonc b/tests/specs/compile/npm_cjs_reexport_relative_parent_component/__test__.jsonc new file mode 100644 index 000000000..be2bbd1e4 --- /dev/null +++ b/tests/specs/compile/npm_cjs_reexport_relative_parent_component/__test__.jsonc @@ -0,0 +1,22 @@ +{ + "tempDir": true, + "steps": [{ + "if": "unix", + "args": "compile --output main main.ts", + "output": "[WILDCARD]" + }, { + "if": "unix", + "commandName": "./main", + "args": [], + "output": "main.out" + }, { + "if": "windows", + "args": "compile --output main.exe main.ts", + "output": "[WILDCARD]" + }, { + "if": "windows", + "commandName": "./main.exe", + "args": [], + "output": "main.out" + }] +} diff --git a/tests/specs/compile/npm_cjs_reexport_relative_parent_component/main.out b/tests/specs/compile/npm_cjs_reexport_relative_parent_component/main.out new file mode 100644 index 000000000..ed3193f8d --- /dev/null +++ b/tests/specs/compile/npm_cjs_reexport_relative_parent_component/main.out @@ -0,0 +1 @@ +Hi. diff --git a/tests/specs/compile/npm_cjs_reexport_relative_parent_component/main.ts b/tests/specs/compile/npm_cjs_reexport_relative_parent_component/main.ts new file mode 100644 index 000000000..c2935aeed --- /dev/null +++ b/tests/specs/compile/npm_cjs_reexport_relative_parent_component/main.ts @@ -0,0 +1,2 @@ +import { hello } from "npm:@denotest/cjs-reexport-relative-parent"; +hello.sayHello(); |