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.` }; }