fix: find install scripts for package names with regex metacharacters

findInstallScript built a regex from the raw package name, so names like
g++ or libstdc++6 threw "Nothing to repeat" on cache save and on restore
with install scripts, and a '.' in a name could match another package's
script. Compare file names as plain strings instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
awalsh128 2026-11-08 15:17:32 -08:00
parent 9ff16f8ab9
commit e4f2f46b93
2 changed files with 39 additions and 2 deletions

View file

@ -66,10 +66,15 @@ export async function findInstallScript(
return undefined;
}
const pattern = new RegExp(`^${packageName.name}(:.*)?\\.${extension}$`);
// Match on plain strings since package names can hold regex metacharacters
// (e.g. g++, libstdc++6). Scripts are named <name>[:<arch>].<extension>.
const suffix = `.${extension}`;
const isMatch = (entry: string) =>
entry === `${packageName.name}${suffix}` ||
(entry.startsWith(`${packageName.name}:`) && entry.endsWith(suffix));
const matches = fs
.readdirSync(scriptsDir)
.filter((entry) => pattern.test(entry))
.filter(isMatch)
.sort((a, b) => a.localeCompare(b));
const candidate = matches[0];
if (!candidate) {

View file

@ -98,6 +98,38 @@ describe("packages", () => {
expect(result).toBe(path.join(scriptsDir, "test-package.preinst"));
});
it.each([
["g++", "g++.postinst"],
["libstdc++6", "libstdc++6:amd64.postinst"],
])(
"findInstallScript name %s with regex metacharacters returns its script",
async (name, scriptFilename) => {
const root = makeTempRoot("pkg-metachar-");
const scriptsDir = ensureScriptsDir(root);
fs.writeFileSync(path.join(scriptsDir, scriptFilename), "", "utf8");
const result = await findInstallScript(
createPackageName(name),
"postinst",
root,
);
expect(result).toBe(path.join(scriptsDir, scriptFilename));
},
);
it("findInstallScript name with dot does not match a similarly named package", async () => {
const root = makeTempRoot("pkg-dot-");
const scriptsDir = ensureScriptsDir(root);
fs.writeFileSync(path.join(scriptsDir, "libaXb.postinst"), "", "utf8");
const result = await findInstallScript(
createPackageName("liba.b"),
"postinst",
root,
);
expect(result).toBeUndefined();
});
it("updateAptLists calls the package manager's update method", async () => {
const aptListsPath = makeTempRoot("apt-lists-");