From 02bb8b5f82b9578f3ac0746bbbb9ecbabcc8fb2e Mon Sep 17 00:00:00 2001 From: Juliette <663378+jrfnl@users.noreply.github.com> Date: Sat, 15 Aug 2026 17:23:54 +0200 Subject: [PATCH 1/5] [skip ci] UPGRADING: Fix entry added in #23260 Newly added changelog entry created a new section for the Phar extension and added it in the wrong place. --- UPGRADING | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/UPGRADING b/UPGRADING index a5262caf3e0f..c9b14fca0dec 100644 --- a/UPGRADING +++ b/UPGRADING @@ -52,12 +52,6 @@ PHP 8.6 UPGRADE NOTES . imagesetstyle(), imagefilter() and imagecrop() filter their array arguments types / values and raise a TypeError / ValueError accordingly. -- Phar: - . Files are only automatically interpreted as Phar archives when included - if ".phar" occurs as an extension in the filename component of their - paths. Previously, it could occur in a directory name or as part of an - extension such as ".pharma". - - GMP: . GMP power and shift operators now throw a ValueError when GMP right operands are outside the unsigned long range, instead of silently truncating them. @@ -119,6 +113,10 @@ PHP 8.6 UPGRADE NOTES the reserved magic ".phar" directory through that form. . Phar::addEmptyDir() now treats non-magic names that merely share the ".phar" prefix as ordinary directories. + . Files are only automatically interpreted as Phar archives when included + if ".phar" occurs as an extension in the filename component of their + paths. Previously, it could occur in a directory name or as part of an + extension such as ".pharma". - Posix: . posix_access() now raises a ValueError when an invalid $flags From 61c2b72eec91ce57124bb66c686582d2ae12cf63 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 15 Aug 2026 16:54:05 +0100 Subject: [PATCH 2/5] session: fix some expectations for C session handlers (#23297) We *explicitly* say that mod_data will be not NULL for create_sid hooks and we violate this invariant if SessionHandler::open() is overwridden without calling the parent method. At the same time add comments explaining the situation and fix some other potential footguns. --- ext/session/mod_files.c | 11 +++--- ext/session/mod_user.c | 22 ++++++------ ext/session/mod_user_class.c | 12 +++++-- ext/session/session.c | 12 ++++--- .../session_create_id_create_sid_throws.phpt | 2 +- .../session_set_save_handler_class_005.phpt | 8 +++-- .../session_set_save_handler_class_016.phpt | 2 ++ .../session_set_save_handler_sid_002.phpt | 35 +++++-------------- 8 files changed, 49 insertions(+), 55 deletions(-) diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 3a7f8aec4522..c3c616c6479d 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -101,13 +101,13 @@ const ps_module ps_mod_files = { PS_MOD_UPDATE_TIMESTAMP(files) }; -static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, const zend_string *key) +ZEND_ATTRIBUTE_NONNULL static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, const zend_string *key) { const char *p; int i; size_t n; - if (!data || ZSTR_LEN(key) <= data->dirdepth || + if (ZSTR_LEN(key) <= data->dirdepth || buflen < (ZSTR_LEN(data->basedir) + 2 * data->dirdepth + ZSTR_LEN(key) + 5 + sizeof(FILE_PREFIX))) { return NULL; } @@ -351,12 +351,12 @@ static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetim return nrdels; } -static zend_result ps_files_key_exists(ps_files *data, const zend_string *key) +ZEND_ATTRIBUTE_NONNULL static zend_result ps_files_key_exists(ps_files *data, const zend_string *key) { char buf[MAXPATHLEN]; zend_stat_t sbuf = {0}; - if (!key || !ps_files_path_create(buf, sizeof(buf), data, key)) { + if (!ps_files_path_create(buf, sizeof(buf), data, key)) { return FAILURE; } if (VCWD_STAT(buf, &sbuf)) { @@ -678,8 +678,7 @@ PS_CREATE_SID_FUNC(files) } } /* Check collision */ - /* FIXME: mod_data(data) should not be NULL (User handler could be NULL) */ - if (data && ps_files_key_exists(data, sid) == SUCCESS) { + if (ps_files_key_exists(data, sid) == SUCCESS) { zend_string_release_ex(sid, false); sid = NULL; if (--maxfail < 0) { diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 71b8abdea8b0..5c6fe557771f 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -16,6 +16,8 @@ #include "php_session.h" #include "mod_user.h" +#include "zend_exceptions.h" + const ps_module ps_mod_user = { PS_MOD_UPDATE_TIMESTAMP(user) }; @@ -222,27 +224,23 @@ PS_CREATE_SID_FUNC(user) { /* maintain backwards compatibility */ if (!Z_ISUNDEF(PSF(create_sid))) { - zend_string *id = NULL; zval retval; ps_call_handler(&PSF(create_sid), 0, NULL, &retval); - - if (!Z_ISUNDEF(retval)) { - if (Z_TYPE(retval) == IS_STRING) { - id = zend_string_copy(Z_STR(retval)); - } - zval_ptr_dtor(&retval); - } else { - zend_throw_error(NULL, "No session id returned by function"); + /* Exception was thrown */ + if (Z_ISUNDEF(retval)) { return NULL; } - if (!id) { - zend_throw_error(NULL, "Session id must be a string"); + if (UNEXPECTED(Z_TYPE(retval) != IS_STRING)) { + /* Will no longer be needed in PHP 9 as the interface return type will be in effect */ + zend_throw_error(zend_ce_type_error, "Session id must be of type string, %s given", zend_zval_type_name(&retval)); + zval_ptr_dtor(&retval); return NULL; } + ZEND_ASSERT(Z_TYPE(retval) == IS_STRING); - return id; + return Z_STR(retval); } /* function as defined by PS_MOD */ diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c index a6bd69c91a07..9626dd27dfb1 100644 --- a/ext/session/mod_user_class.c +++ b/ext/session/mod_user_class.c @@ -51,6 +51,7 @@ PHP_METHOD(SessionHandler, open) } zend_end_try(); if (SUCCESS == ret) { + ZEND_ASSERT(PS(mod_data) && "opened default session must have mod_data"); PS(mod_user_is_open) = true; } @@ -142,13 +143,18 @@ PHP_METHOD(SessionHandler, gc) PHP_METHOD(SessionHandler, create_sid) { - zend_string *id; - ZEND_PARSE_PARAMETERS_NONE(); PS_SANITY_CHECK; + if (!PS(mod_user_is_open)) { + php_error_docref(NULL, E_WARNING, "Parent session handler is not open, defaulting to session_create_id()"); + RETURN_STR(php_session_create_id(NULL)); + } - id = PS(default_mod)->s_create_sid(&PS(mod_data)); + zend_string *id = PS(default_mod)->s_create_sid(&PS(mod_data)); + if (UNEXPECTED(id == NULL)) { + zend_throw_error(NULL, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); + } RETURN_STR(id); } diff --git a/ext/session/session.c b/ext/session/session.c index 452a3446fc14..b1f1d2a36304 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -429,9 +429,9 @@ static zend_result php_session_initialize(void) } /* Open session handler first */ - if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE - /* || PS(mod_data) == NULL */ /* FIXME: open must set valid PS(mod_data) with success */ - ) { + const zend_result open_status = PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)); + /* NOTE: PS(mod_data) might be null if the session is a custom userland session handler */ + if (open_status == FAILURE) { php_session_abort(); if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Failed to initialize storage module: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); @@ -2399,7 +2399,10 @@ PHP_FUNCTION(session_regenerate_id) zend_string_release_ex(PS(id), false); PS(id) = NULL; - if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE) { + /* Open session handler first */ + const zend_result open_status = PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)); + /* NOTE: PS(mod_data) might be null if the session is a custom userland session handler */ + if (open_status == FAILURE) { PS(session_status) = php_session_none; if (!EG(exception)) { zend_throw_error(NULL, "Failed to open session: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); @@ -2480,6 +2483,7 @@ PHP_FUNCTION(session_create_id) } } + /* NOTE: PS(mod_data) might be null if the session is a custom userland session handler */ if (!PS(in_save_handler) && PS(session_status) == php_session_active) { int limit = 3; while (limit--) { diff --git a/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt b/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt index b65c0671d940..c87df2ab458e 100644 --- a/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt +++ b/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt @@ -44,6 +44,6 @@ var_dump(session_status() === PHP_SESSION_ACTIVE); ?> --EXPECT-- -Error: Session id must be a string +TypeError: Session id must be of type string, null given Exception: create_sid failed bool(true) diff --git a/ext/session/tests/user_session_module/session_set_save_handler_class_005.phpt b/ext/session/tests/user_session_module/session_set_save_handler_class_005.phpt index c989cf39d737..cf9460c53df8 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_class_005.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_class_005.phpt @@ -37,11 +37,13 @@ session_unset(); --EXPECTF-- *** Testing session_set_save_handler() : incomplete implementation *** -Warning: SessionHandler::read(): Parent session handler is not open in %ssession_set_save_handler_class_005.php on line %d +Warning: SessionHandler::create_sid(): Parent session handler is not open, defaulting to session_create_id() in %s on line %d -Warning: SessionHandler::close(): Parent session handler is not open in %ssession_set_save_handler_class_005.php on line %d +Warning: SessionHandler::read(): Parent session handler is not open in %s on line %d -Warning: session_start(): Failed to read session data: user (%s) in %ssession_set_save_handler_class_005.php on line %d +Warning: SessionHandler::close(): Parent session handler is not open in %s on line %d + +Warning: session_start(): Failed to read session data: user (%s) in %s on line %d bool(false) string(0) "" string(4) "user" diff --git a/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt b/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt index 242035380ea0..61eecc7141d6 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_class_016.phpt @@ -72,6 +72,8 @@ session_unset(); ?> --EXPECTF-- *** Testing session_set_save_handler() function: class with create_sid *** + +Warning: SessionHandler::create_sid(): Parent session handler is not open, defaulting to session_create_id() in %s on line %d string(%d) "%s" string(4) "user" array(1) { diff --git a/ext/session/tests/user_session_module/session_set_save_handler_sid_002.phpt b/ext/session/tests/user_session_module/session_set_save_handler_sid_002.phpt index 3b9a3f411efa..c9a10de4e442 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_sid_002.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_sid_002.phpt @@ -1,5 +1,5 @@ --TEST-- -Test session_set_save_handler() function: create_sid +session_set_save_handler() with create_sid handler not returning string --INI-- session.save_path="{TMP}" --EXTENSIONS-- @@ -7,10 +7,6 @@ session --FILE-- path . $id); + return file_get_contents($this->path . $id); } public function write($id, $data): bool { @@ -55,26 +51,13 @@ class MySession2 implements SessionHandlerInterface, SessionIdInterface { } session_set_save_handler(new MySession2()); -session_start(); - -$_SESSION['foo'] = "hello"; - -var_dump(session_id(), ini_get('session.save_handler'), $_SESSION); -session_write_close(); -session_unset(); - -session_start(); -var_dump($_SESSION); +try { + session_start(); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} -session_write_close(); -session_unset(); ?> ---EXPECTF-- -*** Testing session_set_save_handler() function: create_sid *** - -Fatal error: Uncaught Error: Session id must be a string in %s:%d -Stack trace: -#0 %s(%d): session_start() -#1 {main} - thrown in %s on line %d +--EXPECT-- +TypeError: Session id must be of type string, bool given From fdd2f74612e641f1053f4f994daf06635243e8b5 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 15 Aug 2026 17:00:44 +0100 Subject: [PATCH 3/5] reflection: pass zend_object* to _class_string() (#23279) Rather than a zval --- ext/reflection/php_reflection.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 1accd39e2578..370cfe86f952 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -296,12 +296,11 @@ static void _function_string(smart_str *str, const zend_function *fptr, const ze static void _property_string(smart_str *str, const zend_property_info *prop, const zend_string *prop_name, const char *indent); static void _class_const_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char *indent); static void _enum_case_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char *indent); -static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const char *indent); static void _extension_string(smart_str *str, const zend_module_entry *module); static void _zend_extension_string(smart_str *str, const zend_extension *extension); /* {{{ _class_string */ -static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const char *indent) +static void _class_string(smart_str *str, zend_class_entry *ce, zend_object *obj, const char *indent) { /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */ if (ce->doc_comment) { @@ -310,7 +309,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const smart_str_appendc(str, '\n'); } - if (obj && Z_TYPE_P(obj) == IS_OBJECT) { + if (obj) { smart_str_append_printf(str, "%sObject of class [ ", indent); } else { const char *kind = "Class"; @@ -492,8 +491,8 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const } smart_str_append_printf(str, "%s }\n", indent); - if (obj && Z_TYPE_P(obj) == IS_OBJECT) { - HashTable *properties = zend_get_properties_no_lazy_init(Z_OBJ_P(obj)); + if (obj) { + HashTable *properties = zend_get_properties_no_lazy_init(obj); smart_str prop_str = {0}; count = 0; @@ -527,7 +526,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const zend_function *closure; /* see if this is a closure */ if (obj && is_closure_invoke(ce, mptr->common.function_name) - && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL) + && (closure = zend_get_closure_invoke_method(obj)) != NULL) { mptr = closure; } else { @@ -4260,7 +4259,7 @@ ZEND_METHOD(ReflectionClass, __toString) ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(ce); - _class_string(&str, ce, &intern->obj, ""); + _class_string(&str, ce, Z_ISUNDEF(intern->obj) ? NULL : Z_OBJ(intern->obj), ""); RETURN_STR(smart_str_extract(&str)); } /* }}} */ From 7aaa06b1022cf118a38e7915bcda877ac855708c Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 15 Aug 2026 17:04:54 +0100 Subject: [PATCH 4/5] odbc: use custom ZPP to extract result and connection (#23261) --- ext/odbc/php_odbc.c | 171 ++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 100 deletions(-) diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 468055732e14..3e7cdbb01b64 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -620,19 +620,32 @@ void odbc_sql_error(ODBC_SQL_ERROR_PARAMS) } /* }}} */ +#define Z_PARAM_ODBC_RESULT(dest) \ + { \ + zend_object *__##dest = NULL; \ + Z_PARAM_OBJ_OF_CLASS(__##dest, odbc_result_ce); \ + dest = odbc_result_from_obj(__##dest); \ + } + +#define Z_PARAM_ODBC_CONNECTION(dest) \ + { \ + zend_object *__##dest = NULL; \ + Z_PARAM_OBJ_OF_CLASS(__##dest, odbc_connection_ce); \ + dest = odbc_link_from_obj(__##dest)->connection; \ + } + + /* {{{ php_odbc_fetch_attribs */ void php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode) { odbc_result *result; - zval *pv_res; zend_long flag; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_LONG(flag) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (mode) { @@ -754,13 +767,12 @@ void odbc_bindcols(odbc_result *result) void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type) { RETCODE rc; - zval *pv_conn; + odbc_connection *conn; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); rc = SQLTransact(conn->henv, conn->hdbc, (SQLUSMALLINT)((type)?SQL_COMMIT:SQL_ROLLBACK)); @@ -778,15 +790,13 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) { odbc_result *result; SQLLEN len; - zval *pv_res; zend_long pv_num; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_LONG(pv_num) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (pv_num < 1) { @@ -850,20 +860,19 @@ PHP_FUNCTION(odbc_longreadlen) /* {{{ Prepares a statement for execution */ PHP_FUNCTION(odbc_prepare) { - zval *pv_conn; char *query; size_t query_len; odbc_result *result = NULL; RETCODE rc; int i; SQLUINTEGER scrollopts; + odbc_connection *conn; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_STRING(query, query_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -964,7 +973,7 @@ static void odbc_release_params(odbc_result *result, odbc_params_t *params) { /* {{{ Execute a prepared statement */ PHP_FUNCTION(odbc_execute) { - zval *pv_res, *tmp; + zval *tmp; HashTable *pv_param_ht = (HashTable *) &zend_empty_array; odbc_params_t *params = NULL; SQLSMALLINT ctype; @@ -973,12 +982,11 @@ PHP_FUNCTION(odbc_execute) RETCODE rc; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_OPTIONAL Z_PARAM_ARRAY_HT(pv_param_ht) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (result->numparams > 0) { @@ -1120,7 +1128,6 @@ PHP_FUNCTION(odbc_execute) /* {{{ Get cursor name */ PHP_FUNCTION(odbc_cursor) { - zval *pv_res; SQLUSMALLINT max_len; SQLSMALLINT len; char *cursorname; @@ -1128,10 +1135,9 @@ PHP_FUNCTION(odbc_cursor) RETCODE rc; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); rc = SQLGetInfo(result->conn_ptr->hdbc,SQL_MAX_CURSOR_NAME_LEN, (void *)&max_len,sizeof(max_len),&len); @@ -1176,14 +1182,14 @@ PHP_FUNCTION(odbc_cursor) /* {{{ Return information about the currently connected data source */ PHP_FUNCTION(odbc_data_source) { - zval *zv_conn; + odbc_connection *conn; zend_long zv_fetch_type; RETCODE rc = 0; /* assume all is good */ UCHAR server_name[100], desc[200]; SQLSMALLINT len1=0, len2=0, fetch_type; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(zv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_LONG(zv_fetch_type) ZEND_PARSE_PARAMETERS_END(); @@ -1194,7 +1200,6 @@ PHP_FUNCTION(odbc_data_source) RETURN_THROWS(); } - odbc_connection *conn = Z_ODBC_CONNECTION_P(zv_conn); CHECK_ODBC_CONNECTION(conn); /* now we have the "connection" lets call the DataSource object */ @@ -1234,7 +1239,7 @@ PHP_FUNCTION(odbc_data_source) /* XXX Use flags */ PHP_FUNCTION(odbc_exec) { - zval *pv_conn; + odbc_connection *conn; char *query; size_t query_len; odbc_result *result = NULL; @@ -1242,11 +1247,10 @@ PHP_FUNCTION(odbc_exec) SQLUINTEGER scrollopts; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_STRING(query, query_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -1319,11 +1323,11 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_ char *buf = NULL; zend_long pv_row = 0; bool pv_row_is_null = true; - zval *pv_res, *pv_res_arr, tmp; + zval *pv_res_arr, tmp; if (return_array || result_type == ODBC_NONE) { ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(pv_row, pv_row_is_null) ZEND_PARSE_PARAMETERS_END(); @@ -1331,14 +1335,13 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_ pv_res_arr = return_value; } else { ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_ZVAL(pv_res_arr) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(pv_row, pv_row_is_null) ZEND_PARSE_PARAMETERS_END(); } - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (!pv_row_is_null && pv_row < 1) { @@ -1533,10 +1536,9 @@ PHP_FUNCTION(odbc_result) int i = 0; RETCODE rc; SQLLEN fieldsize; - zval *pv_res; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_STR_OR_LONG(pv_field_str, pv_field_long) ZEND_PARSE_PARAMETERS_END(); @@ -1548,7 +1550,6 @@ PHP_FUNCTION(odbc_result) field_ind = (int) pv_field_long - 1; } - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (result->numcols == 0) { @@ -1734,18 +1735,16 @@ PHP_FUNCTION(odbc_result_all) char *buf = NULL; odbc_result *result; RETCODE rc; - zval *pv_res; char *pv_format = NULL; size_t i, pv_format_len = 0; SQLSMALLINT sql_c_type; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_OPTIONAL Z_PARAM_STRING(pv_format, pv_format_len) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (result->numcols == 0) { @@ -1866,14 +1865,12 @@ PHP_FUNCTION(odbc_result_all) /* {{{ Free resources associated with a result */ PHP_FUNCTION(odbc_free_result) { - zval *pv_res; odbc_result *result; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); odbc_result_free(result); @@ -2185,15 +2182,15 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ Close an ODBC connection */ PHP_FUNCTION(odbc_close) { - zval *pv_conn; + zend_object *obj; odbc_link *link; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_OBJ_OF_CLASS(obj, odbc_connection_ce) ZEND_PARSE_PARAMETERS_END(); - link = Z_ODBC_LINK_P(pv_conn); - odbc_connection *connection = Z_ODBC_CONNECTION_P(pv_conn); + link = odbc_link_from_obj(obj); + odbc_connection *connection = link->connection; CHECK_ODBC_CONNECTION(connection); odbc_link_free(link); @@ -2209,13 +2206,11 @@ PHP_FUNCTION(odbc_num_rows) { odbc_result *result; SQLLEN rows; - zval *pv_res; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); SQLRowCount(result->stmt, &rows); @@ -2227,14 +2222,12 @@ PHP_FUNCTION(odbc_num_rows) PHP_FUNCTION(odbc_next_result) { odbc_result *result; - zval *pv_res; int rc, i; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (result->values) { @@ -2274,13 +2267,11 @@ PHP_FUNCTION(odbc_next_result) PHP_FUNCTION(odbc_num_fields) { odbc_result *result; - zval *pv_res; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); RETURN_LONG(result->numcols); @@ -2291,15 +2282,13 @@ PHP_FUNCTION(odbc_num_fields) PHP_FUNCTION(odbc_field_name) { odbc_result *result; - zval *pv_res; zend_long pv_num; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_LONG(pv_num) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (pv_num < 1) { @@ -2327,15 +2316,13 @@ PHP_FUNCTION(odbc_field_type) odbc_result *result; char tmp[32]; SQLSMALLINT tmplen; - zval *pv_res; zend_long pv_num; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_LONG(pv_num) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (pv_num < 1) { @@ -2378,14 +2365,12 @@ PHP_FUNCTION(odbc_field_num) char *fname; size_t i, field_ind, fname_len; odbc_result *result; - zval *pv_res; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ODBC_RESULT(result) Z_PARAM_STRING(fname, fname_len) ZEND_PARSE_PARAMETERS_END(); - result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); if (result->numcols == 0) { @@ -2412,17 +2397,16 @@ PHP_FUNCTION(odbc_field_num) PHP_FUNCTION(odbc_autocommit) { RETCODE rc; - zval *pv_conn; + odbc_connection *conn; bool pv_onoff = false; bool pv_onoff_is_null = true; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_OPTIONAL Z_PARAM_BOOL_OR_NULL(pv_onoff, pv_onoff_is_null) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); if (!pv_onoff_is_null) { @@ -2462,17 +2446,15 @@ PHP_FUNCTION(odbc_rollback) /* {{{ php_odbc_lasterror */ static void php_odbc_lasterror(INTERNAL_FUNCTION_PARAMETERS, int mode) { - odbc_connection *conn; - zval *pv_handle = NULL; + odbc_connection *conn = NULL; char *ret; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_OBJECT_OF_CLASS(pv_handle, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) ZEND_PARSE_PARAMETERS_END(); - if (pv_handle) { - conn = Z_ODBC_CONNECTION_P(pv_handle); + if (conn) { CHECK_ODBC_CONNECTION(conn); if (mode == 0) { @@ -2578,14 +2560,14 @@ PHP_FUNCTION(odbc_setoption) /* {{{ Call the SQLTables function */ PHP_FUNCTION(odbc_tables) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *table = NULL, *type = NULL; size_t cat_len = 0, schema_len = 0, table_len = 0, type_len = 0; RETCODE rc; ZEND_PARSE_PARAMETERS_START(1, 5) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_OPTIONAL Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_PATH_OR_NULL(schema, schema_len) @@ -2593,7 +2575,6 @@ PHP_FUNCTION(odbc_tables) Z_PARAM_PATH_OR_NULL(type, type_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -2647,14 +2628,14 @@ PHP_FUNCTION(odbc_tables) /* {{{ Returns a result identifier that can be used to fetch a list of column names in specified tables */ PHP_FUNCTION(odbc_columns) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *table = NULL, *column = NULL; size_t cat_len = 0, schema_len = 0, table_len = 0, column_len = 0; RETCODE rc; ZEND_PARSE_PARAMETERS_START(1, 5) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_OPTIONAL Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_PATH_OR_NULL(schema, schema_len) @@ -2662,7 +2643,6 @@ PHP_FUNCTION(odbc_columns) Z_PARAM_PATH_OR_NULL(column, column_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -2718,21 +2698,20 @@ PHP_FUNCTION(odbc_columns) /* {{{ Returns a result identifier that can be used to fetch a list of columns and associated privileges for the specified table */ PHP_FUNCTION(odbc_columnprivileges) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema, *table, *column; size_t cat_len = 0, schema_len, table_len, column_len; RETCODE rc; ZEND_PARSE_PARAMETERS_START(5, 5) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_STRING(schema, schema_len) Z_PARAM_STRING(table, table_len) Z_PARAM_STRING(column, column_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -2781,14 +2760,14 @@ PHP_FUNCTION(odbc_columnprivileges) /* {{{ Returns a result identifier to either a list of foreign keys in the specified table or a list of foreign keys in other tables that refer to the primary key in the specified table */ PHP_FUNCTION(odbc_foreignkeys) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *pcat = NULL, *pschema, *ptable, *fcat, *fschema, *ftable; size_t pcat_len = 0, pschema_len, ptable_len, fcat_len, fschema_len, ftable_len; RETCODE rc; ZEND_PARSE_PARAMETERS_START(7, 7) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(pcat, pcat_len) Z_PARAM_STRING(pschema, pschema_len) Z_PARAM_STRING(ptable, ptable_len) @@ -2809,7 +2788,6 @@ PHP_FUNCTION(odbc_foreignkeys) EMPTY_TO_NULL(ftable); #endif - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -2860,21 +2838,20 @@ PHP_FUNCTION(odbc_foreignkeys) /* {{{ Returns a result identifier containing information about data types supported by the data source */ PHP_FUNCTION(odbc_gettypeinfo) { - zval *pv_conn; + odbc_connection *conn; zend_long pv_data_type = SQL_ALL_TYPES; odbc_result *result = NULL; RETCODE rc; SQLSMALLINT data_type; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_OPTIONAL Z_PARAM_LONG(pv_data_type) ZEND_PARSE_PARAMETERS_END(); data_type = (SQLSMALLINT) pv_data_type; - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -2919,20 +2896,19 @@ PHP_FUNCTION(odbc_gettypeinfo) /* {{{ Returns a result identifier listing the column names that comprise the primary key for a table */ PHP_FUNCTION(odbc_primarykeys) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *table = NULL; size_t cat_len = 0, schema_len, table_len; RETCODE rc; ZEND_PARSE_PARAMETERS_START(4, 4) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_STRING(schema, schema_len) Z_PARAM_STRING(table, table_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -2980,21 +2956,20 @@ PHP_FUNCTION(odbc_primarykeys) /* {{{ Returns a result identifier containing the list of input and output parameters, as well as the columns that make up the result set for the specified procedures */ PHP_FUNCTION(odbc_procedurecolumns) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *proc = NULL, *col = NULL; size_t cat_len = 0, schema_len = 0, proc_len = 0, col_len = 0; RETCODE rc; ZEND_PARSE_PARAMETERS_START(1, 5) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_PATH_OR_NULL(schema, schema_len) Z_PARAM_PATH_OR_NULL(proc, proc_len) Z_PARAM_PATH_OR_NULL(col, col_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -3043,20 +3018,19 @@ PHP_FUNCTION(odbc_procedurecolumns) /* {{{ Returns a result identifier containing the list of procedure names in a datasource */ PHP_FUNCTION(odbc_procedures) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *proc = NULL; size_t cat_len = 0, schema_len = 0, proc_len = 0; RETCODE rc; ZEND_PARSE_PARAMETERS_START(1, 4) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_PATH_OR_NULL(schema, schema_len) Z_PARAM_PATH_OR_NULL(proc, proc_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -3104,7 +3078,7 @@ PHP_FUNCTION(odbc_procedures) /* {{{ Returns a result identifier containing either the optimal set of columns that uniquely identifies a row in the table or columns that are automatically updated when any value in the row is updated by a transaction */ PHP_FUNCTION(odbc_specialcolumns) { - zval *pv_conn; + odbc_connection *conn; zend_long vtype, vscope, vnullable; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *name = NULL; @@ -3113,7 +3087,7 @@ PHP_FUNCTION(odbc_specialcolumns) RETCODE rc; ZEND_PARSE_PARAMETERS_START(7, 7) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_LONG(vtype) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_STRING(schema, schema_len) @@ -3126,7 +3100,6 @@ PHP_FUNCTION(odbc_specialcolumns) scope = (SQLUSMALLINT) vscope; nullable = (SQLUSMALLINT) vnullable; - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -3176,7 +3149,7 @@ PHP_FUNCTION(odbc_specialcolumns) /* {{{ Returns a result identifier that contains statistics about a single table and the indexes associated with the table */ PHP_FUNCTION(odbc_statistics) { - zval *pv_conn; + odbc_connection *conn; zend_long vunique, vreserved; odbc_result *result = NULL; char *cat = NULL, *schema, *name; @@ -3185,7 +3158,7 @@ PHP_FUNCTION(odbc_statistics) RETCODE rc; ZEND_PARSE_PARAMETERS_START(6, 6) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_STRING(schema, schema_len) Z_PARAM_STRING(name, name_len) @@ -3196,7 +3169,6 @@ PHP_FUNCTION(odbc_statistics) unique = (SQLUSMALLINT) vunique; reserved = (SQLUSMALLINT) vreserved; - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); @@ -3246,20 +3218,19 @@ PHP_FUNCTION(odbc_statistics) /* {{{ Returns a result identifier containing a list of tables and the privileges associated with each table */ PHP_FUNCTION(odbc_tableprivileges) { - zval *pv_conn; + odbc_connection *conn; odbc_result *result = NULL; char *cat = NULL, *schema = NULL, *table = NULL; size_t cat_len = 0, schema_len, table_len; RETCODE rc; ZEND_PARSE_PARAMETERS_START(4, 4) - Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce) + Z_PARAM_ODBC_CONNECTION(conn) Z_PARAM_PATH_OR_NULL(cat, cat_len) Z_PARAM_STRING(schema, schema_len) Z_PARAM_STRING(table, table_len) ZEND_PARSE_PARAMETERS_END(); - odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn); CHECK_ODBC_CONNECTION(conn); object_init_ex(return_value, odbc_result_ce); From 2a9416c6f78710d82558a6488991c8182d167947 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Sun, 16 Aug 2026 00:12:08 +0800 Subject: [PATCH 5/5] Zend: Various refactor with `zend_hash_str_find_ptr_lc` (#23293) zend_hash_str_find_ptr_lc is very useful in place we need to deal with lower case strings. Here we use it to replace the process of first creating the string, turning it to lower case and freeing it. --- Zend/zend_API.c | 23 +++++------------------ Zend/zend_builtin_functions.c | 5 +---- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 7731f4094ed6..6b52080643f1 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2399,9 +2399,6 @@ ZEND_API void add_property_zval_ex(zval *arg, const char *key, size_t key_len, z ZEND_API zend_result zend_startup_module_ex(zend_module_entry *module) /* {{{ */ { - size_t name_len; - zend_string *lcname; - if (module->module_started) { return SUCCESS; } @@ -2413,20 +2410,15 @@ ZEND_API zend_result zend_startup_module_ex(zend_module_entry *module) /* {{{ */ while (dep->name) { if (dep->type == MODULE_DEP_REQUIRED) { - zend_module_entry *req_mod; + zend_module_entry *req_mod = zend_hash_str_find_ptr_lc( + &module_registry, dep->name, strlen(dep->name)); - name_len = strlen(dep->name); - lcname = zend_string_alloc(name_len, 0); - zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len); - - if ((req_mod = zend_hash_find_ptr(&module_registry, lcname)) == NULL || !req_mod->module_started) { - zend_string_efree(lcname); + if (req_mod == NULL || !req_mod->module_started) { /* TODO: Check version relationship */ zend_error(E_CORE_WARNING, "Cannot load module \"%s\" because required module \"%s\" is not loaded", module->name, dep->name); module->module_started = 0; return FAILURE; } - zend_string_efree(lcname); } ++dep; } @@ -2614,17 +2606,12 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module, i while (dep->name) { if (dep->type == MODULE_DEP_CONFLICTS) { - name_len = strlen(dep->name); - lcname = zend_string_alloc(name_len, 0); - zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len); - - if (zend_hash_exists(&module_registry, lcname) || zend_get_extension(dep->name)) { - zend_string_efree(lcname); + if (zend_hash_str_find_ptr_lc(&module_registry, dep->name, strlen(dep->name)) != NULL + || zend_get_extension(dep->name)) { /* TODO: Check version relationship */ zend_error(E_CORE_WARNING, "Cannot load module \"%s\" because conflicting module \"%s\" is already loaded", module->name, dep->name); return NULL; } - zend_string_efree(lcname); } ++dep; } diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 6aa47abd2c6b..9aa930422381 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -2207,15 +2207,12 @@ ZEND_FUNCTION(debug_backtrace) ZEND_FUNCTION(extension_loaded) { zend_string *extension_name; - zend_string *lcname; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) { RETURN_THROWS(); } - lcname = zend_string_tolower(extension_name); - RETVAL_BOOL(zend_hash_exists(&module_registry, lcname)); - zend_string_release_ex(lcname, 0); + RETURN_BOOL(zend_hash_find_ptr_lc(&module_registry, extension_name) != NULL); } /* }}} */