Skip to content

Check a font is flagged before reading the keys only a used font has - #19

Merged
jakejackson1 merged 1 commit into
gravitypdffrom
fix/pattern-resources-core-font
Sep 7, 2026
Merged

Check a font is flagged before reading the keys only a used font has#19
jakejackson1 merged 1 commit into
gravitypdffrom
fix/pattern-resources-core-font

Conversation

@jakejackson1

Copy link
Copy Markdown
Member

Summary

A follow-on from #18, which found this defect in the twin code path but left it alone as out of scope.

BackgroundWriter::writePatterns() writes a resource dictionary for an SVG used as a repeating background, and picks the fonts for it out of $this->mpdf->fonts:

foreach ($this->mpdf->fonts as $font) {
	if (!$font['used'] && $font['type'] === 'TTF') {
		continue;
	}
	if (isset($font['fo']) && $font['fo']) {

used and type are read before fo — but a core font that has not drawn anything yet carries neither key. So the loop raises Undefined array key "used" on PHP 8 for any page whose only text lives inside the SVG background, which is precisely the situation in which this loop runs at all.

Testing the flag first is enough. This is not a mirror of anything upstream; the same shape landed in FormWriter in #18, where the identical order broke Issue539Test and Issue990Test.

Try it

$mpdf = new \Mpdf\Mpdf(['mode' => 'c']);
$mpdf->WriteHTML(
	'<div style="background-image: url(\'tests/data/img/pattern-with-text.svg\');'
	. ' background-repeat: repeat; height: 40mm"></div>'
);
$mpdf->Output();

On gravitypdf, with display_errors on:

Warning: Undefined array key "used" in src/Writer/BackgroundWriter.php on line 166

On this branch, nothing. Note the <div> has no text of its own — that is what leaves the core font registered but unused.

Test plan

  • composer test1050 tests, 2533 assertions, green (gravitypdf is at 1048).
  • composer cs — clean.
  • PHPStan — same 33 findings as gravitypdf, none new.
  • tests/Mpdf/BackgroundPatternResourcesTest.php — both cases error on gravitypdf, pass here.
  • The generated PDF is byte-identical to gravitypdf's once the creation date is normalised, so this is the warning and nothing else.
More info

Behaviour is unchanged

Reordering the guards cannot change which fonts are listed:

Font Before After
no fo skipped (or warned, on the way to being skipped) skipped
fo, TTF, used false skipped by the first check skipped by the inner check
fo, TTF, used true, SIP/SMP one entry per subset id same
anything else with fo one entry same

type is now isset()-guarded too, matching how ResourceWriter::writeResources() reads the same array.

The test

Two cases, both rendering the same page:

  • /PatternType 1 is in the output, so the tiling-pattern branch really ran — without that, a passing test would prove nothing, since PHPUnit's warning-to-error conversion is what catches the regression.
  • The pattern's /Resources object still names the font its Form XObject draws with, so the reorder has not quietly dropped anything. The fixture SVG carries a <text> element for that reason; none of the existing SVG fixtures do.

Relationship to #18

Independent — different file, no conflict, either order. #18 fixes the same defect in FormWriter::getResources(), which is new code there; this one has been in BackgroundWriter all along.

_putpatterns() builds a resource dictionary for an SVG background by
picking out the fonts an SVG has flagged, but it tests $font['used']
and $font['type'] before it tests $font['fo']. A core font that has
drawn nothing yet has neither key, so any page whose only text lives
inside a repeating SVG background raises "Undefined array key" on
PHP 8 — and a page like that is exactly when the loop runs.

Test the flag first. Nothing else changes: the output for such a
document is byte for byte what it was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jakejackson1 jakejackson1 added bug Something isn't working create-upstream-pr labels Sep 7, 2026
@jakejackson1
jakejackson1 merged commit db8c706 into gravitypdf Sep 7, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working create-upstream-pr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant