diff --git a/NEWS b/NEWS index 44780f84d7454..b6d27bb15aa0b 100644 --- a/NEWS +++ b/NEWS @@ -149,6 +149,8 @@ PHP NEWS - Zlib: . gzfile, gzopen and readgzfile, their "use_include_path" argument is now a boolean. (David Carlier) + . Fixed bug GH-16883 (gzopen() does not use the default stream context when + opening HTTP URLs). (nielsdos) <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/UPGRADING b/UPGRADING index 805d2f62440b7..3d0c1101ed5ad 100644 --- a/UPGRADING +++ b/UPGRADING @@ -166,6 +166,8 @@ PHP 8.5 UPGRADE NOTES . The "use_include_path" argument for the gzfile, gzopen and readgzfile functions had been changed from int to boolean. + . gzfile, gzopen and readgzfile functions now respect the default + stream context. ======================================== 6. New Functions diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index fcbae4e34621f..5a177457a4492 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -307,7 +307,7 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name f.type = ZEND_INTERNAL_FUNCTION; f.num_args = 0; f.arg_info = NULL; - f.scope = obj->ce; + f.scope = obj->zo.ce; f.fn_flags = ZEND_ACC_CALL_VIA_HANDLER; f.function_name = zend_string_copy(name); f.handler = PHP_FN(com_method_handler); @@ -392,7 +392,7 @@ static zend_string* com_class_name_get(const zend_object *object) { php_com_dotnet_object *obj = (php_com_dotnet_object *)object; - return zend_string_copy(obj->ce->name); + return zend_string_copy(obj->zo.ce->name); } /* This compares two variants for equality */ @@ -625,7 +625,6 @@ zend_object* php_com_object_new(zend_class_entry *ce) VariantInit(&obj->v); obj->code_page = CP_ACP; - obj->ce = ce; zend_object_std_init(&obj->zo, ce); diff --git a/ext/com_dotnet/com_misc.c b/ext/com_dotnet/com_misc.c index 3c85fc4ce5e4a..a5de6415b9a73 100644 --- a/ext/com_dotnet/com_misc.c +++ b/ext/com_dotnet/com_misc.c @@ -50,8 +50,6 @@ PHP_COM_DOTNET_API void php_com_wrap_dispatch(zval *z, IDispatch *disp, obj = emalloc(sizeof(*obj)); memset(obj, 0, sizeof(*obj)); obj->code_page = codepage; - obj->ce = php_com_variant_class_entry; - obj->zo.ce = php_com_variant_class_entry; VariantInit(&obj->v); V_VT(&obj->v) = VT_DISPATCH; @@ -72,8 +70,6 @@ PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v, obj = emalloc(sizeof(*obj)); memset(obj, 0, sizeof(*obj)); obj->code_page = codepage; - obj->ce = php_com_variant_class_entry; - obj->zo.ce = php_com_variant_class_entry; VariantInit(&obj->v); VariantCopyInd(&obj->v, v); diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index 90c3ab2d40e41..09fe494393470 100644 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -35,8 +35,6 @@ typedef struct _php_com_dotnet_object { ITypeInfo *typeinfo; - zend_class_entry *ce; - /* associated event sink */ IDispatch *sink_dispatch; GUID sink_id; diff --git a/ext/fileinfo/tests/cve-2014-3538-mb.phpt b/ext/fileinfo/tests/cve-2014-3538-mb.phpt index 1cbeaf45a58dd..e6c63e35ac852 100644 --- a/ext/fileinfo/tests/cve-2014-3538-mb.phpt +++ b/ext/fileinfo/tests/cve-2014-3538-mb.phpt @@ -30,7 +30,7 @@ if ($t < 3) { Done --CLEAN-- --EXPECTF-- string(%d) "%s" diff --git a/ext/fileinfo/tests/cve-2014-3538-nojit.phpt b/ext/fileinfo/tests/cve-2014-3538-nojit.phpt index 5ddc2765ee556..2010d538da951 100644 --- a/ext/fileinfo/tests/cve-2014-3538-nojit.phpt +++ b/ext/fileinfo/tests/cve-2014-3538-nojit.phpt @@ -13,7 +13,7 @@ if (getenv('SKIP_PERF_SENSITIVE')) pcre.jit=0 --FILE-- --EXPECTF-- string(%d) "%s" diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 85637a61826c1..34a4064f5fcb1 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -408,9 +408,6 @@ static void *fontFetch (char **error, void *key) path = gdEstrdup (fontsearchpath); /* if name is an absolute filename then test directly */ -#ifdef NETWARE - if (*name == '/' || (name[0] != 0 && strstr(name, ":/"))) { -#else /* Actual length doesn't matter, just the minimum does up to length 2. */ unsigned int min_length = 0; if (name[0] != '\0') { @@ -422,7 +419,6 @@ static void *fontFetch (char **error, void *key) } ZEND_IGNORE_VALUE(min_length); /* On Posix systems this may be unused */ if (IS_ABSOLUTE_PATH(name, min_length)) { -#endif snprintf(fullname, sizeof(fullname) - 1, "%s", name); if (access(fullname, R_OK) == 0) { font_found++; diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 08243f16b1ed2..6c7d58a6ee698 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -146,6 +146,8 @@ static void preload_restart(void); # define LOCKVAL(v) (ZCSG(v)) #endif +#define ZCG_KEY_LEN (MAXPATHLEN * 8) + /** * Clear AVX/SSE2-aligned memory. */ @@ -1195,7 +1197,8 @@ zend_string *accel_make_persistent_key(zend_string *str) char *key; int key_length; - ZSTR_LEN(&ZCG(key)) = 0; + ZEND_ASSERT(GC_REFCOUNT(ZCG(key)) == 1); + ZSTR_LEN(ZCG(key)) = 0; /* CWD and include_path don't matter for absolute file names and streams */ if (IS_ABSOLUTE_PATH(path, path_length)) { @@ -1305,7 +1308,7 @@ zend_string *accel_make_persistent_key(zend_string *str) } /* Calculate key length */ - if (UNEXPECTED((size_t)(cwd_len + path_length + include_path_len + 2) >= sizeof(ZCG(_key)))) { + if (UNEXPECTED((size_t)(cwd_len + path_length + include_path_len + 2) >= ZCG_KEY_LEN)) { return NULL; } @@ -1314,7 +1317,7 @@ zend_string *accel_make_persistent_key(zend_string *str) * since in itself, it may include colons (which we use to separate * different components of the key) */ - key = ZSTR_VAL(&ZCG(key)); + key = ZSTR_VAL(ZCG(key)); memcpy(key, path, path_length); key[path_length] = ':'; key_length = path_length + 1; @@ -1338,7 +1341,7 @@ zend_string *accel_make_persistent_key(zend_string *str) parent_script_len = ZSTR_LEN(parent_script); while ((--parent_script_len > 0) && !IS_SLASH(ZSTR_VAL(parent_script)[parent_script_len])); - if (UNEXPECTED((size_t)(key_length + parent_script_len + 1) >= sizeof(ZCG(_key)))) { + if (UNEXPECTED((size_t)(key_length + parent_script_len + 1) >= ZCG_KEY_LEN)) { return NULL; } key[key_length] = ':'; @@ -1347,11 +1350,9 @@ zend_string *accel_make_persistent_key(zend_string *str) key_length += parent_script_len; } key[key_length] = '\0'; - GC_SET_REFCOUNT(&ZCG(key), 1); - GC_TYPE_INFO(&ZCG(key)) = GC_STRING; - ZSTR_H(&ZCG(key)) = 0; - ZSTR_LEN(&ZCG(key)) = key_length; - return &ZCG(key); + ZSTR_H(ZCG(key)) = 0; + ZSTR_LEN(ZCG(key)) = key_length; + return ZCG(key); } /* not use_cwd */ @@ -2026,8 +2027,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) ZCG(cache_opline) == EG(current_execute_data)->opline))) { persistent_script = ZCG(cache_persistent_script); - if (ZSTR_LEN(&ZCG(key))) { - key = &ZCG(key); + if (ZSTR_LEN(ZCG(key))) { + key = ZCG(key); } } else { @@ -2580,7 +2581,7 @@ static zend_string* persistent_zend_resolve_path(zend_string *filename) SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); } else { - ZSTR_LEN(&ZCG(key)) = 0; + ZSTR_LEN(ZCG(key)) = 0; } ZCG(cache_opline) = EG(current_execute_data) ? EG(current_execute_data)->opline : NULL; ZCG(cache_persistent_script) = persistent_script; @@ -2952,7 +2953,15 @@ static void accel_globals_ctor(zend_accel_globals *accel_globals) ZEND_TSRMLS_CACHE_UPDATE(); #endif memset(accel_globals, 0, sizeof(zend_accel_globals)); + accel_globals->key = zend_string_alloc(ZCG_KEY_LEN, true); +} + +#ifdef ZTS +static void accel_globals_dtor(zend_accel_globals *accel_globals) +{ + zend_string_free(accel_globals->key); } +#endif #ifdef HAVE_HUGE_CODE_PAGES # ifndef _WIN32 @@ -3128,7 +3137,7 @@ static void accel_move_code_to_huge_pages(void) static int accel_startup(zend_extension *extension) { #ifdef ZTS - accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, NULL); + accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); #else accel_globals_ctor(&accel_globals); #endif diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 3f7eb3bdf008f..440d09e235dc5 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -224,8 +224,7 @@ typedef struct _zend_accel_globals { const zend_op *cache_opline; zend_persistent_script *cache_persistent_script; /* preallocated buffer for keys */ - zend_string key; - char _key[MAXPATHLEN * 8]; + zend_string *key; } zend_accel_globals; typedef struct _zend_string_table { diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index ffe09a6bf16aa..939adbfb202a6 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -136,7 +136,11 @@ static int odbc_stmt_dtor(pdo_stmt_t *stmt) { pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; - if (S->stmt != SQL_NULL_HANDLE) { + // TODO: Factor this out; pg/mysql/firebird do the same thing + bool server_obj_usable = !Z_ISUNDEF(stmt->database_object_handle) + && IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)]) + && !(OBJ_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED); + if (S->stmt != SQL_NULL_HANDLE && server_obj_usable) { if (stmt->executed) { SQLCloseCursor(S->stmt); } diff --git a/ext/zlib/tests/gh16883.phpt b/ext/zlib/tests/gh16883.phpt new file mode 100644 index 0000000000000..c3d81d4537938 --- /dev/null +++ b/ext/zlib/tests/gh16883.phpt @@ -0,0 +1,46 @@ +--TEST-- +GH-16883 (gzopen() does not use the default stream context when opening HTTP URLs) +--EXTENSIONS-- +zlib +--INI-- +allow_url_fopen=1 +--SKIPIF-- + +--FILE-- + array( + 'user_agent' => 'dummy', + ) +]); + +$f = gzopen('http://'.PHP_CLI_SERVER_HOSTNAME.':'.PHP_CLI_SERVER_PORT, 'r'); +var_dump(stream_get_contents($f)); + +var_dump(gzfile('http://'.PHP_CLI_SERVER_HOSTNAME.':'.PHP_CLI_SERVER_PORT, 'r')); + +var_dump(readgzfile('http://'.PHP_CLI_SERVER_HOSTNAME.':'.PHP_CLI_SERVER_PORT, 'r')); + +?> +--EXPECT-- +string(6) "dummy +" +array(1) { + [0]=> + string(6) "dummy +" +} +dummy +int(6) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index df3d270217d45..3a72bd506340f 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -26,6 +26,7 @@ #include "SAPI.h" #include "php_ini.h" #include "ext/standard/info.h" +#include "ext/standard/file.h" #include "php_zlib.h" #include "zlib_arginfo.h" @@ -621,7 +622,7 @@ PHP_FUNCTION(gzfile) } /* using a stream here is a bit more efficient (resource wise) than php_gzopen_wrapper */ - stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC); + stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, php_stream_context_from_zval(NULL, false) STREAMS_CC); if (!stream) { /* Error reporting is already done by stream code */ @@ -659,7 +660,7 @@ PHP_FUNCTION(gzopen) flags |= USE_PATH; } - stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, NULL STREAMS_CC); + stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, php_stream_context_from_zval(NULL, false) STREAMS_CC); if (!stream) { RETURN_FALSE; @@ -686,7 +687,7 @@ PHP_FUNCTION(readgzfile) flags |= USE_PATH; } - stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC); + stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, php_stream_context_from_zval(NULL, false) STREAMS_CC); if (!stream) { RETURN_FALSE;