From 056d45cf6b0753b44f1e9a7a894592933f8be687 Mon Sep 17 00:00:00 2001 From: Hanaasagi Date: Wed, 15 Nov 2023 17:31:31 +0800 Subject: [PATCH] fix(install): fix the case that package scope contains tilde. (#7049) * fix(install): fix the case that package name contains tilde. Close: #7045 * add tests * emm, let me know why test failed * overwrite registry config * check more chars * remove $ --- src/string_immutable.zig | 9 ++++++++- test/cli/install/bun-install.test.ts | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/string_immutable.zig b/src/string_immutable.zig index b853561baa..63767bcfae 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -144,16 +144,23 @@ pub inline fn isNPMPackageName(target: string) bool { '@' => true, else => return false, }; + var slash_index: usize = 0; for (target[1..], 0..) |c, i| { switch (c) { // Old packages may have capital letters - 'A'...'Z', 'a'...'z', '0'...'9', '$', '-', '_', '.' => {}, + 'A'...'Z', 'a'...'z', '0'...'9', '-', '_', '.' => {}, '/' => { if (!scoped) return false; if (slash_index > 0) return false; slash_index = i + 1; }, + // issue#7045, package "@~3/svelte_mount" + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#description + // It escapes all characters except: A–Z a–z 0–9 - _ . ! ~ * ' ( ) + '!', '~', '*', '\'', '(', ')' => { + if (!scoped or slash_index > 0) return false; + }, else => return false, } } diff --git a/test/cli/install/bun-install.test.ts b/test/cli/install/bun-install.test.ts index df247c48d8..4ba7722290 100644 --- a/test/cli/install/bun-install.test.ts +++ b/test/cli/install/bun-install.test.ts @@ -7833,3 +7833,26 @@ describe("Registry URLs", () => { expect(await exited).toBe(0); }); }); + +it("should handle @scoped name that contains tilde, issue#7045", async () => { + await writeFile( + join(package_dir, "bunfig.toml"), + ` +[install] +cache = false +`, + ); + const { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "install", "@~39/empty"], + cwd: package_dir, + stdin: null, + stdout: "pipe", + stderr: "pipe", + env, + }); + expect(stderr).toBeDefined(); + expect(await new Response(stderr).text()).toContain("Saved lockfile"); + expect(stdout).toBeDefined(); + expect(await new Response(stdout).text()).toContain("installed @~39/empty@1.0.0"); + expect(await exited).toBe(0); +});