Skip to content

Default $extgstates to an array so the writers can count it (mirrors mpdf/mpdf#2135) - #20

Merged
jakejackson1 merged 1 commit into
gravitypdffrom
mirror/2135-extgstates-default
Sep 7, 2026
Merged

Default $extgstates to an array so the writers can count it (mirrors mpdf/mpdf#2135)#20
jakejackson1 merged 1 commit into
gravitypdffrom
mirror/2135-extgstates-default

Conversation

@jakejackson1

@jakejackson1 jakejackson1 commented Sep 7, 2026

Copy link
Copy Markdown
Member

Summary

This mirrors mpdf/mpdf#2135, so the fork carries the change while the upstream PR sits open.

$extgstates was declared with no default, so it is null on any Mpdf whose constructor has not run — and both ResourceWriter and BackgroundWriter reach for it with count(), which is a TypeError on PHP 8. Giving it the [] every other collection property already has closes that off.

That is the whole of the change. The upstream PR pairs it with a rewrite of SvgTest's set_up(), which is not carried over: the deprecation named in its title comes from somewhere else entirely, and upstream has since fixed that cause directly. See the note below.

Try it

$mpdf = (new ReflectionClass(\Mpdf\Mpdf::class))->newInstanceWithoutConstructor();

var_dump(count($mpdf->extgstates));

Before: TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given.
After: int(0).

Test plan

  • testExtgstatesDefaultsToAnArray in tests/Mpdf/ConfigurationTest.php asserts the property default directly, on an instance built with newInstanceWithoutConstructor(). It fails on gravitypdf (Failed asserting that null is identical to Array &0 ()) and passes here.
  • composer test — 1063 tests, 2559 assertions, up from 1062/2558.
  • composer cs clean.
More info — why the SvgTest half of [mpdf#2135](https://github.com/mpdf/pull/2135) is not mirrored

Upstream 2135 is titled after the PHP 8.1+ notice Using null as an array offset is deprecated, use an empty string instead, raised from Svg.php where it writes $this->mpdf->extgstates[$gs]['fo'] = true.

Adding = [] to $extgstates does not silence that notice. The null in question is $gs, not $extgstates — auto-vivifying an array out of a null property has never been deprecated, but using a null subscript has:

class A { public $x; }
$a = new A();
$gs = null;
$a->x[$gs]['fo'] = true;   // Deprecated: Using null as an array offset

$gs came back null because SvgTest built its Mpdf as Mockery::mock(Mpdf::class)->shouldIgnoreMissing(), so the AddExtGState() call in Svg::ImageSVG() returned null rather than a state number. The upstream PR works around that by swapping the mock for a real new \Mpdf\Mpdf().

Upstream then fixed the same thing at the source in 2dc0381 ("Fix SvgTest on PHP 8.5 by mock definition"), which teaches the mock to answer that one call:

$mpdf->shouldReceive('AddExtGState')->andReturn(1);

That commit is already in gravitypdf, so the notice does not occur here, and replacing the mock now would only make every SVG test build a full Mpdf for no gain.

mpdf/mpdf#2135 here
var $extgstates = [] yes yes
SvgTest uses a real Mpdf yes no — mock keeps AddExtGState stubbed per 2dc0381
test pinning the default none testExtgstatesDefaultsToAnArray

The property was declared without a default, so it is null on any Mpdf whose
constructor has not run. ResourceWriter and BackgroundWriter both reach for it
with count(), which is a TypeError on PHP 8.

Mirrors mpdf#2135, less its SvgTest rewrite: the deprecation that PR is
named after comes from a null $gs subscript, not from $extgstates, and upstream
has since fixed that cause in 2dc0381, which gravitypdf already carries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jakejackson1 jakejackson1 added bug Something isn't working fork-only labels Sep 7, 2026
@jakejackson1
jakejackson1 merged commit e827013 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