Treat repeated stitching Bounds as the empty subdomain they describe - #9
Merged
Merged
Conversation
A real PDF declares Bounds [0.14286, 0.14286] over Domain [0, 1] and failed to render as unordered. The bounds are not out of order: they are equal, which describes an empty subdomain. An empty subdomain can never be selected. Segment selection takes the first bound strictly greater than the input, so an input below the plateau lands before it and an input at or above it falls through to the last segment. The subfunction between two equal bounds is unreachable by construction, which is also why the degenerate interval cannot divide by zero. Rejecting the function discarded a whole page over a subfunction that would never run. Only a decreasing bound is disorder now. The ISO exception letting the last bound equal Domain[1] is untouched, and the multi-segment empty-domain guard still fires first, so the domain [1, 1] case keeps rejecting through that guard. The validation and the selection exist twice, once in the parser and once in the renderer-owned evaluator; fixing only the first moved the error message from one to the other, so both are updated. The evaluator case joins the existing parity table, so the two are asserted to agree. In both new cases the unreachable segment is the one whose outputs start at 10, so selecting it by mistake could not pass unnoticed. Refs soadzoor#2 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Owner
|
Looks good to me, thank you! |
soadzoor
added a commit
that referenced
this pull request
Sep 17, 2026
- 0.1.30 - Fix: use native ESM paths in Vite config - Prefer usable PDF output with bounded raster fallback and approximation warnings - Strengthen CFF BaseFontBlend regression coverage - Merge pull request #10 from sebgoubier/fix/cff-basefontblend-is-not-mm - Clarify stitching bounds tolerance and expand regression tests - Merge pull request #9 from sebgoubier/fix/stitching-bounds-plateau - Feat(pdf): Add support for ICC color profiles (qcms, lcms, and alternate) with fallback - Fix(pdf): recover Flate EOL padding without losing decoded output - Feat(pdf): synthesize cloudy borders for Square annotations - Feat(pdf): support underline borders on Square annotations - Feat(pdf): synthesize Square annotations with validated geometry - Test: reject invalid CIDSystemInfo strings - Merge pull request #5 from sebgoubier/fix/cid-system-info-nul-padding - Fix(tests): handle file URLs correctly on Windows - Merge pull request #4 from sebgoubier/fix/ccitt-b1-strictly-right-of-a0 - Stop rejecting BaseFontBlend as a Multiple Master CFF font - Treat repeated stitching Bounds as the empty subdomain they describe - Trim fixed-width NUL padding in /CIDSystemInfo strings - Fix CCITT b1 selection so vertical modes cannot move backwards Source-Revision: 5d761c9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
A real PDF fails to render with
A stitching PDF function has unordered Bounds.Probed at the failure point:The bounds are not out of order. They are equal, which describes an empty subdomain — and an empty subdomain can never be selected.
evaluateStitchingpicks the segment withbounds.findIndex(bound => input < bound). For equal boundsB:input < B→ segment before the plateauinput >= B→findIndexreturns -1 → the last segmentThe segment between the two equal bounds is unreachable by construction, and its subfunction is never evaluated. Rejecting the function discards the whole page over a subfunction that would never run. There is also no division-by-zero risk in the degenerate interval, precisely because it is never selected.
So the check now rejects only a decreasing bound, which is genuine disorder. Everything else is untouched: the last bound may still equal
Domain[1]under the existing ISO exception, and the multi-segment empty-domain guard above still fires first — thedomain: [1, 1]case intestStitchingFunctionsstill rejects, through that guard.Both evaluators
The same validation and the same selection logic exist twice:
nativeFunctions.tsfor the parser andheprFunctionEvaluator.tsfor the renderer-owned store. The first fix only moved the error message from one to the other, so both are updated together.The new case in
test-hepr-function-evaluator.mjsgoes through the existing parity table, so the two evaluators are asserted to agree on it. In both new cases the unreachable segment ishigh, whose outputs start at 10 — selecting it by mistake would be unmistakable rather than subtle.Checks
test-native-function-semantics.mjs,test-hepr-function-evaluator.mjs— passnpm test—tsc --noEmitclean, 36 / 37 fast files passnpm run test:integration— 41 / 41npm run test:unit— 66 / 68The two failing files (
test-text-lod-core.mjs,test-room-segment-extractor.mjs) also fail onmain; Windows-only path failures.Scope
Stitching bounds only. Independent of #4 through #8.
Refs #2