From 713c1963fd0425d9362d336075909a0a35290f38 Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Sun, 24 May 2026 22:09:29 +0800 Subject: [PATCH] fix(validation): allow + in package names (e.g. logi-options+) Real Homebrew casks contain +, so the publish API was rejecting valid configs. + is not a shell metacharacter, so allowing it doesn't widen the injection surface guarded by existing tests. Fixes #101 Co-Authored-By: Claude Opus 4.7 (1M context) --- src/lib/server/validation.test.ts | 11 +++++++++++ src/lib/server/validation.ts | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/lib/server/validation.test.ts b/src/lib/server/validation.test.ts index 54bab2a..df24577 100644 --- a/src/lib/server/validation.test.ts +++ b/src/lib/server/validation.test.ts @@ -300,6 +300,17 @@ describe('validatePackages', () => { expect(result.valid).toBe(true); }); + it('should accept package names with plus character (e.g. logi-options+)', () => { + const packages = [ + { name: 'logi-options+', type: 'cask' }, + { name: 'gtk+', type: 'formula' } + ]; + const result = validatePackages(packages); + + expect(result.valid).toBe(true); + expect(result.error).toBeUndefined(); + }); + it('should reject non-array input', () => { const result = validatePackages('not an array' as any); diff --git a/src/lib/server/validation.ts b/src/lib/server/validation.ts index 1d26189..0d3d44e 100644 --- a/src/lib/server/validation.ts +++ b/src/lib/server/validation.ts @@ -139,7 +139,8 @@ interface Package { } /** Validates packages array: prevents shell injection in package names. - * Package names must match standard package manager formats (alphanumeric, hyphens, underscores, dots, slashes for scoped packages). + * Package names must match standard package manager formats (alphanumeric, hyphens, underscores, dots, pluses, slashes for scoped packages). + * `+` is allowed because real Homebrew casks contain it (e.g. `logi-options+`, `gnupg@2.1+`). * Types must be: formula, cask, tap, npm. * Maximum 500 packages per config. */ export function validatePackages(packages: unknown): ValidationResult { @@ -174,10 +175,10 @@ export function validatePackages(packages: unknown): ValidationResult { return { valid: false, error: `Package name too long at index ${i}` }; } - if (!/^[@a-zA-Z0-9._\/-]+$/.test(name)) { + if (!/^[@a-zA-Z0-9._+\/-]+$/.test(name)) { return { valid: false, - error: `Invalid package name at index ${i}: "${name}". Only alphanumeric, hyphens, underscores, dots, @ and / allowed.` + error: `Invalid package name at index ${i}: "${name}". Only alphanumeric, hyphens, underscores, dots, plus, @ and / allowed.` }; }