Commit 11da2ee255f for php.net

commit 11da2ee255fd04c1cd891f6fa7c2c4501a1c9060
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Sun Sep 13 10:13:58 2026 -0400

    TSRM: roll back id_count when the resource type table cannot grow (#23595)

    ts_allocate_id(), ts_allocate_fast_id_at() and ts_allocate_tls_id()
    increment id_count before growing resource_types_table. When the
    realloc fails they return 0 with id_count still counting the new slot,
    so allocate_new_resource() later walks j < id_count and reads an entry
    that was never initialized. Roll id_count back on those three paths.

    Closes GH-23595

diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c
index a5032e456aa..a9f6ed5c59b 100644
--- a/TSRM/TSRM.c
+++ b/TSRM/TSRM.c
@@ -305,6 +305,7 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
 		_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
 		if (!_tmp) {
 			TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
+			id_count--;
 			*rsrc_id = 0;
 			tsrm_mutex_unlock(tsmm_mutex);
 			return 0;
@@ -384,6 +385,7 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id_at(ts_rsrc_id *rsrc_id, size_t *offset,
 		_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
 		if (!_tmp) {
 			TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
+			id_count--;
 			*rsrc_id = 0;
 			tsrm_mutex_unlock(tsmm_mutex);
 			return 0;
@@ -419,6 +421,7 @@ TSRM_API ts_rsrc_id ts_allocate_tls_id(ts_rsrc_id *rsrc_id, void *(*tls_addr)(vo
 		_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
 		if (!_tmp) {
 			TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
+			id_count--;
 			*rsrc_id = 0;
 			tsrm_mutex_unlock(tsmm_mutex);
 			return 0;