Skip to content

Commit

Permalink
fix(node): handle cjs exports with escaped chars (#27438)
Browse files Browse the repository at this point in the history
Closes #27422
  • Loading branch information
dsherret authored Dec 21, 2024
1 parent 26425a1 commit e6869d7
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 11 deletions.
26 changes: 15 additions & 11 deletions resolvers/node/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer, TNodeResolverEnv: NodeResolverEnv>
add_export(
&mut source,
export,
&format!("mod[\"{}\"]", escape_for_double_quote_string(export)),
&format!("mod[{}]", to_double_quote_string(export)),
&mut temp_var_count,
);
}
Expand Down Expand Up @@ -561,8 +561,8 @@ fn add_export(
"const __deno_export_{temp_var_count}__ = {initializer};"
));
source.push(format!(
"export {{ __deno_export_{temp_var_count}__ as \"{}\" }};",
escape_for_double_quote_string(name)
"export {{ __deno_export_{temp_var_count}__ as {} }};",
to_double_quote_string(name)
));
} else {
source.push(format!("export const {name} = {initializer};"));
Expand Down Expand Up @@ -620,14 +620,9 @@ fn not_found(path: &str, referrer: &Path) -> AnyError {
std::io::Error::new(std::io::ErrorKind::NotFound, msg).into()
}

fn escape_for_double_quote_string(text: &str) -> Cow<str> {
// this should be rare, so doing a scan first before allocating is ok
if text.chars().any(|c| matches!(c, '"' | '\\')) {
// don't bother making this more complex for perf because it's rare
Cow::Owned(text.replace('\\', "\\\\").replace('"', "\\\""))
} else {
Cow::Borrowed(text)
}
fn to_double_quote_string(text: &str) -> String {
// serde can handle this for us
serde_json::to_string(text).unwrap()
}

#[cfg(test)]
Expand Down Expand Up @@ -665,4 +660,13 @@ mod tests {
Some(("@some-package/core".to_string(), "./actions".to_string()))
);
}

#[test]
fn test_to_double_quote_string() {
assert_eq!(to_double_quote_string("test"), "\"test\"");
assert_eq!(
to_double_quote_string("\r\n\t\"test"),
"\"\\r\\n\\t\\\"test\""
);
}
}
4 changes: 4 additions & 0 deletions tests/specs/node/cjs_key_escaped_whitespace/__test__.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"args": "run -A main.js",
"output": "output.out"
}
2 changes: 2 additions & 0 deletions tests/specs/node/cjs_key_escaped_whitespace/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const bang = await import("./module.cjs");
console.log("imported:", bang);
6 changes: 6 additions & 0 deletions tests/specs/node/cjs_key_escaped_whitespace/module.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
"\nx": "test",
"\ty": "test",
"\rz": "test",
'"a': "test",
};
7 changes: 7 additions & 0 deletions tests/specs/node/cjs_key_escaped_whitespace/output.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
imported: [Module: null prototype] {
"\ty": "test",
"\nx": "test",
"\rz": "test",
'"a': "test",
default: { "\nx": "test", "\ty": "test", "\rz": "test", '"a': "test" }
}

0 comments on commit e6869d7

Please sign in to comment.