Skip to content

Take zip 9.2, quick-xml 0.42 and png 0.18 - #63

Merged
M3gA-Mind merged 6 commits into
tinyhumansai:mainfrom
M3gA-Mind:deps/batch-2026-11
Nov 11, 2026
Merged

M3gA-Mind merged 6 commits into
tinyhumansai:mainfrom
M3gA-Mind:deps/batch-2026-11

Conversation

@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Supersedes #58, #29 and #28 (dependabot). They share Cargo.lock sections, so merging them one by one leaves a lock cargo refuses (--locked). This PR is one branch with one consistent lock. Commits:

  1. zip 9.2 + tokio 1.54 (deps: bump the cargo-minor-and-patch group across 1 directory with 2 updates #58), testing the footer property directly. zip 9.2 no longer rejects the method-99 central record that payload_footer_cannot_be_retried_when_primary_directory_is_invalid relied on; extraction now returns the outer document's text. The nested archive held only nested.xml, which DOCX never reads, so the test asserted zip's strictness, not the property. The nested archive is now a readable DOCX with its own text, and the test asserts that text never comes out, whether or not the record is refused.
    • Decision: the corrupt record need not fail closed. It belongs to a member DOCX never reads, and admission already fixes the directory the reader may use.
    • Known limit, worth a follow-up: with the payload-footer mask switched off (Cell::new(false) in open_admitted_zip), this test still passes, on main (zip 9.0.5) as well as here. So neither the old test nor the new one exercises the mask; zip never falls back to an earlier footer for this archive. A test that does needs a primary directory that preflight admits but zip rejects.
  2. quick-xml 0.42 (deps: bump quick-xml from 0.41.0 to 0.42.0 #29). quick-xml 0.42 stores names, text and attribute values as str and removes decode(). The port compares names as str, reads text and references through their str deref, and uses normalized_value without a decoder. decode() did no EOL normalization, and neither does the deref, so the output is unchanged.
  3. png 0.18 (deps: bump png from 0.17.16 to 0.18.1 #28). output_buffer_size() is now Option<usize>, and the 80x120 fixture unwraps it. Test-only.
  4. rustfmt. Without hayro, the cherry-picked lock is already consistent.

Public API: none.

Not included: hayro 0.6 (#27). Its vello 0.0.7 dependency needs rustc 1.92, above this crate's MSRV of 1.88 (cargo +1.88 check fails). The port is ready on its own branch, but it waits on a decision to raise the MSRV.

Validation, on our Linux CI runner, on 3ff26dd (main 835854e):

  • cargo fmt --all -- --check: clean.
  • cargo clippy --locked --all-targets --all-features -- -D warnings: clean.
  • cargo test --locked --all-features: 224 passed, 0 failed.
  • cargo +1.88 check --locked --all-targets --all-features (MSRV): passes.
  • The lock is already consistent (cargo metadata leaves no diff).
  • Merged with the markdown::convert skips the ZIP admission checks that intake::extract enforces #61 PR: 227 passed, clippy and MSRV clean.
  • Per-commit earlier runs: quick-xml intake 38/38 and markdown 24/24; zip 9.2's rewritten test also passes on zip 9.0.5.

Branch: M3gA-Mind/tinydocs deps/batch-2026-11 @ 3ff26dd (pushed).

zip 9.2 no longer rejects the method-99 central record the admission
test relied on, so extraction now succeeds with the outer document's
text. The test asserted zip's old strictness, not the property it names:
its nested archive held only nested.xml, which DOCX never reads.

Make the nested archive a readable DOCX with its own text, and assert
that text never comes out, whether or not the corrupt record is
refused.

Supersedes tinyhumansai#58 (lockfile from dependabot's update).
quick-xml 0.42 stores names, text and attribute values as str and drops
decode(). Compare names as str, read text and references through their
str deref, and normalize attribute values without a decoder. decode()
did no EOL normalization, and neither does the deref, so the extracted
text is unchanged.

Supersedes tinyhumansai#29.
png 0.18 returns output_buffer_size() as an Option, None only when the
size overflows usize. The test fixture is 80x120, so unwrap it.

Supersedes tinyhumansai#28.
@coderabbitai

coderabbitai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f56660dc-172b-4f69-8c16-3b7c38297193
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@tinysweeper

tinysweeper Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Reviewed head: 9c96cb2d81807668f93bc83ddad920f67f0b36b8

Verdict: Ready for maintainer review · Priority: none
Coverage: Reviewed 6 of 7 files; not reviewed: Cargo.lock.
Pull request purpose (title): Take zip 9.2, quick-…

Diagnostics and supporting details

Full summary

Pull request purpose (title): Take zip 9.2, quick-xml 0.42 and png 0.18. Purpose (from the pull-request title): take zip 9.2, quick-xml 0.42 and png 0.18. The PR folds three Dependabot updates (#58, #29, #28) that share Cargo.lock sections into one branch with a single consistent lock, since merging them one at a time would leave a lock that `cargo --locked` refuses. Behaviorally, the streaming OOXML intake and the Markdown-side OOXML reader are ported to quick-xml 0.42 (names compared as `&str`, text/CDATA/references read through the `str` deref, `decode()` removed, attribute values via `normalized_value` without a reader decoder); the zip admission test is reworked so its nested archive is itself a readable DOCX and the test now requires the outer document to be extracted; and a test-only png 0.18 `Option<usize>` unwrap lands in the PDF render fixture. Intake limits, DTD rejection and admission behavior are preserved, no public API changes, and hayro 0.6 is held back to keep the 1.88 MSRV.

Unreviewed paths

  • Cargo.lock

Review snapshot

Change surface Files Review signal Count
Production 3 Active findings 0
Tests 2 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 1 Pending checks/questions 0

Completeness: Complete
Test assessment: Test coverage is assessed from changed tests and lane evidence; execution is not claimed without trusted check data.

Features

  • Modified — quick-xml 0.42 port of the bounded OOXML intake stream: The intake reader keeps its nesting limits, phonetic (`rPh`) suppression, `br`/`cr`/`tab` handling, shared-string resolution and DTD rejection while reading names as `&str` and text/references through their `str` deref instead of `decode()`, so no attacker-controlled DOM is built and the extracted text is unchanged. (src/intake/mod.rs fn xml_events(xml: &[u8], mut consume: impl FnMut(&str, Option<&str>) -> Result<, src/intake/mod.rs fn xml_text(xml: &[u8], shared: &[String], limit: usize) -> Result<TextSink> {)
  • Modified — Package-relationship manifest scan adapted to str names and normalized attribute values: Element names and attribute keys are borrowed directly from quick-xml's `str`-backed names rather than re-validated from UTF-8 bytes, and attribute values are normalized with `XmlVersion::Implicit1_0` without passing a decoder; the existing 256-byte name, 128-deep nesting and metadata caps are applied unchanged. (src/intake/office_order.rs fn elements()
  • Modified — Markdown-side OOXML text extraction under quick-xml 0.42: Paragraph and text tags are matched as `&str`, character references still resolve, and predefined entities such as `&amp;` are still resolved from the reference itself, so "Q&A" does not collapse to "QA". (src/markdown/ooxml.rs fn xml_text(xml: &str, paragraph_tag: &str, text_tag: &str) -> String {)
  • Modified — Zip admission test reworked for zip 9.2 footer behavior: The embedded archive now contains `word/document.xml` with its own text, so a fallback to an earlier footer would surface readable content rather than merely erroring; the test requires `extract_docx` to succeed, asserts exactly one section, and asserts the outer document's text "visible", so a fallback to the nested archive's "unchecked" text would fail. The author's stated decision is that the corrupt method-99 record need not fail closed because it belongs to a member DOCX never reads, and notes the payload-footer mask is not actually exercised by this test. (src/intake/zip_admission_tests.rs fn payload_footer_cannot_be_retried_when_primary_directory_is_invalid() {)
  • Modified — Dependency consolidation for reproducible --locked builds: One branch carries a single consistent lock for zip 9.2, tokio 1.54, quick-xml 0.42 and png 0.18 instead of three merges that would leave a lock cargo refuses, and hayro 0.6 is held back to keep the 1.88 MSRV. (Cargo.toml, src/intake/mod.rs fn xml_text(xml: &[u8], shared: &[String], limit: usize) -> Result<TextSink> {)

Tests

  • modified test — `renders_only_requested_pages_in_order_with_png_dimensions` unwraps the now-`Option<usize>` png 0.18 `output_buffer_size()` before decoding the rendered page buffer.: A mechanical, test-only adaptation of the fixture decoder to the new png signature. (src/pdf_render/mod_tests.rs fn renders_only_requested_pages_in_order_with_png_dimensions() {)

Findings

No active actionable findings.

Before merge

None.

How this fits together

flowchart LR
  n0["xml_events<br/>changed"]:::changed
  n1["xml_text<br/>changed"]:::changed
  n2["elements<br/>changed"]:::changed
  n3["...data_and_zip64_extensions_have_fixed_caps<br/>changed"]:::changed
  n4["...retried_when_primary_directory_is_invalid<br/>changed"]:::changed
  n5["extraction_failed"]:::impacted
  n6["number"]:::impacted
  n7["docx"]:::impacted
  n8["...before_the_zip_index_can_deduplicate_them"]:::impacted
  n9["extract_office"]:::impacted
  n10["ordered_parts"]:::impacted
  n0 -->|calls| n5
  n1 -->|calls| n5
  n3 -->|calls| n7
  n3 -->|tests| n7
  n4 -->|calls| n6
  n4 -->|tests| n6
  n8 -->|calls| n6
  n8 -->|tests| n6
  n9 -->|calls| n1
  n10 -->|calls| n2
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Both files are changed only by substituting quick-xml's byte-slice event API (LocalName/QName comparisons, BytesText/BytesRef decode calls) with the equivalent &str-based forms; every hunk is a one-for-one replacement with no change to control flow, ordering, budgets, or error handling, and the entity-reference behaviour that the removed `decode()` calls covered is still handled by the `Event::GeneralRef` arms that the existing tests exercise. I found no defect to report.

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: This is a mechanical quick-xml API migration: byte-slice comparisons are replaced with `&str` comparisons, `Event::Text`/`CData` payloads are used directly instead of `.decode()`, and `GeneralRef` names are passed straight to `decode_reference`/`resolve_predefined_entity`. Entity, character-reference, CDATA and truncation handling are preserved, no new sink, subprocess, network, path or authorisation surface is introduced, and no caller-visible behaviour changes. I could not read the vendored quick-xml 0.42 source (the submodule is not checked out), so the `AsRef<str>`/`Deref<Target = str>` accessors used here are taken from the diff's consistency and the existing entity/CDATA tests rather than verified; nothing in the change itself warrants a finding.

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The tests lane reported no findings and judged the dependency bump mechanically adapted with existing parser and entity tests covering the changed call sites.
  • Lane summary: The dependency bump is adapted mechanically and the existing parser/entity tests cover the changed call sites; the one thing this revision loses is that the corrupt-directory fixture no longer makes the primary directory invalid, so the test named for the footer-fallback guard can no longer fail on that condition.

commits

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The commits lane found no sensitive content in the committed files.
  • Lane summary: No sensitive content in committed files.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The description matches the diff. The commits reviewed here are exactly what body item 2 says they are: the quick-xml 0.42 port in `src/intake/mod.rs` (names compared as `&str`, text/reference/CDATA read through the `str` deref, `decode_reference(&e)` taking the reference name directly) and in `src/markdown/ooxml.rs` (tag names compared as `&str`, `push_str(&text)` instead of `decode()`, `resolve_predefined_entity(&reference)`), plus the earlier office_order `normalized_value` change. Nothing significant in the diff is left unexplained, no public API moved, and the caveats the body states (the zip 9.2 test rewrite and the payload-footer mask not being exercised) are about code outside these commits. The vendored quick-xml source is not in the tree, so I could not read the 0.42 definitions of `BytesText`/`BytesRef` deref and `normalized_value` myself; the call sites are consistent with the `&str` signatures the diff implies and with the CI run the body reports.
Evidence and run details
  • Models: ladder/vectors-oai3, deepseek-v4.1-flash
  • Spend: $0.015481
  • Tokens: 189508 input · 70766 output · 86784 cached · 335 embedding
  • Updated: 2026-11-11T12:49:00Z
Head State Pass summary
3ff26dda8571 ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-11-11T11:55:30Z)
1fbbbc0e2d1a ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-11-11T12:26:14Z)
9c96cb2d8180 ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-11-11T12:49:00Z)

tinysweeper 0.1.2

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tinysweeper found nothing blocking. Approving.

Diagnostics

Total spend: $0.0281

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Nov 11, 2026
The test only checked the text when extraction succeeded, so an error
would have passed silently. Under zip 9.2 extraction succeeds, so require
exactly the outer document's single section.
@M3gA-Mind
M3gA-Mind merged commit 49ad092 into tinyhumansai:main Nov 11, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant