* Length cap + trim + dedupe + sort. `applyCharFilter` — skip for trusted * bundle IDs (Apple/Google/MS; a localized "Réglages Système" with unusual * punctuation shouldn't be dropped), apply for anything attacker-installable.
( raw: readonly string[], applyCharFilter: boolean, )
| 130 | * punctuation shouldn't be dropped), apply for anything attacker-installable. |
| 131 | */ |
| 132 | function sanitizeCore( |
| 133 | raw: readonly string[], |
| 134 | applyCharFilter: boolean, |
| 135 | ): string[] { |
| 136 | const seen = new Set<string>() |
| 137 | return raw |
| 138 | .map(name => name.trim()) |
| 139 | .filter(trimmed => { |
| 140 | if (!trimmed) return false |
| 141 | if (trimmed.length > APP_NAME_MAX_LEN) return false |
| 142 | if (applyCharFilter && !APP_NAME_ALLOWED.test(trimmed)) return false |
| 143 | if (seen.has(trimmed)) return false |
| 144 | seen.add(trimmed) |
| 145 | return true |
| 146 | }) |
| 147 | .sort((a, b) => a.localeCompare(b)) |
| 148 | } |
| 149 | |
| 150 | function sanitizeAppNames(raw: readonly string[]): string[] { |
| 151 | const filtered = sanitizeCore(raw, true) |
no test coverage detected