Skip to content

fix(deps): update dependencies - #114

Open
tannevaled wants to merge 1 commit into
mainfrom
renovate/deps
Open

tannevaled wants to merge 1 commit into
mainfrom
renovate/deps

Conversation

@tannevaled

@tannevaled tannevaled commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
github.com/go-gfx/gfx v0.34.1 → v0.35.0 age confidence
github.com/go-pdfkit/reader v0.7.0 → v0.9.0 age confidence

Release Notes

go-gfx/gfx (github.com/go-gfx/gfx)

v0.35.0: — bound the surface and the embedded raster

Compare Source

A security release. Behaviour change: svg.Rasterize now returns an error
for a surface past Options.MaxPixels, which is why it is a minor rather than
a patch. Callers wanting a larger canvas set MaxPixels.

An SVG is text, and two of the numbers in it decide allocations: the
document's own width/height, and the dimensions an embedded
<image href="data:…"> declares in its header. A surface is four bytes a pixel.

input before after
~110 bytes declaring width="40000" height="40000" 6103.5 MiB, rasterised without complaint 0.0 MiB, refused
a 246-byte SVG whose <image> claims 20000×20000 1526.1 MiB held, then drawn into a 100×100 square 0.0 MiB, skipped
a 5000×5000 document 95.4 MiB 95.4 MiB, unchanged

⛔ Nothing about the size of either input hints at the size of the output — and
drawImage skips decode failures in silence, so the gigabyte was allocated
and nothing anywhere said so.

What the fix is

Options.MaxPixels, defaulting to DefaultMaxPixels = 40 000 000 pixels
(a hundred and sixty million bytes) — the same ceiling go-pdfkit/render
already uses, so the fleet has one number for this rather than two.

  • ⛔ the embedded picture is refused from its header, via
    image.DecodeConfig, before anything is decoded: a ceiling enforced after
    the allocation it bounds is not a ceiling, it is a comment;
  • ⛔ both products are computed in int64 — two numbers a file chose,
    multiplied in int on a 32-bit build, is how a ceiling is passed by
    overflowing past it (386 is in the build matrix);
  • Scale counts towards it: the surface is the product, and only one of the
    two numbers is ours.
Also

A <line> whose two ends coincide was the module's single uncovered
statement, and the 100 % gate passed anyway because the total rounds up across
seven packages. ⛔ A gate that passes by rounding will one day pass over a real
gap. Closed.

100 % statement coverage, -race green, twelve CI checks across eight
architectures, four mutations against the ceilings all caught.

go-pdfkit/reader (github.com/go-pdfkit/reader)

v0.9.0

Compare Source

v0.8.0: — an Operation says which bytes of the stream it is

Compare Source

Operation gains Start and End: the byte range of the operation in the
stream it was scanned from — Start at its first operand (or at the operator
when it has none), End just past the operator.

⛔ They are here so a content stream can be edited in place

A tool that wants to put something before every BT has two honest ways to
find one:

  • re-serialise the whole stream, which risks changing what an inline
    image's bytes mean;
  • know where the operator was — and this scanner is the only thing that
    does.

BT appears inside strings, inside names, and inside an inline image's data,
and a byte search cannot tell those from an operator. The test pins the
discriminator:

(BT in a string) Tj  BT /F1 12 Tf ET
 ^ byte search: 1                      ← inside somebody's text
                     ^ the scan: 20     ← the operator

A tool splicing at index 1 corrupts the string.

Two details that are easy to get wrong
  • End is the lexer's position, not the operator's start plus its length.
    An inline image's operator token is BI and its operation runs to the EI
    three keywords later, so measuring from the operator would put the end in
    the middle of the image's data — where a splice corrupts the image instead
    of the stream around it. Asserted;
  • Start is the first operand's position, so splicing before an operation
    does not land between its operands and its operator. 1 0 0 RG starts at
    the 1, not at the RG.

The ranges of a stream are asserted ordered and disjoint, which is what
lets a caller splice at several of them in one pass, and a stream with rubbish
in it keeps honest ranges around what the scan stepped over.

Why in reader rather than in the caller

Three packages already scan content streams through this one scanner —
extract, render and latex — so the primitive is shared already; what was
missing was the one fact only the scan has. The first consumer is
go-pdfkit/ops, for a verb that recolours text without touching anything else.

Checks

100 % statement coverage, go vet and gofmt clean. Two mutations caught: the
range reduced to the operator alone, and the first-operand mark overwritten by
each later operand.

🤖 Generated with Claude Code


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

@tannevaled tannevaled changed the title fix(deps): update module github.com/go-gfx/gfx to v0.35.0 fix(deps): update dependencies Oct 12, 2026
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