AdguardTeam / AdguardTeam/FiltersRegistry
`--include`/`--skip` Filter ID Lists Are Silently Truncated on Windows
- Lingua principale
- Adblock Filter List
- Stelle
- 358
- Fork
- 75
- Merge medio
- 23h 37m
- PR unite (30g)
- 9
Descrizione
## Summary
Running `yarn build --generate-cache --include=1,2,3 --skip=2` from PowerShell on
Windows compiles only filter 1 instead of filters 1 and 3. Unquoted commas are
converted to spaces when arguments are forwarded through the `yarn.cmd` shim, and
`parseFlags` in `scripts/build/build-config.ts` silently truncates the resulting
`"1 2 3"` value to `[1]` without any error or warning. The build finishes with
exit code 0, so the wrong result is indistinguishable from a successful build.
## Environment
- OS: Windows
- Shell: PowerShell 7.6.2 (pwsh, `PSNativeCommandArgumentPassing=Windows`) — affected
- Shell (control): Git Bash (MINGW64) — not affected
- Package manager: yarn 1.22.22
- Node.js: >= 22
- Repository: AdguardTeam/FiltersRegistry (master)
## Steps to Reproduce
1. Run `yarn build --generate-cache --include=1,2,3 --skip=2` in PowerShell.
2. Inspect the command echoed by yarn — the commas have been replaced with spaces:
```text
tsx scripts/build/build.js --generate-cache "--include=1 2 3" --skip=2
```
3. Observe the build log: only filter 1 is compiled; filters 2 and 3 are skipped:
```text
Filter 2 skipped due to '--include' option
Filter 3 skipped due to '--include' option
```
## Expected Behavior
Filters 1 and 3 are compiled (their `filter.txt` and `revision.json` are updated);
filter 2 is skipped with the message `Filter 2 skipped due to '--skip' option`.
## Actual Behavior
Only filter 1 is compiled. Filters 2 and 3 are skipped with the message
`Filter X skipped due to '--include' option`, and the process exits with code 0
and no warning.
The message for filter 2 is the key evidence: if the include list had been parsed
as `[1, 2, 3]`, filter 2 would pass the include check and be rejected by the skip
check instead, producing `due to '--skip' option`. The fact that it was rejected
by the include check proves the parsed list contained only `[1]`.
## Root Cause
Two independent layers contribute to the bug.
### Layer 1: PowerShell argument serialization for batch files (environment)
- The environment under test is PowerShell 7.6.2 with
`PSNativeCommandArgumentPassing=Windows` (legacy mode).
- When the target is a batch-file shim such as `yarn.cmd`, PowerShell
serializes the unquoted token `--include=1,2,3` into the command line as
`--include=1 2 3`, so the script receives spaces instead of commas.
- yarn itself is not at fault: the same yarn forwards the argument intact in
Git Bash, and native executables (node.exe) receive the token intact from
PowerShell. The trigger is the `.cmd` shim boundary.
- Verified behavior in PowerShell 7:
| Command | Result |
| ------- | ------ |
| `Write-Output --include=1,2,3` | three lines: `--include=1`, `2`, `3` |
| `cmd /c node -e "..." --include=1,2,3` | node receives `--include=1,2,3` (intact) |
| `yarn node -e "..." --include=1,2,3` | node receives `--include=1 2 3` (spaces) |
| `yarn node -e "..." "--include=1,2,3"` | node receives `--include=1,2,3` (quoting works) |
The issue does not reproduce in Git Bash (MINGW64) on the same machine: bash
passes the token as-is because the comma is not a special character there.
The command is echoed intact: `tsx scripts/build/build.js --generate-cache
--include=1,2,3 --skip=2`. Filters 1 and 3 are compiled, filter 2 is skipped
with `Filter 2 skipped due to '--skip' option`.
### Layer 2: `parseFlags` in `scripts/build/build-config.ts` (code)
```js
flags.includedFilterIDs = value
.split(',')
.map((x) => Number.parseInt(x, 10))
.filter((x) => !Number.isNaN(x));
```
- The value is split only on `,`, so `"1 2 3"` remains a single element.
- `Number.parseInt("1 2 3", 10)` returns `1`: it parses the leading digits and
silently ignores the rest.
- Invalid elements are silently discarded by the `Number.isNaN` filter.
- No validation exists for `--include`/`--skip` values, so malformed input never
produces an error or warning.
The same fragile pattern exists in `scripts/build/patches.js` for patch
generation; there the `NaN` elements are not even filtered out.
## Impact
- Silent wrong builds: `--generate-cache` and `build:local` runs may update
`filter.txt` and `revision.json` only for a subset of the intended filters.
- The wrong result is reported as success (exit code 0, `Done in Ns.`).
- Any PowerShell user on Windows who forgets to quote the argument gets an
incorrect cache or platform build without knowing it. Git Bash and other
POSIX shells are not affected.
## Proposed Solution
1. Extract a shared helper that parses a filter ID list separated by commas
and/or whitespace, e.g. split on `/[,\s]+/`.
2. Validate every element: a non-integer element must produce a clear error
(for example, `Invalid filter ID in --include: "abc"`) instead of being
silently dropped. Whitespace-separated values such as `1 2 3` should be
accepted as `[1, 2, 3]`, since they are a legitimate consequence of the
Windows quoting issue.
3. Apply the same parsing and validation in `scripts/build/patches.js`.
## Files to Update
- `scripts/build/build-config.ts` — parsing and validation of `--include`/`--skip`.
- `scripts/build/patches.js` — same parsing pattern for patch generation.
- `scripts/build/__tests__/build-config.test.ts` — update the test that expects
invalid IDs to be dropped (`--include=1,abc,3` -> `[1, 3]`); add tests for
whitespace-separated values and for the new error path.
- `DEVELOPMENT.md` — update the *Command Compatibility* section if the accepted
syntax changes (document that both commas and whitespace are supported).
- `README.md` — only if the documented build examples change.
## Workaround
Until the fix is merged, quote the argument in PowerShell:
```powershell
yarn build --generate-cache "--include=1,2,3" --skip=2
```
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.