Commit Graph
5506 Commits
Author SHA1 Message Date
Grzegorz MartensandClaude Opus 5.5 e9142b03b9 M7: a composite font's /Encoding is read through a reference
The Legal forms review of 8fb534ad4. A Type 0 font's /Encoding may be
given by reference (a name or a CMap stream, either indirect), and the
metrics read resolve it: an indirect /Identity-H reads two-byte codes.
The editor's check before reading a composite font's metrics, and
`main`'s `composite_glyph_maps` and `recovered_thai_map`, read it with
`Dict::name`, which doesn't resolve: such a font counted as another
encoding, so the editor adapted no copy of it and Repair Thai maps
passed it over. All three now read it through `identity_h`, which
resolves it as the metrics do.

Tests: `a_composite_fonts_encoding_given_by_reference_is_read` (the
editor adapts a copy of a composite subset with `/Encoding 5 0 R`, object
5 `/Identity-H`, that maps 'Ω', and its metrics read two-byte codes), and
`recovered_thai_map_checks_every_kept_glyph_against_the_font_program`
recovers the same map with the font's /Encoding by reference.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-09 16:27:49 +01:00
Grzegorz MartensandClaude Opus 5.5 8fb534ad4c M7: tests pin what a stage past its limit charges the allowance
Mutation testing of 063f8629e missed eight mutants in
`DecodeBudget::decode_stages_within`: nothing pinned what a read
stopped at a stage's limit, at the stages' total or at what is left of
the allowance charges, which limit it reports, or where one case gives
way to the next.

`a_stage_past_its_limit_charges_what_came_before_and_the_limit` reads
each way, and each boundary on both sides: a byte more room than the hex
stage and the limit (charged them, a byte left), exactly that (past the
allowance: all of it spent, its limit reported), a hex stage making
exactly the limit so the Flate stage reaches the stages' total with more
left (charged the total), with exactly the total left of a larger
allowance and with less (spent, the allowance's limit reported), and,
with nothing left, a stream with data that decodes to nothing (refused)
and an empty one (read).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-09 14:08:29 +01:00
Grzegorz MartensandClaude Opus 5.5 509cf9f9fd M7: the editor reads no metrics for a composite font it can't adapt
The Resources review of 8eead8ecd:

- `embedded_sfnt_within` read a composite font's metrics within the
  editor's allowance before `composite_glyph_maps` refused any `/Encoding`
  but Identity-H, so an Identity-V or UniJIS font spent its ToUnicode and
  `/CIDToGIDMap` for nothing. Its `/Encoding` is now checked first; a
  program with a cmap of its own is kept as it is, as when the rebuild
  finds nothing.
- The Thai edit's allowance, `MAX_THAI_PROGRAMS`, now also pays for the
  CMaps and glyph maps its subsets' metrics and codes are read from: its
  doc and its refusal say "font data", not "font programs".
- `a_symbolic_truetype_font_without_an_encoding_reads_its_glyph_names`
  also reads its font, whose `post` table names its glyphs, within an
  allowance: the program is paid for by the glyph-name reading, by the
  Mac OS Roman one and for the widths, and a byte short of the first the
  names go unread.

Tests: `a_composite_font_that_cant_be_adapted_spends_only_its_program`,
and `adapting_a_programs_cmap_is_paid_for` again expects a composite font
whose codes aren't Identity-H to pay for its program only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-09 13:36:44 +01:00
Grzegorz MartensandClaude Opus 5.5 063f8629e4 M7: each filter stage of a font's stream is held to its limit, as without an allowance
The Resources review of 8eead8ecd. The program read and the metrics reads
passed their limit times the number of filter stages as one total, which
any one stage could use: a FontFile2 of Flate making 128 MiB of
whitespace, under seven ASCIIHex stages (a 130 KB file), made all of it
before being refused, about 0.1 s a font where `main`'s bound stopped it
at 16 MiB. `edit`'s `matching_thai_outline` reads such a program for each
of a page's fonts with no total, and every `Metrics::from_dict` up to
three times.

Now each stage is held to the limit, as a decode without an allowance
holds it, and the stages together to the limit for each of them, so every
stream the stage scaling was for still reads: a full `/CIDToGIDMap` or a
12 MiB program behind ASCIIHex and Flate. The two bounds take an entry
point of their own: `pdfcraft_filters::decode_tolerant_counted_each`,
which `run` already supports, and `DecodeBudget::decode_stages_within`,
which `Reads::decode` and the editor's program read use. A stage past the
limit is charged what the stages before it decoded and the limit; past
the stages' total, or past what is left, it is charged as
`decode_within` charges. The program, the last stage, is so within the
limit without a check of its own.

Tests: `each_stage_is_held_to_its_own_bound_within_the_total` in
`pdfcraft-filters` (a Flate stage stopped at its bound hands the next
stage nothing), `each_stage_is_held_to_the_limit` in `pdfcraft-cos`, and
in `pdfcraft-fonts` `an_editors_program_read_holds_each_stage_to_its_limit`
and `each_stage_of_a_metrics_stream_is_held_to_its_limit`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-09 13:36:29 +01:00
Grzegorz MartensandClaude Opus 5.5 d4abe80671 Merge main again into fix/fonts-decode-budget
main's #3962 (symbolic TrueType glyph names, 63a6f8ace and nearby) reads a
symbolic TrueType font's codes by the `post` names of the glyphs its cmap
selects, before the Mac OS Roman reading:

- crates/fonts/src/pdf.rs, `unicode_map`: both readings stay, in main's
  order, each given the metrics read's allowance. The program read main
  added (`symbolic_glyph_texts`) goes through `Reads::decode`, as
  `symbolic_mac_roman_texts` does since the last merge: paid for from the
  allowance, `past_allowance` set when it can't be, behind several
  filters within the stream's own limit.
- crates/fonts/src/pdf/tests.rs: both sides added tests at the same place;
  all are kept.

Tests: `adapting_a_programs_cmap_is_paid_for` now expects the program to
be paid for a fourth time, and `the_symbolic_mac_roman_reading_is_paid_for`
becomes `the_symbolic_readings_of_a_program_are_paid_for`, paying for both
readings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-09 13:06:32 +01:00
BFlat b6cbf9bb30 Merge pull request #6710 from storytold/merge/forms-links-text2
Land forms, links, find and redaction-save fixes (#4496, #4532, #3567, #3773, #4470, #4474, #4497, #5658)
2026-11-09 19:45:39 +08:00
BFlat 6b56de9ecf Merge pull request #6711 from storytold/merge/render-patches2
Land renderer patches, layer auto state, auto-tag artifacts, export clips and print page lookup (#3969, #4393, #4396, #4410, #4433, #4459, #4159, #5075, #5973)
2026-11-09 19:45:24 +08:00
BFlat 9f4191336d xtask: the private temp folder builder is mutable only on Unix (#6712) 2026-11-09 19:45:13 +08:00
bflatastic e917cc2cc6 Fit the landed changes together 2026-11-09 18:24:27 +07:00
bflatastic 8183f96b37 Merge #5973: fix(print,engine): read the page tree once when finding which pages' text reads up
# Conflicts:
#	crates/print/src/tests.rs
2026-11-09 18:22:45 +07:00
bflatastic 6404602e63 Merge #5075: fix(edit): Office export respects a form's /BBox and a page's re/W/n clip
# Conflicts:
#	crates/edit/src/text/lines.rs
2026-11-09 18:22:16 +07:00
bflatastic e767b244ee Merge #5658: M5: the text selection bar stays inside the pages' area (#5577)
# Conflicts:
#	crates/ui-egui/src/canvas/selection.rs
2026-11-09 18:22:01 +07:00
bflatastic 117f3b1102 Merge #4497: M8: after Apply redactions, Save asks where and proposes the name with _Redacted (protect.redact-filename-suffix) 2026-11-09 18:21:20 +07:00
bflatastic 86c97aca30 Merge #4159: fix(a11y): mark vector graphics and images as artifacts in autotag_text (#4080)
# Conflicts:
#	crates/a11y/src/autotag.rs
2026-11-09 18:21:12 +07:00
bflatastic d8dad6f9ef Merge #4474: M3: relative links resolve against the document's base URI, and a link is active only in its QuadPoints (view.follow-links) 2026-11-09 18:20:36 +07:00
bflatastic 4494642b05 Search reads ligatures through the page text's ligature_letters 2026-11-09 18:20:36 +07:00
bflatastic 70aa8e5c0c Merge #4459: M2: the standard 14 fonts fit the Euro to its standard width (view.render-pages)
# Conflicts:
#	vendor/README.md
2026-11-09 18:19:55 +07:00
bflatastic baa131de70 Merge #4433: M2: zero-area fills and clips mark the pixels they touch (view.render-pages)
# Conflicts:
#	vendor/README.md
#	vendor/hayro-interpret/src/interpret/path.rs
2026-11-09 18:19:48 +07:00
bflatastic 93e45776f2 Merge #4470: M3: Find matches ligatures and words split by a line-end hyphen (#4469) 2026-11-09 18:19:30 +07:00
bflatastic 68abeedc57 Merge #3773: M9: empty signature fields show a Sign tab, sized to the field
# Conflicts:
#	crates/ui-egui/src/canvas/page_input.rs
2026-11-09 18:19:30 +07:00
bflatastic 06a9385543 Merge #4410: fix(render): degenerate subpaths, all-zero dash arrays and negative line widths stroke as the spec says (hayro-interpret patch 61)
# Conflicts:
#	vendor/README.md
2026-11-09 18:19:14 +07:00
bflatastic 0dda66820c Merge #4396: M2: layers open in the state the view auto state sets, and the Layers panel follows /Order (view.layers-panel)
# Conflicts:
#	crates/render/src/inspect.rs
#	crates/render/src/lib.rs
#	vendor/README.md
2026-11-09 18:19:07 +07:00
bflatastic d18a968c33 Merge #3567: M6: a drop-down shows its arrow, and its list looks and works like the form's own
# Conflicts:
#	crates/ui-egui/src/tools/forms_ui.rs
#	crates/ui-egui/tests/it/forms.rs
#	parity/acrobat-features.toml
2026-11-09 18:18:56 +07:00
bflatastic 15a264ff04 Merge #4393: M2: an Indexed image with a short lookup table or an out-of-range hival is drawn as most readers draw it, and one with no table is skipped with a warning (view.render-pages)
# Conflicts:
#	vendor/README.md
2026-11-09 18:17:39 +07:00
bflatastic de333340a5 Merge #4532: M6: list boxes show and pick the option /I names, and a single-select list shows one value (#4531)
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/forms/src/lib.rs
#	crates/forms/src/tests.rs
#	crates/forms/src/values.rs
#	crates/ui-egui/src/tools/forms_ui.rs
#	crates/ui-egui/tests/it/forms.rs
2026-11-09 18:17:35 +07:00
bflatastic 5257a6a34a Merge #3969: M10: a symbolic TrueType font without an encoding reads its glyph names (#3962)
# Conflicts:
#	vendor/README.md
2026-11-09 18:17:22 +07:00
bflatastic c38db36ae4 Merge #4496: M6: a check box's kids with different on states tick one at a time (form.fill-checkbox-radio) 2026-11-09 18:14:35 +07:00
BFlat 9ee213eff7 Fix main's build and tests after the latest merges (#6706) 2026-11-09 19:12:07 +08:00
mtlcl410 cf7734b17e Merge upstream/main into fix/standard14-euro-width 2026-11-09 19:07:08 +08:00
mtlcl410 5ac623ff9f Merge upstream/main into fix/zero-area-fill-and-clip 2026-11-09 19:05:11 +08:00
mtlcl410 299e263bf9 Merge upstream/main into fix/stroke-degenerate-and-dash 2026-11-09 19:02:50 +08:00
Grzegorz MartensandClaude Opus 5.5 8eead8ecdd Merge main: the font reads main added are paid for from the allowance too
main's Thai work (#6249, #3492) and the Type 3 and symbolic TrueType
metrics changed the code this PR bounds. Each conflict, and each read main
added that this PR's allowance must cover:

- crates/fonts/src/pdf.rs, the editor's program read: this PR's read is
  kept, its stage-scaled limit and its check for an allowance already
  spent; main's read had /DecodeParms by reference too, which it has.
- The editor's loop: main rebuilds a cmap for a composite subset without
  one from its ToUnicode and /CIDToGIDMap, where this PR skipped Type 0.
  main's composite support stays, with the metrics read within the
  editor's allowance (`from_dict_within`) and no copy adapted from metrics
  read past it, as for a simple font. The /CIDToGIDMap the cmap is rebuilt
  from (`composite_glyph_maps`) reads as the font's other streams do
  (`Reads::decode`): within the allowance, behind several filters too.
- Reads main added to the metrics read: a Type 3 font's glyph
  descriptions (`type3_glyph_box`), and the program read that tells a
  symbolic TrueType font's codes as Mac OS Roman
  (`symbolic_mac_roman_texts`). Both are now paid for from the allowance
  the metrics are read within, and a refusal sets `past_allowance`. The
  glyph descriptions keep their own limits (64 KiB each, 4 MiB a font).
- Constants and helpers both sides added beside one another, and the
  tests both appended, are all kept. Callers main added of
  `unicode_map` pass a reading without a total, as `from_dict` does.
- crates/edit/src/rules.rs: the refusal of a page whose content didn't
  all decode stays, and the operators come from main's `text::joined`.

Tests: `adapting_a_programs_cmap_is_paid_for` now expects a composite
font's ToUnicode, and a simple font's program read again for the Mac OS
Roman reading, to be paid for. Four are new:
`adapting_a_composite_subsets_cmap_is_paid_for`,
`a_full_cid_map_rebuilds_a_composite_subsets_cmap_behind_two_filters`,
`type3_glyph_boxes_are_paid_for_from_the_allowance` and
`the_symbolic_mac_roman_reading_is_paid_for`. The fixture of main's test
of a composite subset without a cmap moves into `cmapless_composite`,
which both use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
2026-11-09 12:00:17 +01:00
mtlcl410 ad0fab3339 Merge remote-tracking branch 'upstream/main' into lane4-4474b
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/automation/tests/it/automation.rs
#	crates/ui-egui/tests/it/document_links.rs
2026-11-09 18:52:46 +08:00
mtlcl410 ad42d5c276 Merge upstream/main into fix/indexed-short-lookup 2026-11-09 18:48:21 +08:00
mtlcl410 60de09e1a5 Merge remote-tracking branch 'upstream/main' into lane4-4470b
# Conflicts:
#	crates/render/src/text/search.rs
#	crates/render/tests/it/search.rs
2026-11-09 18:43:43 +08:00
mtlcl410 7096266c48 M6: give the custom-validation test's ScriptResult its value_set field 2026-11-09 18:41:47 +08:00
Dylan M. Taylor dafb3be3de fix(xfa): one decoding allowance for all XFA packets (#6000) 2026-11-09 18:38:52 +08:00
Dylan M. Taylor b4679deafd fix(cli): cap input reads, budget check's edit pass and escape its stderr records (#5997) 2026-11-09 18:38:34 +08:00
Dylan M. Taylor ba47f7bbc5 fix(cli): render needs the copying permission, as text does (#5990) 2026-11-09 18:38:17 +08:00
Dylan M. Taylor f800c12a7e fix(xtask): render-oracle writes page pixels into a private temporary folder (#5988) 2026-11-09 18:38:01 +08:00
Dylan M. Taylor 4cdc3d15dd fix(redact): read the page tree once per sanitize pass, not per page (#5983) 2026-11-09 18:37:46 +08:00
Dylan M. Taylor 8f29ed66f9 fix(engine): open linked documents without blocking and check the handle is a regular file (#5982) 2026-11-09 18:37:30 +08:00
Dylan M. Taylor 3fe86a118e fix(print,a11y): read summary scans one operator at a time and borrow form resources (#5968) 2026-11-09 18:37:07 +08:00
Dylan M. Taylor 0d4074755d fix(automation): sign_trust deduplicates certificates with a set (#5965) 2026-11-09 18:36:50 +08:00
Dylan M. Taylor ca56433f5f fix(redact): read text-state operands from the end, as the renderer does (#5951) 2026-11-09 18:36:34 +08:00
Dylan M. Taylor 44a26f4b93 fix(model,oracle): read a page box only when it has four entries; skip empty images (#5941) 2026-11-09 18:36:19 +08:00
Dylan M. Taylor 743a772ee9 fix(content): an inline image only the renderer reads counts as ambiguous (#5874) 2026-11-09 18:36:04 +08:00
.CooCoo e78102c907 M11: PDF Optimizer can discard form submission, import and reset actions (optimize.discard-form-actions) (#4416) 2026-11-09 18:35:01 +08:00
Livio Oswald ba2846cba8 M4: a recovered document's first Save asks where instead of writing the sidecar's path (#3923) (#4327) 2026-11-09 18:33:33 +08:00
mtlcl410 5588db4b62 M10: (n) names the page at position n, whatever its label, in page ranges and the page box (print.page-range) (#4282) 2026-11-09 18:33:17 +08:00