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 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); } /* }}} */ 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); 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)); } /* }}} */ 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