test: pin the sanitizer allowlist and resource-policy boundaries #49

Merged
james.maes merged 5 commits from test/pin-untrusted-input-boundaries into main 2026-11-11 00:32:29 +00:00
5 Commits
Author SHA1 Message Date
james.maesandClaude Fable 5.2 7d3cf921ce fix(themes): leave room for a kept theme to grow when rewritten
node / node (push) Successful in 12s
build / scripts (push) Successful in 12s
windows / windows (push) Successful in 2m23s
build / windows (push) Successful in 2m23s
JSON writes emoji, no-break spaces and private-use glyphs as
six-character escapes, so renaming a theme made of them could push it
past the import limit and be refused. The import limit still bounds
the file read; a kept theme now has its own, larger limit, so a theme
that could be imported can always be renamed, copied and edited.

Refs #48

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 18:27:41 -06:00
james.maesandClaude Fable 5.2 2fff66cf76 fix(themes): keep renamed themes within the size limit
node / node (push) Successful in 29s
build / scripts (push) Successful in 29s
windows / windows (push) Successful in 2m19s
build / windows (push) Successful in 2m19s
Renaming, copying and editing a theme wrote every quote mark, angle
bracket and non-ASCII character as a six-character escape, so a theme
well inside the size limit could grow past it and be refused. Those
operations now write characters as themselves.

Theme text that is not well-formed UTF-16 is refused as an invalid
theme. Tests pin that property names differing only in case, the same
name in two objects, an escaped spelling of a repeated name and an
undecodable string directly inside an array are each handled as
intended.

Refs #48

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 18:14:55 -06:00
james.maesandClaude Fable 5.2 419de2c263 fix(themes): reject a theme with undecodable text or a repeated property anywhere
node / node (push) Successful in 13s
build / scripts (push) Successful in 13s
windows / windows (push) Successful in 2m1s
build / windows (push) Successful in 2m1s
A theme is validated for the strings this version reads, but it is kept,
renamed, edited and re-serialized as a whole document. An unpaired
surrogate escape in a property name or in a value this version ignores,
or a property name that appears twice, was accepted and then threw
InvalidOperationException or ArgumentException from import, rename, copy,
edit and saved-theme repair, none of which handle those.

ReaderTheme now walks the document once and reports either case as
invalid theme JSON, the failure every caller already handles.

Also pin the code-language class length limit and that the source
attribute is allowed only during a source-aware render.

Refs #48

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 17:44:14 -06:00
james.maesandClaude Fable 5.2 6ca8284f1b test: compare the configured allowlists as sets and reject undecodable theme text
node / node (push) Successful in 14s
build / scripts (push) Successful in 13s
windows / windows (push) Successful in 1m52s
build / windows (push) Successful in 1m52s
The element pin missed elements it did not list and five it listed in a
context where the parser never creates them. The sanitizer's configured
elements, attributes and schemes, and the resource policy's file types,
are now compared with independent lists as sets, so any change to them
has to be made in the test as well. Table-only elements are tested inside
a table.

A theme string holding an unpaired surrogate escape made the JSON reader
throw InvalidOperationException, which import and saved-theme repair do
not handle. ReaderTheme now reports it as invalid theme JSON like every
other malformed value.

Also pin the styling-class filter, the exact path prefix and document
comparison, the reserved-name rule's negatives and the export-name
trimming; describe the reserved-name rule as the legacy Win32 rule applied
on every Windows version; and run the device spellings as two tests
instead of 960 theory rows.

Refs #48

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 17:18:59 -06:00
james.maesandClaude Fable 5.2 8770f075ea test: pin the sanitizer allowlist and resource-policy boundaries
node / node (push) Successful in 17s
build / scripts (push) Successful in 17s
windows / windows (push) Successful in 1m50s
build / windows (push) Successful in 1m50s
Widening the sanitizer's element, attribute or scheme allowlist left every
test green, and resource-policy tests rejected their inputs for unrelated
reasons, so removing a single check went unnoticed.

Add an independent exact pin for each allowlist, single-component
variations for origin, file type and forbidden characters, and killing
tests for theme colours and labels, metadata escaping, per-property
settings repair, schema approval and exact size limits. The fuzz corpus
now generates the media, form and metadata elements its oracle forbids.

Reserved Windows device names and forbidden characters become one
written-out rule, WindowsFileNames, used by the resource policy and the
theme export name. It covers every device name in any letter case, with
any extension and with spaces before the extension, plus COM0, LPT0,
CONIN$ and CONOUT$, and a double quote is refused like the other
forbidden characters.

Closes #48

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-10 16:49:09 -06:00