From 0733943fe7de30fa54d6cd8ee34f7393e8bb7482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 15 Jun 2023 20:36:33 +0200 Subject: [PATCH] fix(cli): avoid crash on import of invalid module names (#19523) Fixes https://github.com/denoland/deno/issues/17748 Closes #17770 Co-authored-by: Anton Bershanskiy Co-authored-by: David Sherret --- cli/npm/registry.rs | 18 +++++++++++++++++- cli/tests/integration/npm_tests.rs | 7 +++++++ .../main.out | 6 ++++++ .../main.ts | 6 ++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.out create mode 100644 cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts diff --git a/cli/npm/registry.rs b/cli/npm/registry.rs index 40d7f62191..eb0a2068af 100644 --- a/cli/npm/registry.rs +++ b/cli/npm/registry.rs @@ -363,7 +363,23 @@ impl CliNpmRegistryApiInner { } fn get_package_url(&self, name: &str) -> Url { - self.base_url.join(name).unwrap() + // list of all characters used in npm packages: + // !, ', (, ), *, -, ., /, [0-9], @, [A-Za-z], _, ~ + const ASCII_SET: percent_encoding::AsciiSet = + percent_encoding::NON_ALPHANUMERIC + .remove(b'!') + .remove(b'\'') + .remove(b'(') + .remove(b')') + .remove(b'*') + .remove(b'-') + .remove(b'.') + .remove(b'/') + .remove(b'@') + .remove(b'_') + .remove(b'~'); + let name = percent_encoding::utf8_percent_encode(name, &ASCII_SET); + self.base_url.join(&name.to_string()).unwrap() } fn get_package_file_cache_path(&self, name: &str) -> PathBuf { diff --git a/cli/tests/integration/npm_tests.rs b/cli/tests/integration/npm_tests.rs index c38e4f75fd..014f22658b 100644 --- a/cli/tests/integration/npm_tests.rs +++ b/cli/tests/integration/npm_tests.rs @@ -183,6 +183,13 @@ itest!(dynamic_import_reload_same_package { http_server: true, }); +itest!(dynamic_import_invalid_package_name { + args: "run -A --reload npm/dynamic_import_invalid_package_name/main.ts", + output: "npm/dynamic_import_invalid_package_name/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + itest!(env_var_re_export_dev { args: "run --allow-read --allow-env --quiet npm/env_var_re_export/main.js", output_str: Some("dev\n"), diff --git a/cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.out b/cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.out new file mode 100644 index 0000000000..0e9de5f258 --- /dev/null +++ b/cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/npm/registry/ws%3A +FAILED +TypeError: npm package 'ws:' does not exist. + at async file:///[WILDCARD]/dynamic_import_invalid_package_name/main.ts:2:3 { + code: "ERR_MODULE_NOT_FOUND" +} diff --git a/cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts b/cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts new file mode 100644 index 0000000000..368ccc282e --- /dev/null +++ b/cli/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts @@ -0,0 +1,6 @@ +try { + await import(`npm:${"ws:"}`); +} catch (err) { + console.log("FAILED"); + console.log(err); +}