diff --git a/cli/tests/integration/npm_tests.rs b/cli/tests/integration/npm_tests.rs index 884f2a3a95..6e35456bf4 100644 --- a/cli/tests/integration/npm_tests.rs +++ b/cli/tests/integration/npm_tests.rs @@ -81,6 +81,13 @@ itest!(cjs_this_in_exports { exit_code: 1, }); +itest!(cjs_invalid_name_exports { + args: "run --allow-read --quiet npm/cjs-invalid-name-exports/main.ts", + output: "npm/cjs-invalid-name-exports/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + itest!(translate_cjs_to_esm { args: "run -A --quiet npm/translate_cjs_to_esm/main.js", output: "npm/translate_cjs_to_esm/main.out", diff --git a/cli/tests/testdata/npm/cjs-invalid-name-exports/main.out b/cli/tests/testdata/npm/cjs-invalid-name-exports/main.out new file mode 100644 index 0000000000..45ec15d0e2 --- /dev/null +++ b/cli/tests/testdata/npm/cjs-invalid-name-exports/main.out @@ -0,0 +1,13 @@ +[Module: null prototype] { + "a \\ b": "a \\ b", + "another 'case'": "example", + default: { + 'wow "double quotes"': "double quotes", + "another 'case'": "example", + "a \\ b": "a \\ b", + "name variable": "a", + "foo - bar": "foo - bar" + }, + "foo - bar": "foo - bar", + 'wow "double quotes"': "double quotes" +} diff --git a/cli/tests/testdata/npm/cjs-invalid-name-exports/main.ts b/cli/tests/testdata/npm/cjs-invalid-name-exports/main.ts new file mode 100644 index 0000000000..9bdf0e43b3 --- /dev/null +++ b/cli/tests/testdata/npm/cjs-invalid-name-exports/main.ts @@ -0,0 +1,3 @@ +import * as foo from "npm:@denotest/cjs-invalid-name-exports"; + +console.log(foo); diff --git a/cli/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js b/cli/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js new file mode 100644 index 0000000000..75c3f2e8ad --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js @@ -0,0 +1,6 @@ +exports['wow "double quotes"'] = "double quotes" +exports["another 'case'"] = 'example' +exports["a \\ b"] = 'a \\ b' +const a = 'name variable' +exports[a] = "a"; +exports['foo - bar'] = 'foo - bar' diff --git a/cli/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json b/cli/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json new file mode 100644 index 0000000000..fd715eeae8 --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/cjs-invalid-name-exports", + "version": "1.0.0" +} diff --git a/ext/node/analyze.rs b/ext/node/analyze.rs index 7d98f53dbb..eed0ceb4fe 100644 --- a/ext/node/analyze.rs +++ b/ext/node/analyze.rs @@ -202,7 +202,7 @@ impl add_export( &mut source, export, - &format!("mod[\"{export}\"]"), + &format!("mod[\"{}\"]", escape_for_double_quote_string(export)), &mut temp_var_count, ); } @@ -460,7 +460,8 @@ fn add_export( "const __deno_export_{temp_var_count}__ = {initializer};" )); source.push(format!( - "export {{ __deno_export_{temp_var_count}__ as \"{name}\" }};" + "export {{ __deno_export_{temp_var_count}__ as \"{}\" }};", + escape_for_double_quote_string(name) )); } else { source.push(format!("export const {name} = {initializer};")); @@ -518,6 +519,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) -> String { + text.replace('\\', "\\\\").replace('"', "\\\"") +} #[cfg(test)] mod tests { use super::*;