Skip to content

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

Closed
iliaal wants to merge 1 commit intoPHP-8.4from
fix/gh-21730-mt19937-debuginfo-leak
Closed

Fix GH-21730: Mt19937::__debugInfo() leaks state HashTable when the serialize callback fails#33
iliaal wants to merge 1 commit intoPHP-8.4from
fix/gh-21730-mt19937-debuginfo-leak

Conversation

@iliaal
Copy link
Copy Markdown
Owner

@iliaal iliaal commented Apr 12, 2026

Fixes php#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 php#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. I'm filing it for symmetry with php#20383 and to keep the pattern from regressing if a future engine grows a failing serialize path.

The new phpt (debuginfo_states.phpt) locks down the success-path output shape for all three engines, so future refactors of this code have something to break against. The leak itself can't be exercised from PHP without patching the source (covered in the linked issue). I verified the fix under valgrind with a forced-failure patch: the fixed build reports 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 e16347f to 6fb13bb Compare April 12, 2026 01:34
@iliaal
Copy link
Copy Markdown
Owner Author

iliaal commented Apr 12, 2026

Submitted upstream as php#21733

@iliaal iliaal closed this Apr 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