Skip to content

Fix GH-21730: Mt19937::__debugInfo() leaks state HashTable when the serialize callback fails#21733

Merged
TimWolla merged 1 commit intophp:PHP-8.4from
iliaal:fix/gh-21730-mt19937-debuginfo-leak
Apr 12, 2026
Merged

Fix GH-21730: Mt19937::__debugInfo() leaks state HashTable when the serialize callback fails#21733
TimWolla merged 1 commit intophp:PHP-8.4from
iliaal:fix/gh-21730-mt19937-debuginfo-leak

Conversation

@iliaal
Copy link
Copy Markdown
Contributor

@iliaal iliaal commented Apr 12, 2026

Fixes #21730.

Mt19937::__debugInfo() allocates a temporary HashTable with array_init(&t) and then calls the engine's serialize callback. If the callback returns false, the method throws "Engine serialize failed" and hits RETURN_THROWS() before inserting t, so the HashTable leaks. PcgOneseq128XslRr64 and Xoshiro256StarStar alias the same method and share the leak.

Niels Dossche fixed the same pattern in __serialize() via #20383 (720e006). That cleanup didn't touch __debugInfo(). The fix here is identical: insert t into the return value before calling the callback, so RETURN_THROWS() unwinds it cleanly on failure.

The leak path is latent in stock PHP because the three built-in serialize callbacks all return true, so no user code reaches it today. Fixing for symmetry with #20383 and to keep the pattern from regressing if a future engine grows a failing serialize path. Verified under valgrind with a forced-failure patch: zero definitely-lost bytes.

…e serialize callback fails

Mt19937::__debugInfo() allocates a temporary HashTable with
array_init(&t), calls the engine's serialize callback, and then
inserts t into the return value. If the callback returns false, the
method throws and hits RETURN_THROWS() before inserting t, so the
HashTable leaks. PcgOneseq128XslRr64 and Xoshiro256StarStar alias
the same method and share the leak.

Niels Dossche fixed the same pattern in __serialize() via phpGH-20383
(720e006). That cleanup didn't touch __debugInfo(). Apply the
same reordering here: insert t into return_value first, then let
the callback populate it. RETURN_THROWS() then unwinds the return
value cleanly.

The path is latent in stock PHP because the three built-in serialize
callbacks (mt19937, pcg, xoshiro) all return true, so no user code
reaches the leak today. I'm fixing it for symmetry with phpGH-20383 and
to keep the pattern from regressing if a future engine grows a
failing serialize path.

Closes phpGH-21730
@iliaal iliaal force-pushed the fix/gh-21730-mt19937-debuginfo-leak branch from 6fb13bb to 57eb553 Compare April 12, 2026 15:43
@iliaal iliaal requested a review from TimWolla April 12, 2026 16:28
@TimWolla TimWolla merged commit 5e6b90e into php:PHP-8.4 Apr 12, 2026
19 checks passed
TimWolla added a commit that referenced this pull request Apr 12, 2026
* PHP-8.4:
  Fix GH-21730: Mt19937::__debugInfo() leaks state HashTable when the serialize callback fails (#21733)
TimWolla added a commit that referenced this pull request Apr 12, 2026
* PHP-8.5:
  Fix GH-21730: Mt19937::__debugInfo() leaks state HashTable when the serialize callback fails (#21733)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants