Merge branch 'PHP-8.4'

* PHP-8.4:
  pdo_odbc: Fix memory leak if WideCharToMultiByte() fails
  Fix memory leak on php_odbc_fetch_hash() failure
  Do not delete main chunk in zend_gc
This commit is contained in:
Niels Dossche 2025-06-09 11:26:27 +02:00
commit 502c68264d
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
7 changed files with 33 additions and 2 deletions

13
Zend/tests/gh18756.phpt Normal file
View file

@ -0,0 +1,13 @@
--TEST--
Bug GH-18756: Zend MM may delete the main chunk
--EXTENSIONS--
zend_test
--FILE--
<?php
zend_test_gh18756();
?>
==DONE==
--EXPECT--
==DONE==

View file

@ -2192,7 +2192,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
i++; i++;
} }
} }
if (chunk->free_pages == ZEND_MM_PAGES - ZEND_MM_FIRST_PAGE) { if (chunk->free_pages == ZEND_MM_PAGES - ZEND_MM_FIRST_PAGE && chunk != heap->main_chunk) {
zend_mm_chunk *next_chunk = chunk->next; zend_mm_chunk *next_chunk = chunk->next;
zend_mm_delete_chunk(heap, chunk); zend_mm_delete_chunk(heap, chunk);

View file

@ -1461,6 +1461,7 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type)
if (rc == SQL_ERROR) { if (rc == SQL_ERROR) {
odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData"); odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");
efree(buf); efree(buf);
zval_ptr_dtor(return_value);
RETURN_FALSE; RETURN_FALSE;
} }

View file

@ -103,6 +103,7 @@ static int pdo_odbc_ucs22utf8(int is_unicode, zval *result)
zend_string *str = zend_string_alloc(ret, 0); zend_string *str = zend_string_alloc(ret, 0);
ret = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) Z_STRVAL_P(result), Z_STRLEN_P(result)/sizeof(WCHAR), ZSTR_VAL(str), ZSTR_LEN(str), NULL, NULL); ret = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) Z_STRVAL_P(result), Z_STRLEN_P(result)/sizeof(WCHAR), ZSTR_VAL(str), ZSTR_LEN(str), NULL, NULL);
if (ret == 0) { if (ret == 0) {
zend_string_efree(str);
return PDO_ODBC_CONV_FAIL; return PDO_ODBC_CONV_FAIL;
} }

View file

@ -1613,3 +1613,13 @@ static PHP_FUNCTION(zend_test_compile_to_ast)
RETVAL_STR(result); RETVAL_STR(result);
} }
static PHP_FUNCTION(zend_test_gh18756)
{
ZEND_PARSE_PARAMETERS_NONE();
zend_mm_heap *heap = zend_mm_startup();
zend_mm_gc(heap);
zend_mm_gc(heap);
zend_mm_shutdown(heap, true, false);
}

View file

@ -334,6 +334,8 @@ function zend_test_override_libxml_global_state(): void {}
function zend_test_log_err_debug(string $str): void {} function zend_test_log_err_debug(string $str): void {}
function zend_test_compile_to_ast(string $str): string {} function zend_test_compile_to_ast(string $str): string {}
function zend_test_gh18756(): void {}
} }
namespace ZendTestNS { namespace ZendTestNS {

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead. /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 37ac76dddea2da24d3275cccc748b8fea4c8d09c */ * Stub hash: 13a5559e87cb073c921006bb3be5354b90247306 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
@ -177,6 +177,8 @@ ZEND_END_ARG_INFO()
#define arginfo_zend_test_compile_to_ast arginfo_zend_create_unterminated_string #define arginfo_zend_test_compile_to_ast arginfo_zend_create_unterminated_string
#define arginfo_zend_test_gh18756 arginfo_zend_test_void_return
#define arginfo_ZendTestNS2_namespaced_func arginfo_zend_test_is_pcre_bundled #define arginfo_ZendTestNS2_namespaced_func arginfo_zend_test_is_pcre_bundled
#define arginfo_ZendTestNS2_namespaced_deprecated_func arginfo_zend_test_void_return #define arginfo_ZendTestNS2_namespaced_deprecated_func arginfo_zend_test_void_return
@ -315,6 +317,7 @@ static ZEND_FUNCTION(zend_test_cast_fread);
static ZEND_FUNCTION(zend_test_is_zend_ptr); static ZEND_FUNCTION(zend_test_is_zend_ptr);
static ZEND_FUNCTION(zend_test_log_err_debug); static ZEND_FUNCTION(zend_test_log_err_debug);
static ZEND_FUNCTION(zend_test_compile_to_ast); static ZEND_FUNCTION(zend_test_compile_to_ast);
static ZEND_FUNCTION(zend_test_gh18756);
static ZEND_FUNCTION(ZendTestNS2_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_namespaced_func);
static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func); static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func);
static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func); static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func);
@ -440,6 +443,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(zend_test_is_zend_ptr, arginfo_zend_test_is_zend_ptr) ZEND_FE(zend_test_is_zend_ptr, arginfo_zend_test_is_zend_ptr)
ZEND_FE(zend_test_log_err_debug, arginfo_zend_test_log_err_debug) ZEND_FE(zend_test_log_err_debug, arginfo_zend_test_log_err_debug)
ZEND_FE(zend_test_compile_to_ast, arginfo_zend_test_compile_to_ast) ZEND_FE(zend_test_compile_to_ast, arginfo_zend_test_compile_to_ast)
ZEND_FE(zend_test_gh18756, arginfo_zend_test_gh18756)
#if (PHP_VERSION_ID >= 80400) #if (PHP_VERSION_ID >= 80400)
ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_func"), zif_ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func, 0, NULL, NULL) ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_func"), zif_ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func, 0, NULL, NULL)
#else #else