Split by comma but not inside double-quoted strings, respecting RFC 9110 * §5.6.4 quoted-pairs. Needed for `no-cache` and `private` whose * quoted-string arguments may contain commas; quoted-pair sequences (e.g. * `\"` or `\,`) inside a quoted-string must not toggle the quote state or * trigger
(value: string)
| 180 | * `\"` or `\,`) inside a quoted-string must not toggle the quote state or |
| 181 | * trigger a split. */ |
| 182 | function splitDirectives(value: string): string[] { |
| 183 | // Fast path: no quotes means a simple split is safe. |
| 184 | if (!value.includes('"')) return value.split(","); |
| 185 | |
| 186 | const parts: string[] = []; |
| 187 | let start = 0; |
| 188 | let inQuotes = false; |
| 189 | for (let i = 0; i < value.length; i++) { |
| 190 | const c = value.charCodeAt(i); |
| 191 | if (c === 92 /* \ */ && inQuotes) { |
| 192 | // Quoted-pair (RFC 9110 §5.6.4): skip the escaped byte so a `\"` is |
| 193 | // not seen as a closing quote and a `\,` is not seen as a separator. |
| 194 | i++; |
| 195 | } else if (c === 34 /* " */) { |
| 196 | inQuotes = !inQuotes; |
| 197 | } else if (c === 44 /* , */ && !inQuotes) { |
| 198 | parts.push(value.slice(start, i)); |
| 199 | start = i + 1; |
| 200 | } |
| 201 | } |
| 202 | parts.push(value.slice(start)); |
| 203 | return parts; |
| 204 | } |
| 205 | |
| 206 | /** Parse a comma-separated list of HTTP field names from a directive argument. |
| 207 | * Strips surrounding double quotes if present and unescapes any quoted-pair |
no test coverage detected