Found during PR #598 review (out of scope there).
Problem
`fbird_batch.c:178` stores `fb_batch->trans = trans;` (raw `fbird_transaction*`), dereferenced at :627. The #594 fix added a registry detaching `fbird_query` back-refs before the transaction struct is efree'd (link close / le_trans dtor / execute_auto temps) - batch resources were deliberately left out (same scope decision as #591's BlobWrapper note).
Same failure shape as #594: transaction struct efree'd while a live batch resource holds the pointer -> UAF on later batch ops/shutdown.
Fix direction
Extend the #594 pattern one more holder type: enroll batches in the same per-transaction registry (or a parallel one) and detach at the same 9 sites. The registry helpers (_php_fbird_trans_reg_query/unreg/detach) are typed to fbird_query - either generalize the intrusive list or duplicate minimally.
Acceptance criteria
Found during PR #598 review (out of scope there).
Problem
`fbird_batch.c:178` stores `fb_batch->trans = trans;` (raw `fbird_transaction*`), dereferenced at :627. The #594 fix added a registry detaching `fbird_query` back-refs before the transaction struct is efree'd (link close / le_trans dtor / execute_auto temps) - batch resources were deliberately left out (same scope decision as #591's BlobWrapper note).
Same failure shape as #594: transaction struct efree'd while a live batch resource holds the pointer -> UAF on later batch ops/shutdown.
Fix direction
Extend the #594 pattern one more holder type: enroll batches in the same per-transaction registry (or a parallel one) and detach at the same 9 sites. The registry helpers (_php_fbird_trans_reg_query/unreg/detach) are typed to fbird_query - either generalize the intrusive list or duplicate minimally.
Acceptance criteria