Conversation
SQLite3::close() called from within a userland function, aggregate, collation or authorizer callback freed the registered statements and functions while sqlite3 was still executing, corrupting the active statement and crashing the request. Track callback re-entry with a per-database counter shared by all four callback kinds and throw an Error from close() while it is non-zero; the database stays usable and can be closed after the query completes. Closes phpGH-23650
* PHP-8.4: ext/sqlite3: reject close() from inside a callback
The x86 matcher folds v = BINOP(a, b); c = CMP(v, 0); GUARD(c) into IR_GUARD_JCC_INT, emitting the BINOP, dropping the CMP and branching on the flags the BINOP left, but it only required the BINOP to precede the CMP in the IR. Once GCM hoists a loop-invariant BINOP into a dominating block, the jcc reads flags the intervening code has clobbered and the guard fires on whatever is in EFLAGS. Require the BINOP to sit in the guard's block and allow only snapshots between the comparison and the guard, the way ir_match_fuse_load() pairs ir_in_same_block() with ir_match_has_mem_deps(). The sibling MEM_BINOP fold already checks the block, the IF side folds are pinned by full ref adjacency, and ir_aarch64.dasc has no guard fold. Mirrors the upstream fix dstogov/ir@51107a3. Fixes phpGH-23693
iliaal
force-pushed
the
fix/gh-23693-guard-jcc-cross-block
branch
from
September 16, 2026 17:42
d817cc3 to
b9bf306
Compare
Owner
Author
|
Submitted upstream as php#23711. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The x86 instruction matcher folds
v = BINOP(a, b); c = CMP(v, 0); GUARD(c)into a bare conditional jump on the flags the BINOP left behind, checking only that the BINOP precedes the CMP in the IR. Once GCM hoists a loop-invariant BINOP into a dominating block, the jump reads flags the intervening code has clobbered. In phpGH-23693 that dropsif ($newY < 0) continue;from a recursive board search, so$newPosbecomes -3 and the function throws on an argument it has already proved non-negative.The fold now requires the BINOP in the guard's own block, with only snapshots between the comparison and the guard, the way
ir_match_fuse_load()pairsir_in_same_block()withir_match_has_mem_deps(). Across the reporter's script, the new test,Zend/bench.phpandZend/micro_bench.phpit fires four times before the patch and twice after; the two it loses are the miscompiles.PHP-8.4 compiles the same rule but does not hoist the addition under any of the 20 hot-counter combinations tried, so the test is green there and this targets 8.5. Separately,
ir_gcm.c:598loops onn < 0where upstream IR hasn > 0, so the "OVERFLOW must be scheduled into the same block" pin never runs; that one is stale sync drift and the next IR update resolves it.