Skip to content

chore(docx): stop parsing values the export wrote itself - #715

Merged
DemchaAV merged 1 commit into
2.5-devfrom
chore/docx-codeql-cleanup
Sep 23, 2026
Merged

DemchaAV merged 1 commit into
2.5-devfrom
chore/docx-codeql-cleanup

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

Every DOCX PR from #705 to #711 carried CodeQL review comments that were never cleared —
uncaught NumberFormatException from parsing values back out of the file, and calls to
deprecated overloads. The CodeQL check passes either way: the findings arrive as inline
review comments, not as a failing check. #714 cleared the ones on its own paths; this clears
the rest.

None of them is reachable with a malformed value — every parsed value was one the export had
just written — but each is a parse the code never needed.

What changed

Production code parses nothing it wrote.

  • DocxFontEmbedding.keyOf takes the obfuscation key from the UUID's bits instead of from its
    printed form. The GUID's hex digits read backwards by pair are its sixteen bytes read
    backwards — the low half's least significant byte first — so the key is the same, with no
    text in between.
  • shadingFillOf reads a written colour from the three bytes XmlBeans hands an RGB back as,
    rather than formatting them to hex and parsing that. Anything else — Word's auto, or a
    value this export did not write — is no colour it can composite against, as before.
  • The internal-anchor hyperlink run is built through POI's IRunBody constructor, and a
    run's paragraph is read through getParent(), both in place of deprecated overloads.

Tests read twips through one helper. Nine helpers across eight test files each parsed
their own copy of String.valueOf(measure). DocxTwips.of asserts the value is the number
the export writes and returns it, so a value that is not one fails as that rather than as a
parse error. The probe fixtures use RowBuilder.spacing, which the deprecated gap delegates
to — the same value, the same layout.

After this, render-docx contains no parseLong or parseInt at all.

Verification

./mvnw -B -ntp clean verify over the eight-module gate → BUILD SUCCESS (core 815,
render-pdf 337, render-docx 230, testing 5, render-pptx 140, templates 127, qa 1784).
./mvnw -B -ntp test -f examples/pom.xml → 93 tests, BUILD SUCCESS; no committed preview
drifted.

No test was added or removed: this changes how values are read, not what is written.
DocxFontEmbeddingTest pins the key against the published example from the specification
({F9168C5E-CEB2-4FAA-B6BF-329BF39FA1E4} → E4 A1 9F F3 9B 32 BF B6 …) and passes on the
bit-derived key; the chip-flattening tests pass on the byte-read colour.

Lane: canonical — document.backend.semantic.docx, test-scope helpers. No public API
change.

CodeQL flagged each of these as an uncaught NumberFormatException or a
deprecated call as they landed, and none had been cleared.

The font obfuscation key is taken from the UUID's bits rather than from
its printed form — the GUID's digits read backwards by pair are its
sixteen bytes read backwards — and the published example's key bytes
still match. A shading colour is read from the three bytes XmlBeans hands
a written RGB back as, rather than formatted to text and parsed. The
hyperlink run goes through POI's IRunBody constructor and a run's
paragraph through getParent(), both in place of deprecated overloads.

The tests read twips back through one helper, DocxTwips.of, which asserts
the value is the number the export writes instead of each helper parsing
its own copy of the text, and the probe fixtures use RowBuilder.spacing
where they used the deprecated gap it delegates to.
@DemchaAV
DemchaAV merged commit cbe301d into 2.5-dev Sep 23, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the chore/docx-codeql-cleanup branch September 23, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant