From b4ba65dd9d615cc6bed93660cc6d0ab964e1e8ec Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Dec 2021 00:38:51 +0100 Subject: [PATCH 001/227] Fix chunk_split_variation*_32bit.phpt for Windows Both tests fail on Windows for slightly different reasons, what appears to be legit, and as such we fix the test expectations. Closes GH-7830. --- ext/standard/tests/strings/chunk_split_variation1_32bit.phpt | 2 +- ext/standard/tests/strings/chunk_split_variation2_32bit.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt index b2fd29ad88098..b4bef8add4103 100644 --- a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt +++ b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt @@ -17,4 +17,4 @@ var_dump(chunk_split($a,$b,$c)); --EXPECTF-- *** Testing chunk_split() : unexpected large 'end' string argument variation 1 *** -Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d +Fatal error: %rAllowed memory size of %d bytes exhausted%s\(tried to allocate %d bytes\)|Possible integer overflow in memory allocation \(4294901777 \+ 2097152\)%r in %s on line %d diff --git a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt index 0f777fbd38605..c83a37f00edb4 100644 --- a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt +++ b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt @@ -16,4 +16,4 @@ var_dump(chunk_split($a,$b,$c)); --EXPECTF-- *** Testing chunk_split() : unexpected large 'end' string argument variation 2 *** -Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + 65556) in %s on line %d +Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + %r65556|65560%r) in %s on line %d From fd3fc5c193d056923340d74d4f5be407c089ba94 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Dec 2021 00:05:03 +0100 Subject: [PATCH 002/227] Fix GH-7826: Inconsistent argument name in hash_hmac_file and hash_file Like `hash_file()`, `hash_hmac_file()` expects a filename, and not some string data. Fixing this now, constitutes a (hopefully small) BC break though. Closes GH-7828. --- NEWS | 2 ++ ext/hash/hash.stub.php | 2 +- ext/hash/hash_arginfo.h | 4 ++-- ext/hash/tests/hash_hmac_file_error.phpt | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 2eafc4acad89e..30f8b64959f5a 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ PHP NEWS - Hash: . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). (cmb) + . Fixed bug GH-7826 (Inconsistent argument name in hash_hmac_file and + hash_file). (cmb) - OCI8: . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second diff --git a/ext/hash/hash.stub.php b/ext/hash/hash.stub.php index 250fb68ee4e9f..0a9ac41100b9d 100644 --- a/ext/hash/hash.stub.php +++ b/ext/hash/hash.stub.php @@ -8,7 +8,7 @@ function hash_file(string $algo, string $filename, bool $binary = false): string function hash_hmac(string $algo, string $data, string $key, bool $binary = false): string {} -function hash_hmac_file(string $algo, string $data, string $key, bool $binary = false): string|false {} +function hash_hmac_file(string $algo, string $filename, string $key, bool $binary = false): string|false {} function hash_init(string $algo, int $flags = 0, string $key = ""): HashContext {} diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index 5aef2c11d1d61..ade717d4002f4 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f73c6fa1a4ac1ca93f87775bbe69fbdb2deb5746 */ + * Stub hash: ae4f5ceba77eee7062cbd2fadb112aac33d198ce */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hash, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) @@ -22,7 +22,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash_hmac_file, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() diff --git a/ext/hash/tests/hash_hmac_file_error.phpt b/ext/hash/tests/hash_hmac_file_error.phpt index 7cbc347691202..3a4d85ee7e35b 100644 --- a/ext/hash/tests/hash_hmac_file_error.phpt +++ b/ext/hash/tests/hash_hmac_file_error.phpt @@ -43,4 +43,4 @@ hash_hmac_file(): Argument #1 ($algo) must be a valid cryptographic hashing algo hash_hmac_file(): Argument #1 ($algo) must be a valid cryptographic hashing algorithm -- Testing hash_hmac_file() function with bad path -- -hash_hmac_file(): Argument #2 ($data) must not contain any null bytes +hash_hmac_file(): Argument #2 ($filename) must not contain any null bytes From 1050edaef8e4c24bd194aa1cbfb14f2edca9162b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 26 Dec 2021 10:11:59 +0100 Subject: [PATCH 003/227] Extract special function evaluation from pass1 Pass1 handles a number of special functions that can be evaluated under some circumstances. Move the core logic into a separate helper, as I believe that SCCP should reuse this. --- Zend/Optimizer/pass1.c | 97 +++--------------------- Zend/Optimizer/zend_optimizer.c | 63 +++++++++++++++ Zend/Optimizer/zend_optimizer_internal.h | 2 + 3 files changed, 74 insertions(+), 88 deletions(-) diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 4477a0270a393..4a8f4d4f8ecf9 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -27,7 +27,6 @@ * - pre-evaluate constant function calls */ -#include "php.h" #include "Optimizer/zend_optimizer.h" #include "Optimizer/zend_optimizer_internal.h" #include "zend_API.h" @@ -252,94 +251,16 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } } - /* pre-evaluate constant functions: - constant(x) - function_exists(x) - is_callable(x) - extension_loaded(x) - */ - if (!send2_opline && - Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING) { - if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "function_exists") || - zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "is_callable")) { - zend_internal_function *func; - zend_string *lc_name = zend_string_tolower( - Z_STR(ZEND_OP1_LITERAL(send1_opline))); - - if ((func = zend_hash_find_ptr(EG(function_table), lc_name)) != NULL - && func->type == ZEND_INTERNAL_FUNCTION - && func->module->type == MODULE_PERSISTENT -#ifdef ZEND_WIN32 - && func->module->handle == NULL -#endif - ) { - ZVAL_TRUE(&result); - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - } - zend_string_release_ex(lc_name, 0); - break; - } else if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "extension_loaded")) { - zend_string *lc_name = zend_string_tolower( - Z_STR(ZEND_OP1_LITERAL(send1_opline))); - zend_module_entry *m = zend_hash_find_ptr(&module_registry, - lc_name); - - zend_string_release_ex(lc_name, 0); - if (!m) { - if (PG(enable_dl)) { - break; - } else { - ZVAL_FALSE(&result); - } - } else { - if (m->type == MODULE_PERSISTENT -#ifdef ZEND_WIN32 - && m->handle == NULL -#endif - ) { - ZVAL_TRUE(&result); - } else { - break; - } - } - - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - break; - } else if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "constant")) { - if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(send1_opline)), &result, 1)) { - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - } - break; - /* dirname(IS_CONST/IS_STRING) -> IS_CONST/IS_STRING */ - } else if (zend_string_equals_literal(Z_STR(ZEND_OP2_LITERAL(init_opline)), "dirname") && - IS_ABSOLUTE_PATH(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) { - zend_string *dirname = zend_string_init(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)), 0); - ZSTR_LEN(dirname) = zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname)); - if (IS_ABSOLUTE_PATH(ZSTR_VAL(dirname), ZSTR_LEN(dirname))) { - ZVAL_STR(&result, dirname); - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - replace_by_const_or_qm_assign(op_array, opline, &result); - } else { - zend_string_release_ex(dirname, 0); - } - break; - } + if (!send2_opline && Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING && + zend_optimizer_eval_special_func_call(&result, Z_STR(ZEND_OP2_LITERAL(init_opline)), Z_STR(ZEND_OP1_LITERAL(send1_opline))) == SUCCESS) { + literal_dtor(&ZEND_OP2_LITERAL(init_opline)); + MAKE_NOP(init_opline); + literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); + MAKE_NOP(send1_opline); + replace_by_const_or_qm_assign(op_array, opline, &result); + break; } + /* don't collect constants after any other function call */ collect_constants = 0; break; diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index f8aee5148cbeb..fd04a8bffb13c 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -30,6 +30,7 @@ #include "zend_call_graph.h" #include "zend_inference.h" #include "zend_dump.h" +#include "php.h" #ifndef ZEND_OPTIMIZER_MAX_REGISTERED_PASSES # define ZEND_OPTIMIZER_MAX_REGISTERED_PASSES 32 @@ -121,6 +122,68 @@ zend_result zend_optimizer_eval_strlen(zval *result, zval *op1) /* {{{ */ } /* }}} */ +zend_result zend_optimizer_eval_special_func_call( + zval *result, zend_string *name, zend_string *arg) { + if (zend_string_equals_literal(name, "function_exists") || + zend_string_equals_literal(name, "is_callable")) { + zend_string *lc_name = zend_string_tolower(arg); + zend_internal_function *func = zend_hash_find_ptr(EG(function_table), lc_name); + zend_string_release_ex(lc_name, 0); + + if (func && func->type == ZEND_INTERNAL_FUNCTION + && func->module->type == MODULE_PERSISTENT +#ifdef ZEND_WIN32 + && func->module->handle == NULL +#endif + ) { + ZVAL_TRUE(result); + return SUCCESS; + } + return FAILURE; + } + if (zend_string_equals_literal(name, "extension_loaded")) { + zend_string *lc_name = zend_string_tolower(arg); + zend_module_entry *m = zend_hash_find_ptr(&module_registry, lc_name); + zend_string_release_ex(lc_name, 0); + + if (!m) { + if (PG(enable_dl)) { + return FAILURE; + } + ZVAL_FALSE(result); + return SUCCESS; + } + + if (m->type == MODULE_PERSISTENT +#ifdef ZEND_WIN32 + && m->handle == NULL +#endif + ) { + ZVAL_TRUE(result); + return SUCCESS; + } + return FAILURE; + } + if (zend_string_equals_literal(name, "constant")) { + return zend_optimizer_get_persistent_constant(arg, result, 1) ? SUCCESS : FAILURE; + } + if (zend_string_equals_literal(name, "dirname")) { + if (!IS_ABSOLUTE_PATH(ZSTR_VAL(arg), ZSTR_LEN(arg))) { + return FAILURE; + } + + zend_string *dirname = zend_string_init(ZSTR_VAL(arg), ZSTR_LEN(arg), 0); + ZSTR_LEN(dirname) = zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname)); + if (IS_ABSOLUTE_PATH(ZSTR_VAL(dirname), ZSTR_LEN(dirname))) { + ZVAL_STR(result, dirname); + return SUCCESS; + } + zend_string_release_ex(dirname, 0); + return FAILURE; + } + return FAILURE; +} + bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) { zval *val; diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h index 0116e1506000d..25d021fa98ce9 100644 --- a/Zend/Optimizer/zend_optimizer_internal.h +++ b/Zend/Optimizer/zend_optimizer_internal.h @@ -84,6 +84,8 @@ zend_result zend_optimizer_eval_binary_op(zval *result, zend_uchar opcode, zval zend_result zend_optimizer_eval_unary_op(zval *result, zend_uchar opcode, zval *op1); zend_result zend_optimizer_eval_cast(zval *result, uint32_t type, zval *op1); zend_result zend_optimizer_eval_strlen(zval *result, zval *op1); +zend_result zend_optimizer_eval_special_func_call( + zval *result, zend_string *name, zend_string *arg); bool zend_optimizer_update_op1_const(zend_op_array *op_array, zend_op *opline, zval *val); From e45653c08993ff55a46e9d0cee0ddc7da8f722e4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 26 Dec 2021 10:36:29 +0100 Subject: [PATCH 004/227] Make sure SCCP can evaluate all functions pass1 can Move evaluation of ini_get() into eval_special_func_call() and use this helper both in pass1 and sccp. --- Zend/Optimizer/sccp.c | 24 +++--------------------- Zend/Optimizer/zend_optimizer.c | 13 +++++++++++++ 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index df323b9000075..56c4d24d9bfe8 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -785,27 +785,9 @@ static inline zend_result ct_eval_func_call( return FAILURE; } - if (num_args == 1) { - /* Handle a few functions for which we manually implement evaluation here. */ - if (zend_string_equals_literal(name, "ini_get")) { - zend_ini_entry *ini_entry; - - if (Z_TYPE_P(args[0]) != IS_STRING) { - return FAILURE; - } - - ini_entry = zend_hash_find_ptr(EG(ini_directives), Z_STR_P(args[0])); - if (!ini_entry) { - ZVAL_FALSE(result); - } else if (ini_entry->modifiable != ZEND_INI_SYSTEM) { - return FAILURE; - } else if (ini_entry->value) { - ZVAL_STR_COPY(result, ini_entry->value); - } else { - ZVAL_EMPTY_STRING(result); - } - return SUCCESS; - } + if (num_args == 1 && Z_TYPE_P(args[0]) == IS_STRING && + zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) { + return SUCCESS; } if (!can_ct_eval_func_call(func, name, num_args, args)) { diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index fd04a8bffb13c..9048f0c045109 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -181,6 +181,19 @@ zend_result zend_optimizer_eval_special_func_call( zend_string_release_ex(dirname, 0); return FAILURE; } + if (zend_string_equals_literal(name, "ini_get")) { + zend_ini_entry *ini_entry = zend_hash_find_ptr(EG(ini_directives), arg); + if (!ini_entry) { + ZVAL_FALSE(result); + } else if (ini_entry->modifiable != ZEND_INI_SYSTEM) { + return FAILURE; + } else if (ini_entry->value) { + ZVAL_STR_COPY(result, ini_entry->value); + } else { + ZVAL_EMPTY_STRING(result); + } + return SUCCESS; + } return FAILURE; } From e76ddbd2f6b42e2824da4478392f98a300ab18ab Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 25 Dec 2021 23:04:39 +0100 Subject: [PATCH 005/227] Prevent strict interpretation of tentative definition This header declaration is never supposed to be interpreted as definition; otherwise, the handlers are not properly initialized, what happens, for instance, with ASan instrumented MSVC builds. Closes GH-7827. --- ext/com_dotnet/php_com_dotnet_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index e80bf6e3126eb..eec92fcb86a17 100644 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -72,7 +72,7 @@ zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_entry, * zend_object* php_com_object_new(zend_class_entry *ce); zend_object* php_com_object_clone(zend_object *object); void php_com_object_free_storage(zend_object *object); -zend_object_handlers php_com_object_handlers; +extern zend_object_handlers php_com_object_handlers; void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable); /* com_saproxy.c */ From eac50a360f1e50ab68f68776010697a61398d1bc Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Sun, 5 Dec 2021 19:58:12 +0200 Subject: [PATCH 006/227] Implement fast text conversion interface for Big5 --- ext/mbstring/libmbfl/filters/mbfilter_big5.c | 80 +++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index 2ba32ee04563d..826c979d4136b 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -33,6 +33,8 @@ #include "unicode_table_big5.h" static int mbfl_filt_conv_big5_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_big5_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_big5(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_big5[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -64,8 +66,8 @@ const mbfl_encoding mbfl_encoding_big5 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_big5_wchar, &vtbl_wchar_big5, - NULL, - NULL + mb_big5_to_wchar, + mb_wchar_to_big5 }; const mbfl_encoding mbfl_encoding_cp950 = { @@ -380,3 +382,77 @@ int mbfl_filt_conv_wchar_big5(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_big5_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c <= 0x7F) { + *out++ = c; + } else if (c > 0xA0 && c <= 0xF9 && c != 0xC8 && p < e) { + unsigned char c2 = *p++; + + if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0xA1 && c2 <= 0xFE)) { + unsigned int w = ((c - 0xA1)*157) + c2 - ((c2 <= 0x7E) ? 0x40 : 0xA1 - 0x3F); + w = (w < big5_ucs_table_size) ? big5_ucs_table[w] : 0; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_big5(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_big5_table_min && w < ucs_a1_big5_table_max) { + s = ucs_a1_big5_table[w - ucs_a1_big5_table_min]; + } else if (w >= ucs_a2_big5_table_min && w < ucs_a2_big5_table_max) { + s = ucs_a2_big5_table[w - ucs_a2_big5_table_min]; + } else if (w >= ucs_a3_big5_table_min && w < ucs_a3_big5_table_max) { + s = ucs_a3_big5_table[w - ucs_a3_big5_table_min]; + } else if (w >= ucs_i_big5_table_min && w < ucs_i_big5_table_max) { + s = ucs_i_big5_table[w - ucs_i_big5_table_min]; + } else if (w >= ucs_r1_big5_table_min && w < ucs_r1_big5_table_max) { + s = ucs_r1_big5_table[w - ucs_r1_big5_table_min]; + } else if (w >= ucs_r2_big5_table_min && w < ucs_r2_big5_table_max) { + s = ucs_r2_big5_table[w - ucs_r2_big5_table_min]; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_big5); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s <= 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From da58d42d94ca85269e4f05bd944782f2b0a541b4 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 6 Dec 2021 10:38:07 +0200 Subject: [PATCH 007/227] Implement fast text conversion interface for CP950 --- ext/mbstring/libmbfl/filters/mbfilter_big5.c | 188 ++++++++++++++++++- 1 file changed, 186 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index 826c979d4136b..7d389efc79e91 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -35,6 +35,8 @@ static int mbfl_filt_conv_big5_wchar_flush(mbfl_convert_filter *filter); static size_t mb_big5_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static void mb_wchar_to_big5(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static size_t mb_cp950_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp950(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_big5[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -79,8 +81,8 @@ const mbfl_encoding mbfl_encoding_cp950 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp950_wchar, &vtbl_wchar_cp950, - NULL, - NULL + mb_cp950_to_wchar, + mb_wchar_to_cp950 }; const struct mbfl_convert_vtbl vtbl_big5_wchar = { @@ -456,3 +458,185 @@ static void mb_wchar_to_big5(uint32_t *in, size_t len, mb_convert_buf *buf, bool MB_CONVERT_BUF_STORE(buf, out, limit); } + +static size_t mb_cp950_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c <= 0x7F) { + *out++ = c; + } else if (c > 0x80 && c <= 0xFE && p < e) { + unsigned char c2 = *p++; + + if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0xA1 && c2 <= 0xFE)) { + unsigned int w = ((c - 0xA1)*157) + c2 - ((c2 <= 0x7E) ? 0x40 : 0xA1 - 0x3F); + w = (w < big5_ucs_table_size) ? big5_ucs_table[w] : 0; + + /* PUA for CP950 */ + if (is_in_cp950_pua(c, c2)) { + unsigned int s = (c << 8) | c2; + + int k; + for (k = 0; k < sizeof(cp950_pua_tbl) / (sizeof(unsigned short)*4); k++) { + if (s >= cp950_pua_tbl[k][2] && s <= cp950_pua_tbl[k][3]) { + break; + } + } + + if ((cp950_pua_tbl[k][2] & 0xFF) == 0x40) { + w = 157*(c - (cp950_pua_tbl[k][2] >> 8)) + c2 - (c2 >= 0xA1 ? 0x62 : 0x40) + cp950_pua_tbl[k][0]; + } else { + w = s - cp950_pua_tbl[k][2] + cp950_pua_tbl[k][0]; + } + } else if (c == 0xA1) { + if (c2 == 0x45) { + w = 0x2027; + } else if (c2 == 0x4E) { + w = 0xFE51; + } else if (c2 == 0x5A) { + w = 0x2574; + } else if (c2 == 0xC2) { + w = 0x00AF; + } else if (c2 == 0xC3) { + w = 0xFFE3; + } else if (c2 == 0xC5) { + w = 0x02CD; + } else if (c2 == 0xE3) { + w = 0xFF5E; + } else if (c2 == 0xF2) { + w = 0x2295; + } else if (c2 == 0xF3) { + w = 0x2299; + } else if (c2 == 0xFE) { + w = 0xFF0F; + } + } else if (c == 0xA2) { + if (c2 == 0x40) { + w = 0xFF3C; + } else if (c2 == 0x41) { + w = 0x2215; + } else if (c2 == 0x42) { + w = 0xFE68; + } else if (c2 == 0x46) { + w = 0xFFE0; + } else if (c2 == 0x47) { + w = 0xFFE1; + } else if (c2 == 0xCC) { + w = 0x5341; + } else if (c2 == 0xCE) { + w = 0x5345; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp950(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_big5_table_min && w < ucs_a1_big5_table_max) { + s = ucs_a1_big5_table[w - ucs_a1_big5_table_min]; + } else if (w >= ucs_a2_big5_table_min && w < ucs_a2_big5_table_max) { + s = ucs_a2_big5_table[w - ucs_a2_big5_table_min]; + } else if (w >= ucs_a3_big5_table_min && w < ucs_a3_big5_table_max) { + s = ucs_a3_big5_table[w - ucs_a3_big5_table_min]; + } else if (w >= ucs_i_big5_table_min && w < ucs_i_big5_table_max) { + s = ucs_i_big5_table[w - ucs_i_big5_table_min]; + } else if (w >= ucs_r1_big5_table_min && w < ucs_r1_big5_table_max) { + s = ucs_r1_big5_table[w - ucs_r1_big5_table_min]; + } else if (w >= ucs_r2_big5_table_min && w < ucs_r2_big5_table_max) { + s = ucs_r2_big5_table[w - ucs_r2_big5_table_min]; + } + + if (w >= 0xE000 && w <= 0xF848) { + int k; + for (k = 0; k < sizeof(cp950_pua_tbl) / (sizeof(unsigned short)*4); k++) { + if (w <= cp950_pua_tbl[k][1]) { + break; + } + } + + int c1 = w - cp950_pua_tbl[k][0]; + if ((cp950_pua_tbl[k][2] & 0xFF) == 0x40) { + int c2 = cp950_pua_tbl[k][2] >> 8; + s = ((c1 / 157) + c2) << 8; + c1 %= 157; + s |= c1 + (c1 >= 0x3F ? 0x62 : 0x40); + } else { + s = c1 + cp950_pua_tbl[k][2]; + } + } else if (w == 0xA2 || w == 0xA3 || w == 0x401 || (w >= 0x414 && w <= 0x41C) || (w >= 0x423 && w <= 0x44F) || w == 0x451 || w == 0x2022 || w == 0x203E || w == 0x223C || (w >= 0x2460 && w <= 0x247D) || w == 0x2609 || w == 0x2641 || w == 0x3005 || (w >= 0x302A && w <= 0x30FF) || w == 0xFF64) { + s = 0; + } else if (w == 0xAF) { + s = 0xA1C2; + } else if (w == 0x2CD) { + s = 0xA1C5; + } else if (w == 0x2027) { + s = 0xA145; + } else if (w == 0x2215) { + s = 0xA241; + } else if (w == 0x2295) { + s = 0xA1F2; + } else if (w == 0x2299) { + s = 0xA1F3; + } else if (w == 0x2574) { + s = 0xA15A; + } else if (w == 0xFE51) { + s = 0xA14E; + } else if (w == 0xFE68) { + s = 0xA242; + } else if (w == 0xFF3C) { + s = 0xA240; + } else if (w == 0xFF5E) { + s = 0xA1E3; + } else if (w == 0xFFE0) { + s = 0xA246; + } else if (w == 0xFFE1) { + s = 0xA247; + } else if (w == 0xFFE3) { + s = 0xA1C3; + } else if (w == 0xFF0F) { + s = 0xA1FE; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_big5); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s <= 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 40809cb19f060320b5ac7275e69e10e007c8c5d4 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 6 Dec 2021 15:28:07 +0200 Subject: [PATCH 008/227] Implement fast text conversion interface for HZ --- ext/mbstring/libmbfl/filters/mbfilter_hz.c | 156 ++++++++++++++++++++- ext/mbstring/tests/hz_encoding.phpt | 12 ++ 2 files changed, 166 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_hz.c b/ext/mbstring/libmbfl/filters/mbfilter_hz.c index 3370cd93ef88b..e10109bc33d8f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_hz.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_hz.c @@ -34,6 +34,8 @@ #include "unicode_table_gb2312.h" static int mbfl_filt_conv_hz_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_hz_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_hz(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); const mbfl_encoding mbfl_encoding_hz = { mbfl_no_encoding_hz, @@ -44,8 +46,8 @@ const mbfl_encoding mbfl_encoding_hz = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_hz_wchar, &vtbl_wchar_hz, - NULL, - NULL + mb_hz_to_wchar, + mb_wchar_to_hz }; const struct mbfl_convert_vtbl vtbl_hz_wchar = { @@ -250,3 +252,153 @@ int mbfl_filt_conv_any_hz_flush(mbfl_convert_filter *filter) filter->status = 0; return 0; } + +#define ASCII 0 +#define GB2312 1 + +static size_t mb_hz_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c == '~') { + if (p == e) { + break; + } + unsigned char c2 = *p++; + + if (c2 == '}' && *state == GB2312) { + *state = ASCII; + } else if (c2 == '{' && *state == ASCII) { + *state = GB2312; + } else if (c2 == '~' && *state == ASCII) { + *out++ = '~'; + } else if (c2 == '\n') { + /* "~\n" is a line continuation; no output is needed, nor should we shift modes */ + } else { + /* Invalid character after ~ */ + *out++ = MBFL_BAD_INPUT; + } + } else if (((c > 0x20 && c <= 0x29) || (c >= 0x30 && c <= 0x77)) && p < e && *state == GB2312) { + unsigned char c2 = *p++; + + if (c > 0x20 && c < 0x7F && c2 > 0x20 && c2 < 0x7F) { + unsigned int s = (c - 1)*192 + c2 + 0x40; + ZEND_ASSERT(s < cp936_ucs_table_size); + + if (s == 0x1864) { + s = 0x30FB; + } else if (s == 0x186A) { + s = 0x2015; + } else if (s == 0x186C) { + s = 0x2225; + } else if ((s >= 0x1920 && s <= 0x192A) || s == 0x1963 || (s >= 0x1C60 && s <= 0x1C7F) || (s >= 0x1DBB && s <= 0x1DC4)) { + s = 0; + } else { + s = cp936_ucs_table[s]; + } + if (!s) + s = MBFL_BAD_INPUT; + *out++ = s; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c < 0x80 && *state == ASCII) { + *out++ = c; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_hz(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + if (w == 0xB7 || w == 0x144 || w == 0x148 || w == 0x251 || w == 0x261 || w == 0x2CA || w == 0x2CB || w == 0x2D9) { + s = 0; + } else { + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + if (w == 0x2015) { + s = 0xA1AA; + } else if (w == 0x2010 || w == 0x2013 || w == 0x2014 || w == 0x2016 || w == 0x2025 || w == 0x2035 || w == 0x2105 || w == 0x2109 || w == 0x2121 || (w >= 0x2170 && w <= 0x2179) || (w >= 0x2196 && w <= 0x2199) || w == 0x2215 || w == 0x221F || w == 0x2223 || w == 0x2252 || w == 0x2266 || w == 0x2267 || w == 0x2295 || (w >= 0x2550 && w <= 0x2573) || w == 0x22BF || w == 0x2609 || (w >= 0x2581 && w <= 0x258F) || (w >= 0x2593 && w <= 0x2595) || w == 0x25BC || w == 0x25BD || (w >= 0x25E2 && w <= 0x25E5)) { + s = 0; + } else { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + if (w == 0x30FB) { + s = 0xA1A4; + } else if (w == 0x3006 || w == 0x3007 || w == 0x3012 || w == 0x3231 || w == 0x32A3 || w >= 0x3300 || (w >= 0x3018 && w <= 0x3040) || (w >= 0x309B && w <= 0x309E) || (w >= 0x30FC && w <= 0x30FE)) { + s = 0; + } else { + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } + } else if (w >= ucs_i_gb2312_table_min && w < ucs_i_gb2312_table_max) { + s = ucs_i_gb2312_table[w - ucs_i_gb2312_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w == 0xFFE0 || w == 0xFFE1 || w == 0xFFE3 || w == 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } + + s &= ~0x8080; + + if ((!s && w) || (s >= 0x80 && s < 0x2121)) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_hz); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s < 0x80) { + /* ASCII */ + if (buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, '~', '}'); + buf->state = ASCII; + } + if (s == '~') { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, '~', '~'); + } else { + out = mb_convert_buf_add(out, s); + } + } else { + /* GB 2312-80 */ + if (buf->state != GB2312) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, '~', '{'); + buf->state = GB2312; + } + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0x7F, s & 0x7F); + } + } + + if (end && buf->state != ASCII) { + /* If not in ASCII state, need to emit closing control chars */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, 2); + out = mb_convert_buf_add2(out, '~', '}'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/tests/hz_encoding.phpt b/ext/mbstring/tests/hz_encoding.phpt index 665980c9c7f16..a763fe828563f 100644 --- a/ext/mbstring/tests/hz_encoding.phpt +++ b/ext/mbstring/tests/hz_encoding.phpt @@ -118,6 +118,18 @@ while (!empty($badChars)) { echo "Tested UTF-16BE -> HZ (for all GB2312 characters)\n"; +// Regression tests +if (mb_convert_encoding("\x7A\xFA\x00\x00", 'HZ', 'UTF-16BE') !== "~{\x73\x43~}\x00") + die("Bad"); +if (mb_convert_encoding("~", 'UTF-16BE', 'HZ') !== "") + die("Bad"); +// There had once been a bug whereby the output buffer would be overrun by one byte. +// It was found by fuzzing. Reproducing it required a string which was long enough +// and had a GB2312 character at the end. +$str = "\xD9\x96C\xA7\x1B\xF6\xD8\x86\x94\xB0\xA0\xE1\x9D\x8C\xF8G\xBBMk\xD2Y\tt\xF1\x96d\x17JA\xF9\xF8\xCF\xDC\xFE\x8E\x0E\xC1\x84\xDA\xDBM\xC1\x87\x1AZ\xD5\xA6)\xFF%2\\\xCC\x02\x16]Y\xF0\x00\xEA\xE8{)\x81\xD5VQZ\x12\xB5\xBC\x9A\x91\xA0x\x02\xBA\xF6c\xACo\x9BH\xB7qx\xF5\x0F\t\x15\xDByx\xBA[\xC9\xE8r\xCD*:\xBF\x10P\xF1>Q\x07\xEE\xE5\x80\xAD\xB9\xA2\x9B\xF6\xE1,\x82\xC6q\x94E\xD4\x0B\xC6\xBCQe=\xC3\xE0\xC8\xE0R\x97\x14q\x0C\x1A\x7F\xE1\xC4\xB8U\x8A\x86\x93\xB6/\x84\x95\x06\x91W\xB2\xB6\x1F!\t X\x1A\xD5\xD6\xDA<\x81ib\x9A\x1B3\xD3\xB7:\xE2QS\xD0\x91\x99[K\xF2E\xBBjoh_5\x15 \xA4\xCC\xB0\x7F\x06\xB3,\xB3\xA7u\xB9\x82\x00\xE2f$\x1C\x84NsP\xFAiPB{\x8D\xBA\xB3[\x88\xA9\xB1\xA2r\x86\xFF<\xFD\xFB\xF8\xD6\xABq\x00z\xFA\x87\x8C_\xD9N\xF2\xFA\xEA\xEA\xAA\xD7\xFA\xA2\xD4\x85/\xFC\xE1}\xF7\x9C\x86\xDD\x12@\xC3\xDA\nC\x1Di\xA9\xB0\xC3\xB3\x04\xB2\x1A\x07BA\x02\xED\x11\xA4\xDAz\x96\xB5\xD0!p\xE2\xAD\xEDI\xEF\xF7\\\x05d.p\x07\xC4\x8B\x952\xCDz\x90\x8C\xA6U\xDB\xC7\xF4\x94\xE9\x16X\xF1\xCC\xB13\x07a9\x86]\xF9k\xA9\x87E\xCB\x89\x9Fd\x0E\x81m\xC6c\xDA\x9C\xE9\xAF\x80.\xFAq\xD9\xAAd\x1DB\x1F\x854\xE8\x82v)A\xF3\xB4\x1D\xE5\xF0\xFFu\x0E\x0C\xC4q\xF0\xE7\xB4p\x86\xE6]9\xD9\xA5O\xBAw\x1B\x8D&]\x9D\xE2\x0F\xD2\xD5\x13AY#\x81\x90\xB2\xE8\xDA\xD2\xFC>\xA0\x9A\xBD\x0B\xCC\x08>\x1E\xD1\xFEgr1'$\xEE\xA2!\x8A\xBB>\x11j#Pz_!?\xA8\x15\xCF\xCB\x84\x86\xC1\xF78:\xDA\xBCE\xA7\x02SO\x8B\x81>\x96\xBD\xFD2\x84\xC5\xFC\x19\xE5\xF4\xEFp\xF08K\xBB\xAE-[}\xE1\xDB\x8A%6\xC7\xC9"; +if (substr(mb_convert_encoding($str, 'HZ', 'CP51932'), -4) !== "\x45\x49~}") + die("Bad"); + // Test "long" illegal character markers mb_substitute_character("long"); convertInvalidString("~A", "%", "HZ", "UTF-8"); From c0936d48b08406ebde35e4b53bc0c10c54acd6df Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Tue, 7 Dec 2021 08:59:26 +0200 Subject: [PATCH 009/227] Implement fast text conversion interface for UHC --- ext/mbstring/libmbfl/filters/mbfilter_uhc.c | 94 ++++++++++++++++++++- ext/mbstring/tests/uhc_encoding.phpt | 3 + 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c index e465fbe2b4d4e..bec134aabd2aa 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c @@ -37,6 +37,8 @@ #include "unicode_table_uhc.h" static int mbfl_filt_conv_uhc_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_uhc_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_uhc(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_uhc[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -68,8 +70,8 @@ const mbfl_encoding mbfl_encoding_uhc = { 0, &vtbl_uhc_wchar, &vtbl_wchar_uhc, - NULL, - NULL + mb_uhc_to_wchar, + mb_wchar_to_uhc }; const struct mbfl_convert_vtbl vtbl_uhc_wchar = { @@ -192,3 +194,91 @@ int mbfl_filt_conv_wchar_uhc(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_uhc_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c > 0x80 && c < 0xFE && c != 0xC9 && p < e) { + unsigned char c2 = *p++; + unsigned int w = 0; + + if (c >= 0x81 && c <= 0xA0 && c2 >= 0x41 && c2 <= 0xFE) { + w = (c - 0x81)*190 + (c2 - 0x41); + if (w < uhc1_ucs_table_size) { + w = uhc1_ucs_table[w]; + } + } else if (c >= 0xA1 && c <= 0xC6 && c2 >= 0x41 && c2 <= 0xFE) { + w = (c - 0xA1)*190 + (c2 - 0x41); + if (w < uhc2_ucs_table_size) { + w = uhc2_ucs_table[w]; + } + } else if (c >= 0xC7 && c < 0xFE && c2 >= 0xA1 && c2 <= 0xFE) { + w = (c - 0xC7)*94 + (c2 - 0xA1); + if (w < uhc3_ucs_table_size) { + w = uhc3_ucs_table[w]; + } + } + if (!w) { + w = MBFL_BAD_INPUT; + } + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_uhc(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_uhc_table_min && w < ucs_a1_uhc_table_max) { + s = ucs_a1_uhc_table[w - ucs_a1_uhc_table_min]; + } else if (w >= ucs_a2_uhc_table_min && w < ucs_a2_uhc_table_max) { + s = ucs_a2_uhc_table[w - ucs_a2_uhc_table_min]; + } else if (w >= ucs_a3_uhc_table_min && w < ucs_a3_uhc_table_max) { + s = ucs_a3_uhc_table[w - ucs_a3_uhc_table_min]; + } else if (w >= ucs_i_uhc_table_min && w < ucs_i_uhc_table_max) { + s = ucs_i_uhc_table[w - ucs_i_uhc_table_min]; + } else if (w >= ucs_s_uhc_table_min && w < ucs_s_uhc_table_max) { + s = ucs_s_uhc_table[w - ucs_s_uhc_table_min]; + } else if (w >= ucs_r1_uhc_table_min && w < ucs_r1_uhc_table_max) { + s = ucs_r1_uhc_table[w - ucs_r1_uhc_table_min]; + } else if (w >= ucs_r2_uhc_table_min && w < ucs_r2_uhc_table_max) { + s = ucs_r2_uhc_table[w - ucs_r2_uhc_table_min]; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_uhc); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/tests/uhc_encoding.phpt b/ext/mbstring/tests/uhc_encoding.phpt index cc4d72f9f11ea..622569c68c699 100644 --- a/ext/mbstring/tests/uhc_encoding.phpt +++ b/ext/mbstring/tests/uhc_encoding.phpt @@ -11,6 +11,9 @@ if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); include('encoding_tests.inc'); testEncodingFromUTF16ConversionTable(__DIR__ . '/data/CP949.txt', 'UHC'); +// Regression test +convertInvalidString("\xE4\xA4\xB4<", "\x75\x1A\x00%", "UHC", "UTF-16BE"); + // Test "long" illegal character markers mb_substitute_character("long"); convertInvalidString("\x80", "%", "UHC", "UTF-8"); From 43bb97c539a787a335755b4f92fdde84a9a7ff8d Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Tue, 7 Dec 2021 10:47:31 +0200 Subject: [PATCH 010/227] Implement fast text conversion interface for EUC-KR --- .../libmbfl/filters/mbfilter_euc_kr.c | 95 ++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c index 70c4e3f9d5949..fd7bb3b9f7c1e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c @@ -32,6 +32,8 @@ #include "unicode_table_uhc.h" static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_euckr_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_euckr(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_euckr[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -63,8 +65,8 @@ const mbfl_encoding mbfl_encoding_euc_kr = { 0, &vtbl_euckr_wchar, &vtbl_wchar_euckr, - NULL, - NULL + mb_euckr_to_wchar, + mb_wchar_to_euckr }; const struct mbfl_convert_vtbl vtbl_euckr_wchar = { @@ -200,3 +202,92 @@ static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter) return 0; } + +static size_t mb_euckr_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (((c >= 0xA1 && c <= 0xAC) || (c >= 0xB0 && c <= 0xFD)) && c != 0xC9 && p < e) { + unsigned char c2 = *p++; + + if (c >= 0xA1 && c <= 0xC6 && c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0xA1)*190 + c2 - 0x41; + ZEND_ASSERT(w < uhc2_ucs_table_size); + w = uhc2_ucs_table[w]; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else if (c >= 0xC7 && c <= 0xFE && c != 0xC9 && c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0xC7)*94 + c2 - 0xA1; + ZEND_ASSERT(w < uhc3_ucs_table_size); + w = uhc3_ucs_table[w]; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_euckr(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_uhc_table_min && w < ucs_a1_uhc_table_max) { + s = ucs_a1_uhc_table[w - ucs_a1_uhc_table_min]; + } else if (w >= ucs_a2_uhc_table_min && w < ucs_a2_uhc_table_max) { + s = ucs_a2_uhc_table[w - ucs_a2_uhc_table_min]; + } else if (w >= ucs_a3_uhc_table_min && w < ucs_a3_uhc_table_max) { + s = ucs_a3_uhc_table[w - ucs_a3_uhc_table_min]; + } else if (w >= ucs_i_uhc_table_min && w < ucs_i_uhc_table_max) { + s = ucs_i_uhc_table[w - ucs_i_uhc_table_min]; + } else if (w >= ucs_s_uhc_table_min && w < ucs_s_uhc_table_max) { + s = ucs_s_uhc_table[w - ucs_s_uhc_table_min]; + } else if (w >= ucs_r1_uhc_table_min && w < ucs_r1_uhc_table_max) { + s = ucs_r1_uhc_table[w - ucs_r1_uhc_table_min]; + } else if (w >= ucs_r2_uhc_table_min && w < ucs_r2_uhc_table_max) { + s = ucs_r2_uhc_table[w - ucs_r2_uhc_table_min]; + } + + /* Exclude UHC extension area (although we are using the UHC conversion tables) */ + if (((s >> 8) & 0xFF) < 0xA1 || (s & 0xFF) < 0xA1) { + s = 0; + } + + if (!s) { + if (w < 0x80) { + out = mb_convert_buf_add(out, w); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euckr); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 20555371d5733e97023919d4911ac5f52b005a1d Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Thu, 9 Dec 2021 16:51:11 +0200 Subject: [PATCH 011/227] Implement fast text conversion interface for CP932 --- ext/mbstring/libmbfl/filters/mbfilter_cp932.c | 154 +++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c index 06ac6b22b26f2..ef7c47e967415 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c @@ -34,6 +34,8 @@ #include "unicode_table_jis.h" static int mbfl_filt_conv_cp932_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_cp932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_sjis[] = { /* 0x80-0x9f,0xE0-0xFF */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -65,8 +67,8 @@ const mbfl_encoding mbfl_encoding_cp932 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp932_wchar, &vtbl_wchar_cp932, - NULL, - NULL + mb_cp932_to_wchar, + mb_wchar_to_cp932 }; const struct mbfl_convert_vtbl vtbl_cp932_wchar = { @@ -310,3 +312,151 @@ mbfl_filt_conv_wchar_cp932(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_cp932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c > 0xA0 && c < 0xE0) { + /* Kana */ + *out++ = 0xFEC0 + c; + } else if (c > 0x80 && c < 0xFD && c != 0xA0 && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0x40 && c2 <= 0xFC && c2 != 0x7F) { + unsigned int s1, s2, w = 0; + SJIS_DECODE(c, c2, s1, s2); + unsigned int s = (s1 - 0x21)*94 + s2 - 0x21; + + if (s <= 137) { + if (s == 31) { + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + } else if (s == 32) { + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s == 33) { + w = 0x2225; /* PARALLEL TO */ + } else if (s == 60) { + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ + } else if (s == 80) { + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ + } else if (s == 81) { + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ + } else if (s == 137) { + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ + } + } + + if (w == 0) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { + w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; + } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { + w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; + } else if (s >= (94*94) && s < (114*94)) { + w = s - (94*94) + 0xE000; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s1 = 0, s2 = 0, c1, c2; + + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s1 = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s1 = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s1 = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s1 = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } else if (w >= 0xE000 && w < (0xE000 + 20*94)) { + s1 = w - 0xE000; + c1 = s1/94 + 0x7f; + c2 = s1%94 + 0x21; + s1 = (c1 << 8) | c2; + s2 = 1; + } + + if (w == 0xA5) { /* YEN SIGN */ + s1 = 0x216F; /* FULLWIDTH YEN SIGN */ + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s1 = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s1 = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s1 = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s1 = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s1 = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s1 = 0x224C; + } else if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } + + if (!s1 || (s1 >= 0x8080 && !s2)) { /* not found or X 0212 */ + for (unsigned int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (cp932ext1_ucs_table[i] == w) { + s1 = ((i/94 + 0x2D) << 8) + (i%94 + 0x21); + goto emit_output; + } + } + + for (unsigned int i = 0; i < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; i++) { + if (cp932ext3_ucs_table[i] == w) { + s1 = ((i/94 + 0x93) << 8) + (i%94 + 0x21); + goto emit_output; + } + } + + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp932); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + continue; + } + +emit_output: + if (s1 < 0x100) { + out = mb_convert_buf_add(out, s1); + } else { + c1 = (s1 >> 8) & 0xFF; + c2 = s1 & 0xFF; + SJIS_ENCODE(c1, c2, s1, s2); + out = mb_convert_buf_add2(out, s1, s2); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 661a10160b8fece3117e518f7e5250303c17fdbc Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Thu, 9 Dec 2021 20:44:39 +0200 Subject: [PATCH 012/227] Implement fast text conversion interface for CP936 --- ext/mbstring/libmbfl/filters/mbfilter_cp936.c | 164 +++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c index f12523dedca2a..5591608afa87d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c @@ -33,6 +33,9 @@ #include "unicode_table_cp936.h" static int mbfl_filt_conv_cp936_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_cp936_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp936(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); + static const unsigned char mblen_table_cp936[] = { /* 0x81-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -64,8 +67,8 @@ const mbfl_encoding mbfl_encoding_cp936 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp936_wchar, &vtbl_wchar_cp936, - NULL, - NULL + mb_cp936_to_wchar, + mb_wchar_to_cp936 }; const struct mbfl_convert_vtbl vtbl_cp936_wchar = { @@ -267,3 +270,160 @@ int mbfl_filt_conv_wchar_cp936(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_cp936_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c == 0x80) { + *out++ = 0x20AC; /* Euro sign */ + } else if (c < 0xFF) { + if (p >= e) { + *out++ = MBFL_BAD_INPUT; + continue; + } + + unsigned char c2 = *p++; + + if (((c >= 0xAA && c <= 0xAF) || (c >= 0xF8 && c <= 0xFE)) && (c2 >= 0xA1 && c2 <= 0xFE)) { + /* UDA part 1, 2: U+E000-U+E4C5 */ + *out++ = 94*(c >= 0xF8 ? c - 0xF2 : c - 0xAA) + (c2 - 0xA1) + 0xE000; + } else if (c >= 0xA1 && c <= 0xA7 && c2 >= 0x40 && c2 < 0xA1 && c2 != 0x7F) { + /* UDA part 3: U+E4C6-U+E765*/ + *out++ = 96*(c - 0xA1) + c2 - (c2 >= 0x80 ? 0x41 : 0x40) + 0xE4C6; + } else { + unsigned int w = (c << 8) | c2; + + if ((w >= 0xA2AB && w <= 0xA9FE) || (w >= 0xD7FA && w <= 0xD7FE) || (w >= 0xFE50 && w <= 0xFEA0)) { + for (int k = 0; k < mbfl_cp936_pua_tbl_max; k++) { + if (w >= mbfl_cp936_pua_tbl[k][2] && w <= mbfl_cp936_pua_tbl[k][2] + mbfl_cp936_pua_tbl[k][1] - mbfl_cp936_pua_tbl[k][0]) { + *out++ = w - mbfl_cp936_pua_tbl[k][2] + mbfl_cp936_pua_tbl[k][0]; + goto next_iteration; + } + } + } + + if (c < 0xFF && c > 0x80 && c2 >= 0x40 && c2 < 0xFF && c2 != 0x7F) { + w = (c - 0x81)*192 + c2 - 0x40; + ZEND_ASSERT(w < cp936_ucs_table_size); + *out++ = cp936_ucs_table[w]; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + } else { + *out++ = 0xF8F5; + } +next_iteration: ; + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp936(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + /* U+0000-U+0451 */ + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + /* U+2000-U+26FF */ + if (w == 0x203E) { + s = 0xA3FE; + } else if (w == 0x2218) { + s = 0xA1E3; + } else if (w == 0x223C) { + s = 0xA1AB; + } else { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + /* U+2F00-U+33FF */ + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } else if (w >= ucs_i_cp936_table_min && w < ucs_i_cp936_table_max) { + /* U+4D00-9FFF CJK Unified Ideographs (+ Extension A) */ + s = ucs_i_cp936_table[w - ucs_i_cp936_table_min]; + } else if (w >= 0xE000 && w <= 0xE864) { + /* PUA */ + if (w < 0xe766) { + if (w < 0xe4c6) { + unsigned int c1 = w - 0xE000; + s = (c1 % 94) + 0xA1; + c1 /= 94; + s |= (c1 < 0x6 ? c1 + 0xAA : c1 + 0xF2) << 8; + } else { + unsigned int c1 = w - 0xE4C6; + s = ((c1 / 96) + 0xA1) << 8; + c1 %= 96; + s |= c1 + (c1 >= 0x3F ? 0x41 : 0x40); + } + } else { + /* U+E766-U+E864 */ + unsigned int k1 = 0; + unsigned int k2 = mbfl_cp936_pua_tbl_max; + while (k1 < k2) { + int k = (k1 + k2) >> 1; + if (w < mbfl_cp936_pua_tbl[k][0]) { + k2 = k; + } else if (w > mbfl_cp936_pua_tbl[k][1]) { + k1 = k + 1; + } else { + s = w - mbfl_cp936_pua_tbl[k][0] + mbfl_cp936_pua_tbl[k][2]; + break; + } + } + } + } else if (w == 0xF8F5) { + s = 0xFF; + } else if (w >= ucs_ci_cp936_table_min && w < ucs_ci_cp936_table_max) { + /* U+F900-U+FA2F CJK Compatibility Ideographs */ + s = ucs_ci_cp936_table[w - ucs_ci_cp936_table_min]; + } else if (w >= ucs_cf_cp936_table_min && w < ucs_cf_cp936_table_max) { + s = ucs_cf_cp936_table[w - ucs_cf_cp936_table_min]; + } else if (w >= ucs_sfv_cp936_table_min && w < ucs_sfv_cp936_table_max) { + /* U+FE50-U+FE6F Small Form Variants */ + s = ucs_sfv_cp936_table[w - ucs_sfv_cp936_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + /* U+FF00-U+FFFF HW/FW Forms */ + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w >= 0xFFE0 && w <= 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp936); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } + } else if (s <= 0x80 || s == 0xFF) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 9bd08a97d98161396d9f07d32d6da366b01174d0 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 10 Dec 2021 11:34:44 +0200 Subject: [PATCH 013/227] Implement fast text conversion interface for EUC-TW --- .../libmbfl/filters/mbfilter_euc_tw.c | 123 +++++++++++++++++- 1 file changed, 121 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c index f505ca17a3923..571b711bdf6c7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c @@ -33,6 +33,8 @@ #include "unicode_table_cns11643.h" static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_euctw_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_euctw(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_euctw[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -65,8 +67,8 @@ const mbfl_encoding mbfl_encoding_euc_tw = { 0, &vtbl_euctw_wchar, &vtbl_wchar_euctw, - NULL, - NULL + mb_euctw_to_wchar, + mb_wchar_to_euctw }; const struct mbfl_convert_vtbl vtbl_euctw_wchar = { @@ -252,3 +254,120 @@ static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter) return 0; } + +static size_t mb_euctw_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (((c >= 0xA1 && c <= 0xA6) || (c >= 0xC2 && c <= 0xFD)) && c != 0xC3 && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0xA1)*94 + (c2 - 0xA1); + if (w < cns11643_1_ucs_table_size) { + w = cns11643_1_ucs_table[w]; + } else { + w = 0; + } + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8E && p < e) { + unsigned char c2 = *p++; + + if ((c2 == 0xA1 || c2 == 0xA2 || c2 == 0xAE) && p < e) { + unsigned int plane = c2 - 0xA1; /* This is actually the CNS-11643 plane minus one */ + unsigned char c3 = *p++; + + if (c3 >= 0xA1 && ((plane == 0 && ((c3 >= 0xA1 && c3 <= 0xA6) || (c3 >= 0xC2 && c3 <= 0xFD)) && c3 != 0xC3) || (plane == 1 && c3 <= 0xF2) || (plane == 13 && c3 <= 0xE7)) && p < e) { + unsigned char c4 = *p++; + + if (c2 <= 0xAE && c4 > 0xA0 && c4 < 0xFF) { + unsigned int s = (c3 - 0xA1)*94 + c4 - 0xA1, w = 0; + + /* A later version of CNS-11643 moved all the characters in "plane 14" to "plane 3", + * and added tens of thousands more characters in planes 4, 5, 6, and 7 + * We only support the older version of CNS-11643 + * This is the same as iconv from glibc 2.2 */ + if (plane == 0 && s < cns11643_1_ucs_table_size) { + w = cns11643_1_ucs_table[s]; + } else if (plane == 1 && s < cns11643_2_ucs_table_size) { + w = cns11643_2_ucs_table[s]; + } else if (plane == 13 && s < cns11643_14_ucs_table_size) { + w = cns11643_14_ucs_table[s]; + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + continue; + } + } + } + + *out++ = MBFL_BAD_INPUT; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_euctw(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cns11643_table_min && w < ucs_a1_cns11643_table_max) { + s = ucs_a1_cns11643_table[w - ucs_a1_cns11643_table_min]; + } else if (w >= ucs_a2_cns11643_table_min && w < ucs_a2_cns11643_table_max) { + s = ucs_a2_cns11643_table[w - ucs_a2_cns11643_table_min]; + } else if (w >= ucs_a3_cns11643_table_min && w < ucs_a3_cns11643_table_max) { + s = ucs_a3_cns11643_table[w - ucs_a3_cns11643_table_min]; + } else if (w >= ucs_i_cns11643_table_min && w < ucs_i_cns11643_table_max) { + s = ucs_i_cns11643_table[w - ucs_i_cns11643_table_min]; + } else if (w >= ucs_r_cns11643_table_min && w < ucs_r_cns11643_table_max) { + s = ucs_r_cns11643_table[w - ucs_r_cns11643_table_min]; + } + + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euctw); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } + } else { + unsigned int plane = s >> 16; + if (plane <= 1) { + if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add4(out, 0x8E, 0xA0 + plane, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 6ef1b35223f46c0a41be025462fcbe9ea8e9324e Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 10 Dec 2021 13:41:17 +0200 Subject: [PATCH 014/227] Implement fast text conversion interface for EUC-CN --- .../libmbfl/filters/mbfilter_euc_cn.c | 110 +++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c index 0465a814ff3d8..f179d602505a2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c @@ -33,6 +33,8 @@ #include "unicode_table_cp936.h" static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_euccn_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_euccn(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_euccn[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -64,8 +66,8 @@ const mbfl_encoding mbfl_encoding_euc_cn = { 0, &vtbl_euccn_wchar, &vtbl_wchar_euccn, - NULL, - NULL + mb_euccn_to_wchar, + mb_wchar_to_euccn }; const struct mbfl_convert_vtbl vtbl_euccn_wchar = { @@ -216,3 +218,107 @@ static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter) return 0; } + +static size_t mb_euccn_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (((c >= 0xA1 && c <= 0xA9) || (c >= 0xB0 && c <= 0xF7)) && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int w = (c - 0x81)*192 + c2 - 0x40; + ZEND_ASSERT(w < cp936_ucs_table_size); + if (w == 0x1864) { + w = 0x30FB; + } else if (w == 0x186A) { + w = 0x2015; + } else if ((w >= 0x1921 && w <= 0x192A) || w == 0x1963 || (w >= 0x1C59 && w <= 0x1C7E) || (w >= 0x1DBB && w <= 0x1DC4)) { + w = 0; + } else { + w = cp936_ucs_table[w]; + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_euccn(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + if (w != 0xB7 && w != 0x144 && w != 0x148 && w != 0x251 && w != 0x261) { + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + if (w == 0x2015) { + s = 0xA1AA; + } else if (w != 0x2014 && (w < 0x2170 || w > 0x2179)) { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + if (w == 0x30FB) { + s = 0xA1A4; + } else { + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } + } else if (w >= ucs_i_cp936_table_min && w < ucs_i_cp936_table_max) { + s = ucs_i_cp936_table[w - ucs_i_cp936_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w >= 0xFFE0 && w <= 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } + + /* Exclude CP936 extensions */ + if (((s >> 8) & 0xFF) < 0xA1 || (s & 0xFF) < 0xA1) { + s = 0; + } + + if (!s) { + if (w < 0x80) { + out = mb_convert_buf_add(out, w); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euccn); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From e5af94b74fbd8fa1c0bc3aad19114549f1ce1d31 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 10 Dec 2021 15:54:53 +0200 Subject: [PATCH 015/227] Implement fast text conversion interface for CP51932 --- .../libmbfl/filters/mbfilter_cp51932.c | 145 +++++++++++++++++- 1 file changed, 143 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c index 2f7193462e025..7d1a739f3369e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c @@ -35,6 +35,8 @@ #include "cp932_table.h" static int mbfl_filt_conv_cp51932_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_cp51932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp51932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_eucjp[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -66,8 +68,8 @@ const mbfl_encoding mbfl_encoding_cp51932 = { 0, &vtbl_cp51932_wchar, &vtbl_wchar_cp51932, - NULL, - NULL + mb_cp51932_to_wchar, + mb_wchar_to_cp51932 }; const struct mbfl_convert_vtbl vtbl_cp51932_wchar = { @@ -267,3 +269,142 @@ mbfl_filt_conv_wchar_cp51932(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_cp51932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c >= 0xA1 && c <= 0xFE && p < e) { + unsigned char c2 = *p++; + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int s = (c - 0xA1)*94 + c2 - 0xA1, w = 0; + + if (s <= 137) { + if (s == 31) { + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + } else if (s == 32) { + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s == 33) { + w = 0x2225; /* PARALLEL TO */ + } else if (s == 60) { + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ + } else if (s == 80) { + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ + } else if (s == 81) { + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ + } else if (s == 137) { + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ + } + } + + if (w == 0) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { + w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8E && p < e) { + unsigned char c2 = *p++; + if (c2 >= 0xA1 && c2 <= 0xDF) { + *out++ = 0xFEC0 + c2; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_cp51932(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } else if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } + + if (s >= 0x8080) s = 0; /* We don't support JIS X0213 */ + + if (s == 0) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x216F; /* FULLWIDTH YEN SIGN */ + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else { + for (int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (cp932ext1_ucs_table[i] == w) { + s = ((i/94 + 0x2D) << 8) + (i%94) + 0x21; + goto found_it; + } + } + + for (int i = 0; i < cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; i++) { + if (cp932ext2_ucs_table[i] == w) { + s = ((i/94 + 0x79) << 8) + (i%94) + 0x21; + goto found_it; + } + } + } +found_it: ; + } + + if (!s || s >= 0x8080) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp51932); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s < 0x100) { + out = mb_convert_buf_add2(out, 0x8E, s); + } else { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 3e8088dc80f85355b4a336cc3ef7ebb662d2d073 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Sat, 11 Dec 2021 23:19:10 +0200 Subject: [PATCH 016/227] Implement fast text conversion interface for EUC-JP-MS --- .../libmbfl/filters/mbfilter_euc_jp_win.c | 199 +++++++++++++++++- 1 file changed, 197 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c index 49e7f9dccd279..4845abda5c280 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c @@ -35,6 +35,8 @@ #include "cp932_table.h" static int mbfl_filt_conv_eucjpwin_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_eucjpwin_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_eucjpwin(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const unsigned char mblen_table_eucjp[] = { /* 0xA1-0xFE */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -66,8 +68,8 @@ const mbfl_encoding mbfl_encoding_eucjp_win = { 0, &vtbl_eucjpwin_wchar, &vtbl_wchar_eucjpwin, - NULL, - NULL + mb_eucjpwin_to_wchar, + mb_wchar_to_eucjpwin }; const struct mbfl_convert_vtbl vtbl_eucjpwin_wchar = { @@ -337,3 +339,196 @@ int mbfl_filt_conv_wchar_eucjpwin(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_eucjpwin_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c >= 0xA1 && c <= 0xFE && p < e) { + unsigned char c2 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE) { + unsigned int s = (c - 0xA1)*94 + c2 - 0xA1, w = 0; + + if (s <= 137) { + if (s == 31) { + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + } else if (s == 32) { + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s == 33) { + w = 0x2225; /* PARALLEL TO */ + } else if (s == 60) { + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ + } else if (s == 80) { + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ + } else if (s == 81) { + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ + } else if (s == 137) { + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ + } + } + + if (w == 0) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= (84 * 94)) { + w = s - (84 * 94) + 0xE000; + } + } + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8E && p < e) { + unsigned char c2 = *p++; + if (c2 >= 0xA1 && c2 <= 0xDF) { + *out++ = 0xFEC0 + c2; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c == 0x8F && p < e) { + unsigned char c2 = *p++; + if (p == e) { + *out++ = MBFL_BAD_INPUT; + continue; + } + unsigned char c3 = *p++; + + if (c2 >= 0xA1 && c2 <= 0xFE && c3 >= 0xA1 && c3 <= 0xFE) { + unsigned int s = (c2 - 0xA1)*94 + c3 - 0xA1, w = 0; + + if (s < jisx0212_ucs_table_size) { + w = jisx0212_ucs_table[s]; + if (w == 0x7E) + w = 0xFF5E; /* FULLWIDTH TILDE */ + } else if (s >= (82*94) && s < (84*94)) { + s = (c2 << 8) | c3; + for (int i = 0; i < cp932ext3_eucjp_table_size; i++) { + if (cp932ext3_eucjp_table[i] == s) { + w = cp932ext3_ucs_table[i]; + break; + } + } + } else if (s >= (84*94)) { + w = s - (84*94) + 0xE000 + (94*10); + } + + if (w == 0xA6) + w = 0xFFE4; /* FULLWIDTH BROKEN BAR */ + + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_eucjpwin(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } else if (w == 0xAF) { /* U+00AF is MACRON */ + s = 0xA2B4; /* Use JIS X 0212 overline */ + } else if (w == 0x203E) { + s = 0x7E; + } else if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } else if (w >= 0xE000 && w < (0xE000 + 10*94)) { + s = w - 0xE000; + s = ((s/94 + 0x75) << 8) + (s%94) + 0x21; + } else if (w >= (0xE000 + 10*94) && w < (0xE000 + 20*94)) { + s = w - (0xE000 + 10*94); + s = ((s/94 + 0xF5) << 8) + (s%94) + 0xA1; + } + + if (s == 0xA2F1) + s = 0x2D62; /* NUMERO SIGN */ + + if (s == 0) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x5C; + } else if (w == 0x2014) { /* EM DASH */ + s = 0x213D; + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else { + for (int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (cp932ext1_ucs_table[i] == w) { + s = (((i/94) + (cp932ext1_ucs_table_min/94) + 0x21) << 8) + (i%94) + 0x21; + break; + } + } + + if (!s) { + for (int i = 0; i < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; i++) { + if (cp932ext3_ucs_table[i] == w) { + s = cp932ext3_eucjp_table[i]; + break; + } + } + } + } + } + + if (!s) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_eucjpwin); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s < 0x100) { + out = mb_convert_buf_add2(out, 0x8E, s); + } else if (s < 0x8080) { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 3); + out = mb_convert_buf_add3(out, 0x8F, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From cb4626c5b212e80c3fa5e3a55b7673285458df41 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Sun, 12 Dec 2021 15:56:57 +0200 Subject: [PATCH 017/227] Implement fast text conversion interface for GB18030 --- .../libmbfl/filters/mbfilter_gb18030.c | 232 +++++++++++++++++- 1 file changed, 230 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c index 00494daf358f0..b86b8315a560f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c @@ -34,6 +34,8 @@ #include "unicode_table_gb18030.h" static int mbfl_filt_conv_gb18030_wchar_flush(mbfl_convert_filter *filter); +static size_t mb_gb18030_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_gb18030(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); static const char *mbfl_encoding_gb18030_aliases[] = {"gb-18030", "gb-18030-2000", NULL}; @@ -46,8 +48,8 @@ const mbfl_encoding mbfl_encoding_gb18030 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_gb18030_wchar, &vtbl_wchar_gb18030, - NULL, - NULL + mb_gb18030_to_wchar, + mb_wchar_to_gb18030 }; const struct mbfl_convert_vtbl vtbl_gb18030_wchar = { @@ -382,3 +384,229 @@ int mbfl_filt_conv_wchar_gb18030(int c, mbfl_convert_filter *filter) return 0; } + +static size_t mb_gb18030_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c < 0x80) { + *out++ = c; + } else if (c > 0x80 && c < 0xFF && p < e) { + unsigned char c2 = *p++; + unsigned int s = (c << 8) | c2; + + if (((c >= 0x81 && c <= 0x84) || (c >= 0x90 && c <= 0xE3)) && c2 >= 0x30 && c2 <= 0x39) { + if (p >= e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c3 = *p++; + + if (c3 >= 0x81 && c3 <= 0xFE && p < e) { + unsigned char c4 = *p++; + + if (c4 >= 0x30 && c4 <= 0x39) { + if (c >= 0x90 && c <= 0xE3) { + unsigned int w = ((((c - 0x90)*10 + (c2 - 0x30))*126 + (c3 - 0x81)))*10 + (c4 - 0x30) + 0x10000; + *out++ = (w > 0x10FFFF) ? MBFL_BAD_INPUT : w; + } else { + /* Unicode BMP */ + unsigned int w = (((c - 0x81)*10 + (c2 - 0x30))*126 + (c3 - 0x81))*10 + (c4 - 0x30); + if (w <= 39419) { + *out++ = w + mbfl_gb_uni_ofst[mbfl_bisec_srch(w, mbfl_gb2uni_tbl, mbfl_gb_uni_max)]; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (((c >= 0xAA && c <= 0xAF) || (c >= 0xF8 && c <= 0xFE)) && (c2 >= 0xA1 && c2 <= 0xFE)) { + /* UDA part 1, 2: U+E000-U+E4C5 */ + *out++ = 94*(c >= 0xF8 ? c - 0xF2 : c - 0xAA) + (c2 - 0xA1) + 0xE000; + } else if (c >= 0xA1 && c <= 0xA7 && c2 >= 0x40 && c2 < 0xA1 && c2 != 0x7F) { + /* UDA part 3: U+E4C6-U+E765 */ + *out++ = 96*(c - 0xA1) + c2 - (c2 >= 0x80 ? 0x41 : 0x40) + 0xE4C6; + } else { + if ((s >= 0xA2AB && s <= 0xA9FE) || (s >= 0xD7FA && s <= 0xD7FE) || (s >= 0xFE50 && s <= 0xFEA0)) { + for (int i = 0; i < mbfl_gb18030_pua_tbl_max; i++) { + if (s >= mbfl_gb18030_pua_tbl[i][2] && s <= mbfl_gb18030_pua_tbl[i][2] + mbfl_gb18030_pua_tbl[i][1] - mbfl_gb18030_pua_tbl[i][0]) { + *out++ = s - mbfl_gb18030_pua_tbl[i][2] + mbfl_gb18030_pua_tbl[i][0]; + goto next_iteration; + } + } + } + + if ((c >= 0xA1 && c <= 0xA9 && c2 >= 0xA1 && c2 <= 0xFE) || + (c >= 0xB0 && c <= 0xf7 && c2 >= 0xa1 && c2 <= 0xfe) || + (c >= 0x81 && c <= 0xa0 && c2 >= 0x40 && c2 <= 0xfe && c2 != 0x7f) || + (c >= 0xAA && c <= 0xfe && c2 >= 0x40 && c2 <= 0xa0 && c2 != 0x7f) || + (c >= 0xA8 && c <= 0xa9 && c2 >= 0x40 && c2 <= 0xa0 && c2 != 0x7F)) { + unsigned int w = (c - 0x81)*192 + c2 - 0x40; + ZEND_ASSERT(w < cp936_ucs_table_size); + *out++ = cp936_ucs_table[w]; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + } else { + *out++ = MBFL_BAD_INPUT; + } +next_iteration: ; + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static void mb_wchar_to_gb18030(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w == 0) { + out = mb_convert_buf_add(out, 0); + continue; + } else if (w >= ucs_a1_cp936_table_min && w < ucs_a1_cp936_table_max) { + if (w == 0x1F9) { + s = 0xA8Bf; + } else { + s = ucs_a1_cp936_table[w - ucs_a1_cp936_table_min]; + } + } else if (w >= ucs_a2_cp936_table_min && w < ucs_a2_cp936_table_max) { + if (w == 0x20AC) { /* Euro sign */ + s = 0xA2E3; + } else { + s = ucs_a2_cp936_table[w - ucs_a2_cp936_table_min]; + } + } else if (w >= ucs_a3_cp936_table_min && w < ucs_a3_cp936_table_max) { + s = ucs_a3_cp936_table[w - ucs_a3_cp936_table_min]; + } else if (w >= ucs_i_cp936_table_min && w < ucs_i_cp936_table_max) { + s = ucs_i_cp936_table[w - ucs_i_cp936_table_min]; + } else if (w >= ucs_ci_cp936_table_min && w < ucs_ci_cp936_table_max) { + /* U+F900-U+FA2F CJK Compatibility Ideographs */ + if (w == 0xF92C) { + s = 0xFD9C; + } else if (w == 0xF979) { + s = 0xFD9D; + } else if (w == 0xF995) { + s = 0xFD9E; + } else if (w == 0xF9E7) { + s = 0xFD9F; + } else if (w == 0xF9F1) { + s = 0xFDA0; + } else if (w >= 0xFA0C && w <= 0xFA29) { + s = ucs_ci_s_cp936_table[w - 0xFA0C]; + } + } else if (w >= ucs_cf_cp936_table_min && w < ucs_cf_cp936_table_max) { + /* CJK Compatibility Forms */ + s = ucs_cf_cp936_table[w - ucs_cf_cp936_table_min]; + } else if (w >= ucs_sfv_cp936_table_min && w < ucs_sfv_cp936_table_max) { + /* U+FE50-U+FE6F Small Form Variants */ + s = ucs_sfv_cp936_table[w - ucs_sfv_cp936_table_min]; + } else if (w >= ucs_hff_cp936_table_min && w < ucs_hff_cp936_table_max) { + /* U+FF00-U+FFFF HW/FW Forms */ + if (w == 0xFF04) { + s = 0xA1E7; + } else if (w == 0xFF5E) { + s = 0xA1AB; + } else if (w >= 0xFF01 && w <= 0xFF5D) { + s = w - 0xFF01 + 0xA3A1; + } else if (w >= 0xFFE0 && w <= 0xFFE5) { + s = ucs_hff_s_cp936_table[w - 0xFFE0]; + } + } else if (w >= 0xE000 && w <= 0xE864) { + /* PUA */ + if (w < 0xE766) { + if (w < 0xE4C6) { + unsigned int c1 = w - 0xE000; + s = (c1 % 94) + 0xA1; + c1 /= 94; + s |= (c1 + (c1 < 0x06 ? 0xAA : 0xF2)) << 8; + } else { + unsigned int c1 = w - 0xE4C6; + s = ((c1 / 96) + 0xA1) << 8; + c1 %= 96; + s |= c1 + (c1 >= 0x3F ? 0x41 : 0x40); + } + } else { + /* U+E766-U+E864 */ + unsigned int k1 = 0, k2 = mbfl_gb18030_pua_tbl_max; + while (k1 < k2) { + unsigned int k = (k1 + k2) >> 1; + if (w < mbfl_gb18030_pua_tbl[k][0]) { + k2 = k; + } else if (w > mbfl_gb18030_pua_tbl[k][1]) { + k1 = k + 1; + } else { + s = w - mbfl_gb18030_pua_tbl[k][0] + mbfl_gb18030_pua_tbl[k][2]; + break; + } + } + } + } + + /* While GB18030 and CP936 are very similar, some mappings are different between these encodings; + * do a binary search in a table of differing codepoints to see if we have one */ + if (!s && w >= mbfl_gb18030_c_tbl_key[0] && w <= mbfl_gb18030_c_tbl_key[mbfl_gb18030_c_tbl_max-1]) { + int i = mbfl_bisec_srch2(w, mbfl_gb18030_c_tbl_key, mbfl_gb18030_c_tbl_max); + if (i >= 0) { + s = mbfl_gb18030_c_tbl_val[i]; + } + } + + /* If we have not yet found a suitable mapping for this codepoint, it requires a 4-byte code */ + if (!s && w >= 0x80 && w <= 0xFFFF) { + /* BMP */ + int i = mbfl_bisec_srch(w, mbfl_uni2gb_tbl, mbfl_gb_uni_max); + if (i >= 0) { + unsigned int c1 = w - mbfl_gb_uni_ofst[i]; + s = (c1 % 10) + 0x30; + c1 /= 10; + s |= ((c1 % 126) + 0x81) << 8; + c1 /= 126; + s |= ((c1 % 10) + 0x30) << 16; + c1 /= 10; + s |= (c1 + 0x81) << 24; + } + } else if (w >= 0x10000 && w <= 0x10FFFF) { + /* Code set 3: Unicode U+10000-U+10FFFF */ + unsigned int c1 = w - 0x10000; + s = (c1 % 10) + 0x30; + c1 /= 10; + s |= ((c1 % 126) + 0x81) << 8; + c1 /= 126; + s |= ((c1 % 10) + 0x30) << 16; + c1 /= 10; + s |= (c1 + 0x90) << 24; + } + + if (!s) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_gb18030); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s > 0xFFFFFF) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + out = mb_convert_buf_add4(out, (s >> 24) & 0xFF, (s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 01afd9f14169b66bc936bae3761b568fad109204 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 13 Dec 2021 15:41:25 +0200 Subject: [PATCH 018/227] Implement fast text conversion interface for JIS --- ext/mbstring/libmbfl/filters/mbfilter_jis.c | 86 ++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_jis.c b/ext/mbstring/libmbfl/filters/mbfilter_jis.c index b175743a4afbe..3b7f1f8586fa0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_jis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_jis.c @@ -36,6 +36,7 @@ static int mbfl_filt_conv_jis_wchar_flush(mbfl_convert_filter *filter); static size_t mb_iso2022jp_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static void mb_wchar_to_iso2022jp(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static void mb_wchar_to_jis(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); const mbfl_encoding mbfl_encoding_jis = { mbfl_no_encoding_jis, @@ -47,7 +48,7 @@ const mbfl_encoding mbfl_encoding_jis = { &vtbl_jis_wchar, &vtbl_wchar_jis, mb_iso2022jp_to_wchar, - NULL + mb_wchar_to_jis, }; const mbfl_encoding mbfl_encoding_2022jp = { @@ -667,3 +668,86 @@ static void mb_wchar_to_iso2022jp(uint32_t *in, size_t len, mb_convert_buf *buf, MB_CONVERT_BUF_STORE(buf, out, limit); } + +static void mb_wchar_to_jis(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; + + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w == 0x203E) { /* OVERLINE */ + s = 0x1007E; /* Convert to JISX 0201 OVERLINE */ + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } + + if (s == 0) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x1005C; + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else if (w != 0) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_iso2022jp); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + continue; + } + } + + if (s < 0x80) { /* ASCII */ + if (buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s < 0x8080) { /* JIS X 0208 */ + if (buf->state != JISX_0208) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 5); + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0x7F, s & 0x7F); + } else if (s < 0x10000) { /* JIS X 0212 */ + if (buf->state != JISX_0212) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 6); + out = mb_convert_buf_add4(out, 0x1B, '$', '(', 'D'); + buf->state = JISX_0212; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0x7F, s & 0x7F); + } else { /* X 0201 Latin */ + if (buf->state != JISX_0201_LATIN) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } + } + + if (end && buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} From 53ffba967cc517315e2b102f601c35998db7d615 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 20 Dec 2021 22:03:02 +0200 Subject: [PATCH 019/227] Implement fast text conversion interface for CP5022{0,1,2} --- .../libmbfl/filters/mbfilter_cp5022x.c | 413 +++++++++++++++++- ext/mbstring/tests/cp5022x_encoding.phpt | 5 + 2 files changed, 412 insertions(+), 6 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index a67b538bb4311..18686e8bf1ed1 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -35,6 +35,10 @@ static int mbfl_filt_conv_cp5022x_wchar_flush(mbfl_convert_filter *filter); static int mbfl_filt_conv_wchar_cp50220_flush(mbfl_convert_filter *filter); static int mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter); static int mbfl_filt_conv_wchar_cp50220(int c, mbfl_convert_filter *filter); +static size_t mb_cp5022x_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); +static void mb_wchar_to_cp50220(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static void mb_wchar_to_cp50221(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); +static void mb_wchar_to_cp50222(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); /* Previously, a dubious 'encoding' called 'cp50220raw' was supported * This was just CP50220, but the implementation was less strict regarding @@ -56,8 +60,8 @@ const mbfl_encoding mbfl_encoding_cp50220 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp50220_wchar, &vtbl_wchar_cp50220, - NULL, - NULL + mb_cp5022x_to_wchar, + mb_wchar_to_cp50220 }; const mbfl_encoding mbfl_encoding_cp50221 = { @@ -69,8 +73,8 @@ const mbfl_encoding mbfl_encoding_cp50221 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp50221_wchar, &vtbl_wchar_cp50221, - NULL, - NULL + mb_cp5022x_to_wchar, + mb_wchar_to_cp50221 }; const mbfl_encoding mbfl_encoding_cp50222 = { @@ -82,8 +86,8 @@ const mbfl_encoding mbfl_encoding_cp50222 = { MBFL_ENCTYPE_GL_UNSAFE, &vtbl_cp50222_wchar, &vtbl_wchar_cp50222, - NULL, - NULL + mb_cp5022x_to_wchar, + mb_wchar_to_cp50222 }; const struct mbfl_convert_vtbl vtbl_cp50220_wchar = { @@ -627,3 +631,400 @@ static int mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter) return 0; } + +#define ASCII 0 +#define JISX_0201_LATIN 1 +#define JISX_0201_KANA 2 +#define JISX_0208 3 +#define JISX_0212 4 + +static size_t mb_cp5022x_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) +{ + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; + + while (p < e && out < limit) { + unsigned char c = *p++; + + if (c == 0x1B) { + /* Escape sequence */ + if ((e - p) < 2) { + *out++ = MBFL_BAD_INPUT; + /* Duplicate error-handling behavior of legacy code */ + if (p < e && (*p == '(' || *p == '$')) + p++; + continue; + } + unsigned char c2 = *p++; + if (c2 == '$') { + unsigned char c3 = *p++; + if (c3 == '@' || c3 == 'B') { + *state = JISX_0208; + } else if (c3 == '(') { + if (p == e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c4 = *p++; + if (c4 == '@' || c4 == 'B') { + *state = JISX_0208; + } else if (c4 == 'D') { + *state = JISX_0212; + } else { + if ((limit - out) < 3) { + p -= 4; + break; + } + *out++ = MBFL_BAD_INPUT; + *out++ = '$'; + *out++ = '('; + p--; + } + } else { + if ((limit - out) < 2) { + p -= 3; + break; + } + *out++ = MBFL_BAD_INPUT; + *out++ = '$'; + p--; + } + } else if (c2 == '(') { + unsigned char c3 = *p++; + if (c3 == 'B' || c3 == 'H') { + *state = ASCII; + } else if (c3 == 'J') { + *state = JISX_0201_LATIN; + } else if (c3 == 'I') { + *state = JISX_0201_KANA; + } else { + if ((limit - out) < 2) { + p -= 3; + break; + } + *out++ = MBFL_BAD_INPUT; + *out++ = '('; + p--; + } + } else { + *out++ = MBFL_BAD_INPUT; + p--; + } + } else if (c == 0xE) { + *state = JISX_0201_KANA; + } else if (c == 0xF) { + *state = ASCII; + } else if (*state == JISX_0201_LATIN && c == 0x5C) { /* YEN SIGN */ + *out++ = 0xA5; + } else if (*state == JISX_0201_LATIN && c == 0x7E) { /* OVER LINE */ + *out++ = 0x203E; + } else if (*state == JISX_0201_KANA && c > 0x20 && c < 0x60) { + *out++ = 0xFF40 + c; + } else if (*state >= JISX_0208 && c > 0x20 && c <= 0x97) { + if (p == e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c2 = *p++; + if (c2 > 0x20 && c2 < 0x7F) { + unsigned int s = (c - 0x21)*94 + c2 - 0x21; + uint32_t w = 0; + if (*state == JISX_0208) { + if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { + w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; + } else if (s < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[s]; + } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { + w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; + } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { + w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; + } else if (s >= 94*94 && s < 114*94) { + /* MicroSoft extension */ + w = s - 94*94 + 0xE000; + } + if (!w) + w = MBFL_BAD_INPUT; + } else { + if (s < jisx0212_ucs_table_size) { + w = jisx0212_ucs_table[s]; + } + if (!w) + w = MBFL_BAD_INPUT; + } + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; + } + } else if (c < 0x80) { + *out++ = c; + } else if (c >= 0xA1 && c <= 0xDF) { + *out++ = 0xFEC0 + c; + } else { + *out++ = MBFL_BAD_INPUT; + } + } + + *in_len = e - p; + *in = p; + return out - buf; +} + +static unsigned int lookup_wchar(uint32_t w) +{ + unsigned int s = 0; + + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; + } else if (w == 0x203E) { /* OVERLINE */ + s = 0x1007E; /* Convert to JISX 0201 OVERLINE */ + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; + } else if (w >= 0xE000 && w <= 0xE757) { + /* Private Use Area codepoints */ + s = w - 0xE000; + s = ((s / 94) + 0x7F) << 8 | ((s % 94) + 0x21); + } + + if (!s) { + if (w == 0xA5) { /* YEN SIGN */ + s = 0x1005C; + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else if (w == 0x2225) { /* PARALLEL TO */ + s = 0x2142; + } else if (w == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s = 0x215D; + } else if (w == 0xFFE0) { /* FULLWIDTH CENT SIGN */ + s = 0x2171; + } else if (w == 0xFFE1) { /* FULLWIDTH POUND SIGN */ + s = 0x2172; + } else if (w == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s = 0x224C; + } else if (w == 0) { + return 0; + } + } + + /* Above, we do a series of lookups in `ucs_*_jis_table` to find a + * corresponding kuten code for this Unicode codepoint + * If we get zero, that means the codepoint is not in JIS X 0208 + * On the other hand, if we get a result with the high bits set on both + * upper and lower bytes, that is not a code in JIS X 0208 but rather + * in JIS X 0213 + * In either case, check if this codepoint is one of the extensions added + * to JIS X 0208 by MicroSoft (to make CP932) */ + if (!s || s >= 0x8080) { + for (int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) { + if (w == cp932ext1_ucs_table[i]) { + return (((i / 94) + (cp932ext1_ucs_table_min / 94) + 0x21) << 8) + (i % 94) + 0x21; + } + } + + for (int i = 0; i < cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; i++) { + if (w == cp932ext2_ucs_table[i]) { + return (((i / 94) + (cp932ext2_ucs_table_min / 94) + 0x21) << 8) + (i % 94) + 0x21; + } + } + } + + return s; +} + +static void mb_wchar_to_cp50220(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + bool consumed = false; + + while (len--) { + uint32_t w = *in++; + + w = mbfl_convert_kana(w, len ? *in : 0, &consumed, NULL, MBFL_HAN2ZEN_KATAKANA | MBFL_HAN2ZEN_GLUE); + + if (consumed) { + /* Two successive codepoints were converted into one */ + in++; len--; consumed = false; + } + + unsigned int s = lookup_wchar(w); + + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } else if (s < 0x80) { + /* ASCII */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != ASCII) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s >= 0xA0 && s < 0xE0) { + /* JISX 0201 Kana */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_KANA) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'I'); + buf->state = JISX_0201_KANA; + } + out = mb_convert_buf_add(out, s - 0x80); + } else if (s <= 0x927E) { + /* JISX 0208 Kanji */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 5); + if (buf->state != JISX_0208) { + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else if (s >= 0x10000) { + /* JISX 0201 Latin; we 'tag' these by adding 0x10000 */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_LATIN) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } + } + + if (end && buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} + +static void mb_wchar_to_cp50221(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = lookup_wchar(w); + + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } else if (s < 0x80) { + /* ASCII */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != ASCII) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s >= 0xA0 && s < 0xE0) { + /* JISX 0201 Kana */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_KANA) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'I'); + buf->state = JISX_0201_KANA; + } + out = mb_convert_buf_add(out, s - 0x80); + } else if (s <= 0x927E) { + /* JISX 0208 Kanji */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 5); + if (buf->state != JISX_0208) { + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else if (s >= 0x10000) { + /* JISX 0201 Latin; we 'tag' these by adding 0x10000 */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state != JISX_0201_LATIN) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50221); + } + } + + if (end && buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} + +static void mb_wchar_to_cp50222(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + + while (len--) { + uint32_t w = *in++; + unsigned int s = lookup_wchar(w); + + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50222); + } else if (s < 0x80) { + /* ASCII */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state == JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xF); + buf->state = ASCII; + } else if (buf->state != ASCII) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + buf->state = ASCII; + } + out = mb_convert_buf_add(out, s); + } else if (s >= 0xA0 && s < 0xE0) { + /* JISX 0201 Kana */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + if (buf->state != JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xE); + buf->state = JISX_0201_KANA; + } + out = mb_convert_buf_add(out, s - 0x80); + } else if (s <= 0x927E) { + /* JISX 0208 Kanji */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 5); + if (buf->state == JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xF); + } + if (buf->state != JISX_0208) { + out = mb_convert_buf_add3(out, 0x1B, '$', 'B'); + buf->state = JISX_0208; + } + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else if (s >= 0x10000) { + /* JISX 0201 Latin; we 'tag' these by adding 0x10000 */ + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + if (buf->state == JISX_0201_KANA) { + out = mb_convert_buf_add(out, 0xF); + } + if (buf->state != JISX_0201_LATIN) { + out = mb_convert_buf_add3(out, 0x1B, '(', 'J'); + buf->state = JISX_0201_LATIN; + } + out = mb_convert_buf_add(out, s & 0x7F); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp50222); + } + } + + if (end) { + if (buf->state == JISX_0201_KANA) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 1); + out = mb_convert_buf_add(out, 0xF); + } else if (buf->state != ASCII) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 3); + out = mb_convert_buf_add3(out, 0x1B, '(', 'B'); + } + } + + MB_CONVERT_BUF_STORE(buf, out, limit); +} diff --git a/ext/mbstring/tests/cp5022x_encoding.phpt b/ext/mbstring/tests/cp5022x_encoding.phpt index 11a4855462a84..cde33e85cc670 100644 --- a/ext/mbstring/tests/cp5022x_encoding.phpt +++ b/ext/mbstring/tests/cp5022x_encoding.phpt @@ -365,6 +365,11 @@ foreach (['CP50220', 'CP50221', 'CP50222'] as $encoding) { } echo "Invalid escape sequences OK\n"; + +// Regression test +if (mb_convert_encoding("\x1BC\xF5", 'UTF-16BE', 'CP50221') !== "\x00%\x00C\x00%") + die("Bad") + ?> --EXPECT-- ASCII support OK From 5005445994ff03e01524cff345e9c0d60027f662 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Dec 2021 13:48:26 +0100 Subject: [PATCH 020/227] Mark curl tests using http2.golang.org as XFAIL http2.golang.org/serverpush has been retired[1], so we need to come up with an alternative. Until then, we mark the relevant tests as XFAIL (although bug77535.phpt passes, what might be an indication that the test needs further revision). To avoid waiting for the timeout, we also unconditionally skip these tests for now. [1] Closes GH-7829. --- ext/curl/tests/bug76675.phpt | 3 +++ ext/curl/tests/bug77535.phpt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ext/curl/tests/bug76675.phpt b/ext/curl/tests/bug76675.phpt index 5d36abfdd671b..c52874a6ed37d 100644 --- a/ext/curl/tests/bug76675.phpt +++ b/ext/curl/tests/bug76675.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #76675 (Segfault with H2 server push write/writeheader handlers) +--XFAIL-- +http2.golang.org/serverpush is gone --SKIPIF-- --FILE-- --FILE-- Date: Sun, 26 Dec 2021 16:49:32 +0100 Subject: [PATCH 021/227] Fix bug40228*.phpt conflict Both tests use the same directory structure; we avoid that by extracting to separate subdirectories. Closes GH-7831. --- ext/zip/tests/bug40228-mb.phpt | 5 +++-- ext/zip/tests/bug40228.phpt | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/zip/tests/bug40228-mb.phpt b/ext/zip/tests/bug40228-mb.phpt index fddfb65f29639..39715a615a02a 100644 --- a/ext/zip/tests/bug40228-mb.phpt +++ b/ext/zip/tests/bug40228-mb.phpt @@ -4,8 +4,8 @@ Bug #40228 (extractTo does not create recursive empty path) --FILE-- open($arc_name, ZIPARCHIVE::CREATE); $zip->extractTo($dest); @@ -13,6 +13,7 @@ if (is_dir($dest . '/test/empty')) { echo "Ok\n"; rmdir($dest . '/test/empty'); rmdir($dest . '/test'); + rmdir($dest); } else { echo "Failed.\n"; } diff --git a/ext/zip/tests/bug40228.phpt b/ext/zip/tests/bug40228.phpt index 49e202c576baf..f9cd20f2439d1 100644 --- a/ext/zip/tests/bug40228.phpt +++ b/ext/zip/tests/bug40228.phpt @@ -4,8 +4,8 @@ Bug #40228 (extractTo does not create recursive empty path) --FILE-- open($arc_name, ZIPARCHIVE::CREATE); $zip->extractTo($dest); @@ -13,6 +13,7 @@ if (is_dir($dest . '/test/empty')) { echo "Ok\n"; rmdir($dest . '/test/empty'); rmdir($dest . '/test'); + rmdir($dest); } else { echo "Failed.\n"; } From 2759e6bc699f1a0fee132e70adc64fbd9295ec03 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 27 Dec 2021 12:02:13 +0300 Subject: [PATCH 022/227] Fixed assertion when check "instanceof" on unlinked class --- Zend/Optimizer/zend_inference.c | 13 ++++++++++++- ext/opcache/tests/opt/inference_003.phpt | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/inference_003.phpt diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 80b01a6db26ac..bf70a2f66cc6a 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -3630,6 +3630,17 @@ static zend_class_entry *join_class_entries( return ce1; } +static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { + if (ce1 == ce2) { + return 1; + } + if (!(ce1->ce_flags & ZEND_ACC_LINKED)) { + /* This case could be generalized, similarly to unlinked_instanceof */ + return 0; + } + return instanceof_function(ce1, ce2); +} + static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_bitset worklist, zend_long optimization_level) { zend_basic_block *blocks = ssa->cfg.blocks; @@ -3661,7 +3672,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend if (!ce) { ce = constraint->ce; is_instanceof = 1; - } else if (is_instanceof && instanceof_function(constraint->ce, ce)) { + } else if (is_instanceof && safe_instanceof(constraint->ce, ce)) { ce = constraint->ce; } else { /* Ignore the constraint (either ce instanceof constraint->ce or diff --git a/ext/opcache/tests/opt/inference_003.phpt b/ext/opcache/tests/opt/inference_003.phpt new file mode 100644 index 0000000000000..046396f212532 --- /dev/null +++ b/ext/opcache/tests/opt/inference_003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Type inference 003: instanceof with unlinked class +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +getMessage()); + } +} +?> +--EXPECTF-- +Fatal error: Uncaught Error: Interface "I" not found in %sinference_003.php:2 +Stack trace: +#0 {main} + thrown in %sinference_003.php on line 2 + From a066b809de7a18c8b35cbe798747f70d63c50ea8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 27 Dec 2021 15:28:46 +0300 Subject: [PATCH 023/227] Skip abstract methods --- Zend/Optimizer/zend_optimizer.c | 1 + ext/opcache/zend_persist.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index 9048f0c045109..0a4111fa4fd33 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -1415,6 +1415,7 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (op_array->scope == ce && op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_foreach_op_array_helper(op_array, func, context); } diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index a572f5e3be87e..2ccfff3d04321 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1262,6 +1262,7 @@ static void zend_accel_persist_class_table(HashTable *class_table) ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (op_array->type == ZEND_USER_FUNCTION) { if (op_array->scope == ce + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { @@ -1276,7 +1277,8 @@ static void zend_accel_persist_class_table(HashTable *class_table) if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION) { + if (op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) { if ((op_array->scope != ce || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC From f82593d597f5d23fadca1ba5e7d076392d11faaf Mon Sep 17 00:00:00 2001 From: David Warner Date: Thu, 23 Dec 2021 22:52:50 +1100 Subject: [PATCH 024/227] Fix GH-7815: php_uname doesn't recognise latest Windows versions We check `dwBuildNumber` to determine newer Windows versions. Closes GH-7816. --- NEWS | 2 ++ ext/standard/info.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index b33abd8be9b3a..ecf24e5d08005 100644 --- a/NEWS +++ b/NEWS @@ -59,6 +59,8 @@ PHP NEWS - Standard: . Fixed bug GH-7748 (gethostbyaddr outputs binary string). (cmb) + . Fixed bug GH-7815 (php_uname doesn't recognise latest Windows versions). + (David Warner) 02 Dec 2021, PHP 8.1.1 diff --git a/ext/standard/info.c b/ext/standard/info.c index 395110d25f218..651bf3ae3f6d7 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -268,11 +268,34 @@ char* php_get_windows_name() if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) { if (osvi.dwMajorVersion == 10) { - if( osvi.dwMinorVersion == 0 ) { - if( osvi.wProductType == VER_NT_WORKSTATION ) { - major = "Windows 10"; + if (osvi.dwMinorVersion == 0) { + if (osvi.wProductType == VER_NT_WORKSTATION) { + if (osvi.dwBuildNumber >= 22000) { + major = "Windows 11"; + } else { + major = "Windows 10"; + } } else { - major = "Windows Server 2016"; + if (osvi.dwBuildNumber >= 20348) { + major = "Windows Server 2022"; + } else if (osvi.dwBuildNumber >= 19042) { + major = "Windows Server, version 20H2"; + } else if (osvi.dwBuildNumber >= 19041) { + major = "Windows Server, version 2004"; + } else if (osvi.dwBuildNumber >= 18363) { + major = "Windows Server, version 1909"; + } else if (osvi.dwBuildNumber >= 18362) { + major = "Windows Server, version 1903"; + } else if (osvi.dwBuildNumber >= 17763) { + // could also be Windows Server, version 1809, but there's no easy way to tell + major = "Windows Server 2019"; + } else if (osvi.dwBuildNumber >= 17134) { + major = "Windows Server, version 1803"; + } else if (osvi.dwBuildNumber >= 16299) { + major = "Windows Server, version 1709"; + } else { + major = "Windows Server 2016"; + } } } } From 71b55d7dd8aae6d5c75dfe19abfae29a4746d334 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 27 Dec 2021 15:17:16 +0100 Subject: [PATCH 025/227] [ci skip] supportedOs Id for Windows 10 and 11 are the same Cf. . --- win32/build/default.manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/build/default.manifest b/win32/build/default.manifest index aa5da5c4d08c4..a73c2fb53d3ab 100644 --- a/win32/build/default.manifest +++ b/win32/build/default.manifest @@ -15,7 +15,7 @@ - + From 76e2a8380e5e030412e9d565955d011972af8418 Mon Sep 17 00:00:00 2001 From: Florian Sowade Date: Thu, 18 Nov 2021 16:16:37 +0100 Subject: [PATCH 026/227] Fix zend_observer_fcall_end_all() accessing dangling pointers This may happen, when the execute_data was allocated on the stack. We ensure that the runtime cache pointer is not NULL before dereferencing it. This is a partial fix for bug 81430. Closes GH-7665. --- NEWS | 2 ++ Zend/zend_observer.c | 1 + ext/zend_test/tests/observer_bug81430_1.phpt | 27 ++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 ext/zend_test/tests/observer_bug81430_1.phpt diff --git a/NEWS b/NEWS index 30f8b64959f5a..cbbd41ab5e1eb 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) + . Fixed zend_observer_fcall_end_all() accessing dangling pointers. (Florian + Sowade) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index b970acd85c8e5..08c09e8ff1773 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -229,6 +229,7 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( zend_execute_data *ex = execute_data->prev_execute_data; while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags) + || !&RUN_TIME_CACHE(&ex->func->op_array) || !ZEND_OBSERVER_DATA(&ex->func->op_array) || ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) { ex = ex->prev_execute_data; diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt new file mode 100644 index 0000000000000..830112b1b5370 --- /dev/null +++ b/ext/zend_test/tests/observer_bug81430_1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #81430 (Attribute instantiation frame has no run time cache) +--INI-- +memory_limit=20M +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +--FILE-- +getAttributes(A::class)[0], 'newInstance']); +?> +--EXPECTF-- + + + + + + From ee610947ce03a5d83447f144886b4d5278e1b47b Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 27 Dec 2021 21:08:51 +0100 Subject: [PATCH 027/227] Revert "Fix zend_observer_fcall_end_all() accessing dangling pointers" This reverts commit 76e2a8380e5e030412e9d565955d011972af8418. Cf. . --- NEWS | 2 -- Zend/zend_observer.c | 1 - ext/zend_test/tests/observer_bug81430_1.phpt | 27 -------------------- 3 files changed, 30 deletions(-) delete mode 100644 ext/zend_test/tests/observer_bug81430_1.phpt diff --git a/NEWS b/NEWS index cbbd41ab5e1eb..30f8b64959f5a 100644 --- a/NEWS +++ b/NEWS @@ -6,8 +6,6 @@ PHP NEWS . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) - . Fixed zend_observer_fcall_end_all() accessing dangling pointers. (Florian - Sowade) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index 08c09e8ff1773..b970acd85c8e5 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -229,7 +229,6 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( zend_execute_data *ex = execute_data->prev_execute_data; while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags) - || !&RUN_TIME_CACHE(&ex->func->op_array) || !ZEND_OBSERVER_DATA(&ex->func->op_array) || ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) { ex = ex->prev_execute_data; diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt deleted file mode 100644 index 830112b1b5370..0000000000000 --- a/ext/zend_test/tests/observer_bug81430_1.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Bug #81430 (Attribute instantiation frame has no run time cache) ---INI-- -memory_limit=20M -zend_test.observer.enabled=1 -zend_test.observer.observe_all=1 ---FILE-- -getAttributes(A::class)[0], 'newInstance']); -?> ---EXPECTF-- - - - - - - From eb43f8a4f81ddd94f9e30f1274f71c5c74869646 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 27 Dec 2021 23:40:21 +0300 Subject: [PATCH 028/227] Eliminate more VERIFY_RETURN_TYPE instructions --- Zend/Optimizer/dfa_pass.c | 54 +++++++++++++++++++++++++++------------ Zend/Optimizer/zend_ssa.c | 40 +++++++++++++++++++++++++++++ Zend/Optimizer/zend_ssa.h | 1 + 3 files changed, 79 insertions(+), 16 deletions(-) diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 0218a77d3f950..114a1b8ce243a 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -1293,30 +1293,52 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx } else if (opline->opcode == ZEND_VERIFY_RETURN_TYPE && opline->op1_type != IS_CONST && ssa->ops[op_1].op1_def == v - && ssa->ops[op_1].op1_use >= 0 - && ssa->ops[op_1].op1_use_chain == -1 - && can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) { + && ssa->ops[op_1].op1_use >= 0) { + int orig_var = ssa->ops[op_1].op1_use; + int ret = ssa->vars[v].use_chain; + + if (ssa->ops[op_1].op1_use_chain == -1 + && can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) { // op_1: VERIFY_RETURN_TYPE #orig_var.? [T] -> #v.? [T] => NOP - int orig_var = ssa->ops[op_1].op1_use; - zend_ssa_unlink_use_chain(ssa, op_1, orig_var); + zend_ssa_unlink_use_chain(ssa, op_1, orig_var); + + if (ret >= 0) { + ssa->ops[ret].op1_use = orig_var; + ssa->ops[ret].op1_use_chain = ssa->vars[orig_var].use_chain; + ssa->vars[orig_var].use_chain = ret; + } + + ssa->vars[v].definition = -1; + ssa->vars[v].use_chain = -1; + + ssa->ops[op_1].op1_def = -1; + ssa->ops[op_1].op1_use = -1; + + MAKE_NOP(opline); + remove_nops = 1; + } else if (ret >= 0 + && ssa->ops[ret].op1_use == v + && ssa->ops[ret].op1_use_chain == -1 + && can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) { + +// op_1: VERIFY_RETURN_TYPE #orig_var.? [T] -> #v.? [T] => NOP + + zend_ssa_replace_use_chain(ssa, op_1, ret, orig_var); - int ret = ssa->vars[v].use_chain; - if (ret >= 0) { ssa->ops[ret].op1_use = orig_var; - ssa->ops[ret].op1_use_chain = ssa->vars[orig_var].use_chain; - ssa->vars[orig_var].use_chain = ret; - } + ssa->ops[ret].op1_use_chain = ssa->ops[op_1].op1_use_chain; - ssa->vars[v].definition = -1; - ssa->vars[v].use_chain = -1; + ssa->vars[v].definition = -1; + ssa->vars[v].use_chain = -1; - ssa->ops[op_1].op1_def = -1; - ssa->ops[op_1].op1_use = -1; + ssa->ops[op_1].op1_def = -1; + ssa->ops[op_1].op1_use = -1; - MAKE_NOP(opline); - remove_nops = 1; + MAKE_NOP(opline); + remove_nops = 1; + } } } diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 98f60468a0e69..2cd1d4276e7fa 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -1209,6 +1209,46 @@ void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var) /* {{{ */ } /* }}} */ +void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var) /* {{{ */ +{ + if (ssa->vars[var].use_chain == op) { + ssa->vars[var].use_chain = new_op; + return; + } else { + int use = ssa->vars[var].use_chain; + + while (use >= 0) { + if (ssa->ops[use].result_use == var) { + if (ssa->ops[use].res_use_chain == op) { + ssa->ops[use].res_use_chain = new_op; + return; + } else { + use = ssa->ops[use].res_use_chain; + } + } else if (ssa->ops[use].op1_use == var) { + if (ssa->ops[use].op1_use_chain == op) { + ssa->ops[use].op1_use_chain = new_op; + return; + } else { + use = ssa->ops[use].op1_use_chain; + } + } else if (ssa->ops[use].op2_use == var) { + if (ssa->ops[use].op2_use_chain == op) { + ssa->ops[use].op2_use_chain = new_op; + return; + } else { + use = ssa->ops[use].op2_use_chain; + } + } else { + break; + } + } + } + /* something wrong */ + ZEND_UNREACHABLE(); +} +/* }}} */ + void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op) /* {{{ */ { if (ssa_op->result_use >= 0) { diff --git a/Zend/Optimizer/zend_ssa.h b/Zend/Optimizer/zend_ssa.h index 93fa6e673f2e8..9fde352c79cc1 100644 --- a/Zend/Optimizer/zend_ssa.h +++ b/Zend/Optimizer/zend_ssa.h @@ -149,6 +149,7 @@ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *scrip ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa); ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *opline, uint32_t k, uint32_t build_flags, int ssa_vars_count, zend_ssa_op *ssa_ops, int *var); void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var); +void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var); void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to); void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op); From 87d9e02f01cf835deada04e4639b073144c14ee9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 27 Dec 2021 13:44:53 +0100 Subject: [PATCH 029/227] Don't truncate subsecond precision in run-tests.php JUNIT output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When run-tests.php has been typed[1], the type of `$time` has been chosen to be `int`. This, however, leads to truncation, and the somewhat relevant subsecond precision is lost. We fix that by changing the type to `float`, although `int|string` would be more appropriate, but requires PHP ≥ 7.4.0. Another option would be to move the `number_format()` formatting into `junit_mark_test_as()`. [1] Closes GH-7836. --- run-tests.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run-tests.php b/run-tests.php index 333b6058fbed1..709c657c2f0fe 100755 --- a/run-tests.php +++ b/run-tests.php @@ -3478,7 +3478,7 @@ function junit_mark_test_as( $type, string $file_name, string $test_name, - ?int $time = null, + ?float $time = null, string $message = '', string $details = '' ): void { @@ -3533,7 +3533,7 @@ function junit_mark_test_as( $JUNIT['files'][$file_name]['xml'] .= "\n"; } -function junit_suite_record(string $suite, string $param, int $value = 1): void +function junit_suite_record(string $suite, string $param, float $value = 1): void { global $JUNIT; @@ -3541,7 +3541,7 @@ function junit_suite_record(string $suite, string $param, int $value = 1): void $JUNIT['suites'][$suite][$param] += $value; } -function junit_get_timer(string $file_name): int +function junit_get_timer(string $file_name): float { global $JUNIT; if (!junit_enabled()) { From de358f856fea56ad2b7ff79f3f7daa91ee99b32a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Dec 2021 09:57:03 +0300 Subject: [PATCH 030/227] Fix reference contig inference Fixes oss-fuzz #43032 --- ext/opcache/Optimizer/zend_inference.c | 25 +++++++++++++++++++++--- ext/opcache/tests/jit/fetch_obj_009.phpt | 21 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/jit/fetch_obj_009.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index feb469303c497..46f0f1e076a9c 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2191,6 +2191,25 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, zend_property_in return MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_RC1 | MAY_BE_RCN; } +static zend_bool result_may_be_separated(zend_ssa *ssa, zend_ssa_op *ssa_op) +{ + int tmp_var = ssa_op->result_def; + + if (ssa->vars[tmp_var].use_chain >= 0 + && !ssa->vars[tmp_var].phi_use_chain) { + zend_ssa_op *use_op = &ssa->ops[ssa->vars[tmp_var].use_chain]; + + /* TODO: analize instructions between ssa_op and use_op */ + if (use_op == ssa_op + 1) { + if ((use_op->op1_use == tmp_var && use_op->op1_use_chain < 0) + || (use_op->op2_use == tmp_var && use_op->op2_use_chain < 0)) { + return 0; + } + } + } + return 1; +} + static zend_always_inline int _zend_update_type_info( const zend_op_array *op_array, zend_ssa *ssa, @@ -3307,11 +3326,11 @@ static zend_always_inline int _zend_update_type_info( if (prop_info) { /* FETCH_OBJ_R/IS for plain property increments reference counter, so it can't be 1 */ - if (ce && !ce->create_object) { + if (ce && !ce->create_object && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } } else { - if (ce && !ce->create_object && !ce->__get) { + if (ce && !ce->create_object && !ce->__get && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } } @@ -3336,7 +3355,7 @@ static zend_always_inline int _zend_update_type_info( zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce); if (opline->result_type != IS_TMP_VAR) { tmp |= MAY_BE_REF | MAY_BE_INDIRECT; - } else { + } else if (!result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); diff --git a/ext/opcache/tests/jit/fetch_obj_009.phpt b/ext/opcache/tests/jit/fetch_obj_009.phpt new file mode 100644 index 0000000000000..92d67de08abbf --- /dev/null +++ b/ext/opcache/tests/jit/fetch_obj_009.phpt @@ -0,0 +1,21 @@ +--TEST-- +JIT: FETCH_OBJ 009 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +x[0] = null; + $obj->x > $obj->x[0] = null; + } +} +test(); +?> +DONE +--EXPECT-- +DONE From cb3d85874543a8e5c092353402c13776c775a912 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 27 Dec 2021 10:05:02 +0000 Subject: [PATCH 031/227] Fix buffer allocations in zlog_stream_set_msg_suffix() If that code was used, there would be a UAF scenario. Closes GH-7835. --- sapi/fpm/fpm/zlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/fpm/fpm/zlog.c b/sapi/fpm/fpm/zlog.c index 4808447f5c924..0938f08e89de4 100644 --- a/sapi/fpm/fpm/zlog.c +++ b/sapi/fpm/fpm/zlog.c @@ -637,10 +637,10 @@ zlog_bool zlog_stream_set_msg_suffix( if (suffix != NULL) { stream->msg_suffix_len = strlen(suffix); len = stream->msg_suffix_len + 1; - stream->msg_suffix = malloc(len); if (stream->msg_suffix != NULL) { free(stream->msg_suffix); } + stream->msg_suffix = malloc(len); if (stream->msg_suffix == NULL) { return ZLOG_FALSE; } @@ -650,10 +650,10 @@ zlog_bool zlog_stream_set_msg_suffix( if (final_suffix != NULL) { stream->msg_final_suffix_len = strlen(final_suffix); len = stream->msg_final_suffix_len + 1; - stream->msg_final_suffix = malloc(len); if (stream->msg_final_suffix != NULL) { free(stream->msg_suffix); } + stream->msg_final_suffix = malloc(len); if (stream->msg_final_suffix == NULL) { return ZLOG_FALSE; } From fd879e6fe47c5d83e9f2e9fd2f72e6b1b548a02a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Dec 2021 16:51:03 +0300 Subject: [PATCH 032/227] JIT: Fix array clobbering by user error handler Gixes oss-fuzz #43055 --- ext/opcache/jit/zend_jit_helpers.c | 64 ++++++++++++++++++++++ ext/opcache/tests/jit/fetch_dim_r_010.phpt | 19 +++++++ 2 files changed, 83 insertions(+) create mode 100644 ext/opcache/tests/jit/fetch_dim_r_010.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 4595afdc17873..2eb3bb3cc1880 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -456,6 +456,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, zend_ulong hval; zend_string *offset_key; zval *retval; + zend_execute_data *execute_data; + const zend_op *opline; if (Z_TYPE_P(dim) == IS_REFERENCE) { dim = Z_REFVAL_P(dim); @@ -469,7 +471,31 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } /* break missing intentionally */ case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); @@ -531,6 +557,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim zend_ulong hval; zend_string *offset_key; zval *retval; + zend_execute_data *execute_data; + const zend_op *opline; if (Z_TYPE_P(dim) == IS_REFERENCE) { dim = Z_REFVAL_P(dim); @@ -544,7 +572,31 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } /* break missing intentionally */ case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); @@ -616,7 +668,19 @@ static int ZEND_FASTCALL zend_jit_fetch_dim_isset_helper(zend_array *ht, zval *d offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return 0; + } + if (EG(exception)) { + return 0; + } /* break missing intentionally */ case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); diff --git a/ext/opcache/tests/jit/fetch_dim_r_010.phpt b/ext/opcache/tests/jit/fetch_dim_r_010.phpt new file mode 100644 index 0000000000000..201d0b40f5bd3 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_010.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT FETCH_DIM_R: 010 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 206bcff50d9a5ec1d26ab480f93c0ef539644408 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Dec 2021 16:56:23 +0300 Subject: [PATCH 033/227] iSeparate tests --- ext/opcache/tests/jit/fetch_dim_r_010.phpt | 1 - ext/opcache/tests/jit/fetch_dim_r_011.phpt | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/fetch_dim_r_011.phpt diff --git a/ext/opcache/tests/jit/fetch_dim_r_010.phpt b/ext/opcache/tests/jit/fetch_dim_r_010.phpt index 201d0b40f5bd3..677f4a411b6aa 100644 --- a/ext/opcache/tests/jit/fetch_dim_r_010.phpt +++ b/ext/opcache/tests/jit/fetch_dim_r_010.phpt @@ -12,7 +12,6 @@ set_error_handler(function() { }); $a = [$y]; ($a[$b]); -($a[17604692317316877817]); ?> DONE --EXPECT-- diff --git a/ext/opcache/tests/jit/fetch_dim_r_011.phpt b/ext/opcache/tests/jit/fetch_dim_r_011.phpt new file mode 100644 index 0000000000000..3ef3733f19c00 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_011.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT FETCH_DIM_R: 011 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 85af420f791b5c727ec055a9c3dd7a4231072e61 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Tue, 28 Dec 2021 11:35:45 -0500 Subject: [PATCH 034/227] [skip ci] Update documentation of supported php versions (#7822) https://www.php.net/supported-versions.php Co-authored-by: Christoph M. Becker --- CONTRIBUTING.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd1ed6f4792cb..a77eec1e01fb9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,7 @@ If you are fixing a bug, then please submit your PR against the lowest actively supported branch of PHP that the bug affects (only green branches on [the supported version page](https://www.php.net/supported-versions.php) are supported). For example, at the time of writing, the lowest supported version is -PHP 7.3, which corresponds to the `PHP-7.3` branch in Git. Please also make sure +PHP 8.0, which corresponds to the `PHP-8.0` branch in Git. Please also make sure you add a link to the PR in the bug on [the bug tracker](https://bugs.php.net/). Pull requests implementing RFCs should be submitted against `master`. @@ -332,9 +332,9 @@ Currently we have the following branches in use: | master | Active development branch for PHP 8.2, which is open for backwards incompatible changes and major internal API changes. | | PHP-8.1 | Is used to release the PHP 8.1.x series. This is a current stable version and is open for bugfixes only. | | PHP-8.0 | Is used to release the PHP 8.0.x series. This is a current stable version and is open for bugfixes only. | -| PHP-7.4 | Is used to release the PHP 7.4.x series. This is a current stable version and is open for bugfixes only. | -| PHP-7.3 | Is used to release the PHP 7.3.x series. This is a current stable version and is open for bugfixes only. | -| PHP-7.2 | Is used to release the PHP 7.2.x series. This is an old stable version and is open for security fixes only. | +| PHP-7.4 | Is used to release the PHP 7.4.x series. This is an old stable version and is open for security fixes only. | +| PHP-7.3 | This branch is closed. | +| PHP-7.2 | This branch is closed. | | PHP-7.1 | This branch is closed. | | PHP-7.0 | This branch is closed. | | PHP-5.6 | This branch is closed. | @@ -349,8 +349,8 @@ Currently we have the following branches in use: The next few rules are more of a technical nature: 1. All non-security bugfix changes should first go to the lowest bugfix branch - (i.e. 7.3) and then get merged up to all other branches. All security fixes - should go to the lowest security fixes branch (i.e 7.2). If a change is not + (i.e. 8.0) and then get merged up to all other branches. All security fixes + should go to the lowest security fixes branch (i.e 7.4). If a change is not needed for later branches (i.e. fixes for features which were dropped from later branches) an empty merge should be done. From 24be11f632496796514b90d66219a535a3152305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Tue, 28 Dec 2021 14:13:25 +0100 Subject: [PATCH 035/227] Remove bogus type of $object param in SplObjectStorage::offsetSet() This parameter definitely only accepts objects, so we shouldn't explicitly mark it as mixed. Looks like I accidentally added this type when adding the tentative return type. Closes GH-7840 --- ext/spl/spl_observer.stub.php | 2 +- ext/spl/spl_observer_arginfo.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/spl/spl_observer.stub.php b/ext/spl/spl_observer.stub.php index e5ea360354f4d..ed327aa7aad6b 100644 --- a/ext/spl/spl_observer.stub.php +++ b/ext/spl/spl_observer.stub.php @@ -90,7 +90,7 @@ public function offsetGet($object): mixed {} * @implementation-alias SplObjectStorage::attach * @no-verify Cannot specify arg type because ArrayAccess does not */ - public function offsetSet(mixed $object, mixed $info = null): void {} + public function offsetSet($object, mixed $info = null): void {} /** * @param object $object diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index 5e9044a088f1e..94991119cb6f1 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a3c87f5b7edd257e25d6651628dd9896e14f5715 */ + * Stub hash: 63dde3294f600164805befd79b1f670fbfb23571 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObserver_update, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, subject, SplSubject, 0) @@ -75,7 +75,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObjectStorage ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObjectStorage_offsetSet, 0, 1, IS_VOID, 0) - ZEND_ARG_TYPE_INFO(0, object, IS_MIXED, 0) + ZEND_ARG_INFO(0, object) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, info, IS_MIXED, 0, "null") ZEND_END_ARG_INFO() From 7d2f2a100582ba95d4da082bcbd629ef48549084 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Dec 2021 12:03:42 +0100 Subject: [PATCH 036/227] Remove an incorrect JMPZNZ optimization This is already skipped for TMP/VAR, but also needs to be skipped for CV, because we need to insert CHECK_VAR in that case, if we're being pedantic. That leaves us with CONST as the only case we can handle, which is already covered by constant folding. This optimization never actually triggers in our tests, so it's not a big loss. --- Zend/Optimizer/pass3.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 2b0fa7aa52ebc..f96e071311f61 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -340,15 +340,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, target); } - if (ZEND_OP2_JMP_ADDR(opline) == target && - !(opline->op1_type & (IS_VAR|IS_TMP_VAR))) { - /* JMPZNZ(?,L,L) -> JMP(L) */ - opline->opcode = ZEND_JMP; - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target); - SET_UNUSED(opline->op1); - SET_UNUSED(opline->op2); - opline->extended_value = 0; - } /* Don't convert JMPZNZ back to JMPZ/JMPNZ, because the following JMP is not removed yet. */ break; From 0698bf794f502b59840bb422908ae47573112034 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Dec 2021 12:44:57 +0100 Subject: [PATCH 037/227] Add helper for convertion to CHECK_VAR/FREE/NOP This is a recurring pattern whenever an instruction with an operand is deleted. --- Zend/Optimizer/block_pass.c | 33 ++++-------------------- Zend/Optimizer/optimize_func_calls.c | 16 +++--------- Zend/Optimizer/pass3.c | 20 ++------------ Zend/Optimizer/zend_optimizer.c | 19 ++++++++++++++ Zend/Optimizer/zend_optimizer_internal.h | 1 + 5 files changed, 30 insertions(+), 59 deletions(-) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index eac6d6b37aa73..4a88c58abc13a 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -1327,14 +1327,8 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr follow_block = get_follow_block(cfg, block, 1, opt_count); if (target_block == follow_block) { /* L: JMP[N]Z(X, L+1) -> NOP or FREE(X) */ - if (last_op->op1_type == IS_CV) { - last_op->opcode = ZEND_CHECK_VAR; - last_op->op2.num = 0; - } else if (last_op->op1_type & (IS_VAR|IS_TMP_VAR)) { - last_op->opcode = ZEND_FREE; - last_op->op2.num = 0; - } else { - MAKE_NOP(last_op); + zend_optimizer_convert_to_free_op1(op_array, last_op); + if (last_op->opcode == ZEND_NOP) { block->len--; } block->successors_count = 1; @@ -1344,14 +1338,8 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr if (target->opcode == ZEND_JMP) { if (block->successors[0] == follow_block->successors[0]) { /* JMPZ(X,L1), JMP(L1) -> NOP, JMP(L1) */ - if (last_op->op1_type == IS_CV) { - last_op->opcode = ZEND_CHECK_VAR; - last_op->op2.num = 0; - } else if (last_op->op1_type & (IS_VAR|IS_TMP_VAR)) { - last_op->opcode = ZEND_FREE; - last_op->op2.num = 0; - } else { - MAKE_NOP(last_op); + zend_optimizer_convert_to_free_op1(op_array, last_op); + if (last_op->opcode == ZEND_NOP) { block->len--; } block->successors[0] = follow_block - cfg->blocks; @@ -1704,18 +1692,7 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use case ZEND_QM_ASSIGN: case ZEND_BOOL: case ZEND_BOOL_NOT: - if (opline->op1_type == IS_CV) { - opline->opcode = ZEND_CHECK_VAR; - SET_UNUSED(opline->result); - } else if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { - opline->opcode = ZEND_FREE; - SET_UNUSED(opline->result); - } else { - if (opline->op1_type == IS_CONST) { - literal_dtor(&ZEND_OP1_LITERAL(opline)); - } - MAKE_NOP(opline); - } + zend_optimizer_convert_to_free_op1(op_array, opline); break; case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: diff --git a/Zend/Optimizer/optimize_func_calls.c b/Zend/Optimizer/optimize_func_calls.c index e2e16f90b8654..c1f69f5748a7a 100644 --- a/Zend/Optimizer/optimize_func_calls.c +++ b/Zend/Optimizer/optimize_func_calls.c @@ -43,7 +43,7 @@ typedef struct _optimizer_call_info { uint32_t func_arg_num; } optimizer_call_info; -static void zend_delete_call_instructions(zend_op *opline) +static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opline) { int call = 0; @@ -73,17 +73,7 @@ static void zend_delete_call_instructions(zend_op *opline) case ZEND_SEND_VAL: case ZEND_SEND_VAR: if (call == 0) { - if (opline->op1_type == IS_CONST) { - MAKE_NOP(opline); - } else if (opline->op1_type == IS_CV) { - opline->opcode = ZEND_CHECK_VAR; - opline->extended_value = 0; - opline->result.var = 0; - } else { - opline->opcode = ZEND_FREE; - opline->extended_value = 0; - opline->result.var = 0; - } + zend_optimizer_convert_to_free_op1(op_array, opline); } break; } @@ -144,7 +134,7 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o MAKE_NOP(opline); } - zend_delete_call_instructions(opline-1); + zend_delete_call_instructions(op_array, opline-1); } } } diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index f96e071311f61..39e1d65c20806 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -116,15 +116,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) (opline-1)->opcode == ZEND_JMPNZ)) { if (ZEND_OP2_JMP_ADDR(opline-1) == target) { /* JMPZ(X,L1), JMP(L1) -> NOP, JMP(L1) */ - if ((opline-1)->op1_type == IS_CV) { - (opline-1)->opcode = ZEND_CHECK_VAR; - (opline-1)->op2.num = 0; - } else if ((opline-1)->op1_type & (IS_TMP_VAR|IS_VAR)) { - (opline-1)->opcode = ZEND_FREE; - (opline-1)->op2.num = 0; - } else { - MAKE_NOP(opline-1); - } + zend_optimizer_convert_to_free_op1(op_array, opline - 1); } else { /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ if ((opline-1)->opcode == ZEND_JMPZ) { @@ -194,15 +186,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* convert L: JMPZ L+1 to NOP */ if (target == opline + 1) { - if (opline->op1_type == IS_CV) { - opline->opcode = ZEND_CHECK_VAR; - opline->op2.num = 0; - } else if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { - opline->opcode = ZEND_FREE; - opline->op2.num = 0; - } else { - MAKE_NOP(opline); - } + zend_optimizer_convert_to_free_op1(op_array, opline); } break; diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index 0a4111fa4fd33..58512f751b667 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -208,6 +208,25 @@ bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zva return 0; } +void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline) +{ + if (opline->op1_type == IS_CV) { + opline->opcode = ZEND_CHECK_VAR; + SET_UNUSED(opline->op2); + SET_UNUSED(opline->result); + opline->extended_value = 0; + } else if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + opline->opcode = ZEND_FREE; + SET_UNUSED(opline->op2); + SET_UNUSED(opline->result); + opline->extended_value = 0; + } else { + ZEND_ASSERT(opline->op1_type == IS_CONST); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } +} + int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv) { int i = op_array->last_literal; diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h index 25d021fa98ce9..9e295bad73dcb 100644 --- a/Zend/Optimizer/zend_optimizer_internal.h +++ b/Zend/Optimizer/zend_optimizer_internal.h @@ -76,6 +76,7 @@ static inline bool zend_optimizer_is_loop_var_free(const zend_op *opline) { || (opline->opcode == ZEND_FREE && opline->extended_value == ZEND_FREE_SWITCH); } +void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline); int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv); bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy); void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value); From f2b50156bc7f3fbf4e3384cdcf1240bacb4310ef Mon Sep 17 00:00:00 2001 From: "Chun-Sheng, Li" Date: Thu, 30 Dec 2021 20:02:56 +0800 Subject: [PATCH 038/227] Add some more test cases for BCMath Closes GH-7851. --- ext/bcmath/tests/bcadd.phpt | 4 ++++ ext/bcmath/tests/bcadd_variation001.phpt | 8 +++++++- ext/bcmath/tests/bccomp_variation002.phpt | 8 +++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ext/bcmath/tests/bcadd.phpt b/ext/bcmath/tests/bcadd.phpt index b24ce8dbd7927..fa4be8acbe1ae 100644 --- a/ext/bcmath/tests/bcadd.phpt +++ b/ext/bcmath/tests/bcadd.phpt @@ -8,9 +8,13 @@ bcmath.scale=0 --EXPECT-- 3 4.0000 +-6.0000 +-4.0000 8728932003911564969352217864684.00 diff --git a/ext/bcmath/tests/bcadd_variation001.phpt b/ext/bcmath/tests/bcadd_variation001.phpt index 447958b4a2f0f..d6bd89b52231d 100644 --- a/ext/bcmath/tests/bcadd_variation001.phpt +++ b/ext/bcmath/tests/bcadd_variation001.phpt @@ -7,10 +7,16 @@ bcmath.scale=5 --FILE-- --EXPECT-- 6.50 +6.50 +-5.1 -5.1 3.03000 +-11.57000 diff --git a/ext/bcmath/tests/bccomp_variation002.phpt b/ext/bcmath/tests/bccomp_variation002.phpt index ae7ba7fafe819..eb9655083ca3f 100644 --- a/ext/bcmath/tests/bccomp_variation002.phpt +++ b/ext/bcmath/tests/bccomp_variation002.phpt @@ -8,9 +8,15 @@ bcmath.scale=0 --EXPECT-- 0 -1 1 +-1 +1 +1 From 50c7512f5213566add86e33fcdf2c8889b61c78e Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 30 Dec 2021 14:08:12 +0000 Subject: [PATCH 039/227] mysqli_result::__construct should throw exceptions (#7855) --- ext/mysqli/mysqli.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 58ee1e7b564da..8769d08ee9823 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -980,8 +980,12 @@ PHP_METHOD(mysqli_result, __construct) } if (!result) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql)); + } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = (void *)result; From 8869bbe0e9a37293e3f790b5fb891e765000d7d9 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 30 Dec 2021 14:15:29 +0000 Subject: [PATCH 040/227] Fix bug GH-7746 (mysqli_sql_exception->sqlstate is inaccessible) Closes GH-7747 --- NEWS | 1 + ext/mysqli/mysqli.stub.php | 2 ++ ext/mysqli/mysqli_arginfo.h | 7 ++++++- ext/mysqli/mysqli_exception.c | 14 ++++++++++++++ ext/mysqli/tests/gh7746.phpt | 25 +++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 ext/mysqli/tests/gh7746.phpt diff --git a/NEWS b/NEWS index ecf24e5d08005..2ba941999f0e6 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ PHP NEWS . Fixed bug #81658 (MYSQL_OPT_LOAD_DATA_LOCAL_DIR not available in MariaDB). (devnexen) . Introduced MYSQLI_IS_MARIADB. (devnexen) + . Fixed bug GH-7746 (mysqli_sql_exception->getSqlState()). (Kamil Tekiela) - OCI8: . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index e0c46a5427bcb..be0bbbc919b25 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -613,6 +613,8 @@ public function next(): bool {} final class mysqli_sql_exception extends RuntimeException { protected string $sqlstate = "00000"; + + public function getSqlState(): string {} } /** @refcount 1 */ diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 4cd285e347f47..a0168a51c7a98 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: e9f4dd04e7d01864c38033bcaf5e03b63e191deb */ + * Stub hash: 78662c05cd463735a8a4101c0357fd0d2698d48e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -720,6 +720,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_mysqli_warning_next arginfo_mysqli_thread_safe +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_sql_exception_getSqlState, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_FUNCTION(mysqli_affected_rows); ZEND_FUNCTION(mysqli_autocommit); @@ -842,6 +845,7 @@ ZEND_METHOD(mysqli_result, getIterator); ZEND_METHOD(mysqli_stmt, __construct); ZEND_METHOD(mysqli_warning, __construct); ZEND_METHOD(mysqli_warning, next); +ZEND_METHOD(mysqli_sql_exception, getSqlState); static const zend_function_entry ext_functions[] = { @@ -1083,6 +1087,7 @@ static const zend_function_entry class_mysqli_warning_methods[] = { static const zend_function_entry class_mysqli_sql_exception_methods[] = { + ZEND_ME(mysqli_sql_exception, getSqlState, arginfo_class_mysqli_sql_exception_getSqlState, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c index 3bc80807a7e98..3d15881863e24 100644 --- a/ext/mysqli/mysqli_exception.c +++ b/ext/mysqli/mysqli_exception.c @@ -63,3 +63,17 @@ void php_mysqli_throw_sql_exception(char *sqlstate, int errorno, char *format, . zend_throw_exception_object(&sql_ex); } + +PHP_METHOD(mysqli_sql_exception, getSqlState) +{ + zval *prop; + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + prop = zend_read_property(mysqli_exception_class_entry, Z_OBJ_P(ZEND_THIS), "sqlstate", sizeof("sqlstate")-1, 1, &rv); + ZVAL_DEREF(prop); + zend_string *str = zval_get_string(prop); + + RETURN_STR(str); +} diff --git a/ext/mysqli/tests/gh7746.phpt b/ext/mysqli/tests/gh7746.phpt new file mode 100644 index 0000000000000..18fdb03451377 --- /dev/null +++ b/ext/mysqli/tests/gh7746.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #GH-7746 mysqli_sql_exception->sqlstate is inaccessible +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query("stuff"); +} catch (mysqli_sql_exception $exception) { + var_dump($exception->getSqlState()); +} + +?> +--EXPECT-- +string(5) "42000" From b63e4cf727ec596373c21079c5e2f37eec5dd59d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Dec 2021 16:55:21 +0100 Subject: [PATCH 041/227] Handle holes in zend_get_opcode_id() Some opcodes may currently not be allocated. --- Zend/zend_vm_gen.php | 3 ++- Zend/zend_vm_opcodes.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 343447a8d8983..45d559f26c7c4 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -2688,7 +2688,8 @@ function gen_vm($def, $skel) { fputs($f, "ZEND_API zend_uchar zend_get_opcode_id(const char *name, size_t length) {\n"); fputs($f, "\tzend_uchar opcode;\n"); fputs($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n"); - fputs($f, "\t\tif (strncmp(zend_vm_opcodes_names[opcode], name, length) == 0) {\n"); + fputs($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n"); + fputs($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n"); fputs($f, "\t\t\treturn opcode;\n"); fputs($f, "\t\t}\n"); fputs($f, "\t}\n"); diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 7f88f9e84b690..085c473d59578 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -449,7 +449,8 @@ ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode) { ZEND_API zend_uchar zend_get_opcode_id(const char *name, size_t length) { zend_uchar opcode; for (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) { - if (strncmp(zend_vm_opcodes_names[opcode], name, length) == 0) { + const char *opcode_name = zend_vm_opcodes_names[opcode]; + if (opcode_name && strncmp(opcode_name, name, length) == 0) { return opcode; } } From b3903515bfe962529f1e9fd9aa4d3b761def868f Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Wed, 29 Dec 2021 16:11:14 +0100 Subject: [PATCH 042/227] Fix bug where large bigints may be truncated Unless stringified results are requested, we need to parse large bigints as unsigned, to avoid wrap-around behavior. Co-authored-by: Christoph M. Becker Closes GH-7837. --- NEWS | 3 +++ ext/mysqli/tests/gh7837.phpt | 42 ++++++++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_wireprotocol.c | 4 +-- 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 ext/mysqli/tests/gh7837.phpt diff --git a/NEWS b/NEWS index 30f8b64959f5a..7f2292bc4a732 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS . Fixed bug GH-7826 (Inconsistent argument name in hash_hmac_file and hash_file). (cmb) +- MySQLnd: + . Fixed bug where large bigints may be truncated. (Nathan Freeman, cmb) + - OCI8: . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second call). (cmb) diff --git a/ext/mysqli/tests/gh7837.phpt b/ext/mysqli/tests/gh7837.phpt new file mode 100644 index 0000000000000..dc361c2bc1306 --- /dev/null +++ b/ext/mysqli/tests/gh7837.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug GH-7837 (large bigints may be truncated) +--SKIPIF-- + +--FILE-- +options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); +$mysql->query("DROP TABLE IF EXISTS test"); +$mysql->query("CREATE TABLE test (`ubigint` bigint unsigned NOT NULL) ENGINE=InnoDB"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (18446744073709551615)"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (9223372036854775808)"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (1)"); +$result = $mysql->query("SELECT ubigint FROM test"); +var_dump($result->fetch_all()); +?> +--EXPECT-- +array(3) { + [0]=> + array(1) { + [0]=> + string(20) "18446744073709551615" + } + [1]=> + array(1) { + [0]=> + string(19) "9223372036854775808" + } + [2]=> + array(1) { + [0]=> + int(1) + } +} diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 63503f5c9849c..b83de494c2f7d 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -1634,9 +1634,9 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_ROW_BUFFER * row_buffer, zval * } else { uint64_t v = #ifndef PHP_WIN32 - (uint64_t) atoll((char *) p); + strtoull((char *) p, NULL, 10); #else - (uint64_t) _atoi64((char *) p); + _strtoui64((char *) p, NULL, 10); #endif zend_bool uns = fields_metadata[i].flags & UNSIGNED_FLAG? TRUE:FALSE; /* We have to make it ASCIIZ temporarily */ From 49512b6b36f18295277da33967b143071cb60012 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 30 Dec 2021 19:25:32 +0000 Subject: [PATCH 043/227] Fix formatting in the new mysqli test --- ext/mysqli/tests/gh7837.phpt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ext/mysqli/tests/gh7837.phpt b/ext/mysqli/tests/gh7837.phpt index dc361c2bc1306..40f8fabeee6c0 100644 --- a/ext/mysqli/tests/gh7837.phpt +++ b/ext/mysqli/tests/gh7837.phpt @@ -2,15 +2,15 @@ Bug GH-7837 (large bigints may be truncated) --SKIPIF-- --FILE-- options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); @@ -22,6 +22,10 @@ $mysql->query("INSERT INTO test (`ubigint`) VALUES (1)"); $result = $mysql->query("SELECT ubigint FROM test"); var_dump($result->fetch_all()); ?> +--CLEAN-- + --EXPECT-- array(3) { [0]=> From d963b3f015ad606050a45c9ac3c97c7726b0ad81 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 31 Dec 2021 00:22:29 +0100 Subject: [PATCH 044/227] mysqli_next_result_no_repeat_error.phpt must not use --EXTENSIONS-- This is only properly supported as of PHP 8.1.0[1], and may cause spurious test failures for older versions[2]. [1] [2] --- ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt b/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt index 22fb70979650d..7241ef7dd0cc7 100644 --- a/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt +++ b/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt @@ -1,9 +1,8 @@ --TEST-- next_result reports errors from previous calls ---EXTENSIONS-- -mysqli --SKIPIF-- --FILE-- From 96a5026bfd43415676a730b351d38ed64b9d711d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Tue, 28 Dec 2021 14:06:12 +0100 Subject: [PATCH 045/227] Redefine PDOException::$code with correct type Closes GH-7839 --- ext/pdo/pdo.stub.php | 2 ++ ext/pdo/pdo_arginfo.h | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/pdo/pdo.stub.php b/ext/pdo/pdo.stub.php index 39a508bafcb15..ebe81b7a51ad8 100644 --- a/ext/pdo/pdo.stub.php +++ b/ext/pdo/pdo.stub.php @@ -4,6 +4,8 @@ class PDOException extends RuntimeException { + /** @var int|string */ + protected $code = 0; public ?array $errorInfo = null; } diff --git a/ext/pdo/pdo_arginfo.h b/ext/pdo/pdo_arginfo.h index d4c74eef624f8..72eda0c3ae99a 100644 --- a/ext/pdo/pdo_arginfo.h +++ b/ext/pdo/pdo_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 52ee252fdfc80d4d076f1c49842e333c27ed5102 */ + * Stub hash: 8d975a20d009e827f8d72ac19b94b55870b6bf9c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pdo_drivers, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -25,6 +25,12 @@ static zend_class_entry *register_class_PDOException(zend_class_entry *class_ent INIT_CLASS_ENTRY(ce, "PDOException", class_PDOException_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + zval property_code_default_value; + ZVAL_LONG(&property_code_default_value, 0); + zend_string *property_code_name = zend_string_init("code", sizeof("code") - 1, 1); + zend_declare_property_ex(class_entry, property_code_name, &property_code_default_value, ZEND_ACC_PROTECTED, NULL); + zend_string_release(property_code_name); + zval property_errorInfo_default_value; ZVAL_NULL(&property_errorInfo_default_value); zend_string *property_errorInfo_name = zend_string_init("errorInfo", sizeof("errorInfo") - 1, 1); From 05ed3b779951ca54003c47d68fadea83a6fc6940 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sun, 2 Jan 2022 22:50:35 +0000 Subject: [PATCH 046/227] Remove duplicated SKIP checks from mysqli tests (#7858) --- ext/mysqli/tests/014.phpt | 19 ++++++------ ext/mysqli/tests/015.phpt | 18 +++++------ ext/mysqli/tests/045.phpt | 5 ++-- ext/mysqli/tests/067.phpt | 11 ++++--- ext/mysqli/tests/bug42548.phpt | 9 +++--- ext/mysqli/tests/bug44897.phpt | 12 ++++---- ext/mysqli/tests/bug49442.phpt | 12 ++++---- ext/mysqli/tests/bug51647.phpt | 5 ++-- ext/mysqli/tests/bug53503.phpt | 14 ++++----- ext/mysqli/tests/bug55283.phpt | 3 +- ext/mysqli/tests/bug55582.phpt | 3 +- ext/mysqli/tests/bug63398.phpt | 3 +- ext/mysqli/tests/bug64726.phpt | 3 +- ext/mysqli/tests/bug68077.phpt | 9 +++--- ext/mysqli/tests/bug69899.phpt | 1 - ext/mysqli/tests/bug70384.phpt | 30 ++++++++++--------- ext/mysqli/tests/bug70949.phpt | 7 ++--- ext/mysqli/tests/bug71863.phpt | 7 ++--- ext/mysqli/tests/bug72701.phpt | 5 ++-- ext/mysqli/tests/bug76386.phpt | 12 ++++---- ext/mysqli/tests/bug77956.phpt | 9 +++--- ext/mysqli/tests/clean_table.inc | 2 +- ext/mysqli/tests/gh7746.phpt | 1 - ...file_overrides_local_infile_directory.phpt | 12 ++++---- ext/mysqli/tests/mysqli_autocommit.phpt | 10 +++---- ext/mysqli/tests/mysqli_autocommit_oo.phpt | 13 ++++---- .../tests/mysqli_change_user_insert_id.phpt | 7 ++--- ext/mysqli/tests/mysqli_change_user_new.phpt | 6 ++-- ext/mysqli/tests/mysqli_change_user_oo.phpt | 6 ++-- .../tests/mysqli_change_user_rollback.phpt | 12 ++++---- .../tests/mysqli_change_user_set_names.phpt | 8 ++--- ext/mysqli/tests/mysqli_commit.phpt | 12 ++++---- ext/mysqli/tests/mysqli_commit_oo.phpt | 13 ++++---- ext/mysqli/tests/mysqli_connect_attr.phpt | 8 ++--- .../tests/mysqli_connect_oo_warnings.phpt | 12 ++++---- ext/mysqli/tests/mysqli_debug_ini.phpt | 10 ++++--- .../tests/mysqli_debug_mysqlnd_only.phpt | 8 ++--- ext/mysqli/tests/mysqli_explain_metadata.phpt | 8 ++--- ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt | 15 +++++----- .../mysqli_fetch_assoc_no_alias_utf8.phpt | 13 ++++---- .../tests/mysqli_fetch_field_flags.phpt | 12 ++++---- ext/mysqli/tests/mysqli_fork.phpt | 9 +++--- ext/mysqli/tests/mysqli_get_client_info.phpt | 11 ++----- ext/mysqli/tests/mysqli_get_warnings.phpt | 7 ++--- .../tests/mysqli_insert_packet_overflow.phpt | 6 ++-- ...local_infile_directory_access_allowed.phpt | 16 +++++----- ..._local_infile_directory_access_denied.phpt | 16 +++++----- ...ocal_infile_directory_vs_open_basedir.phpt | 12 ++++---- .../tests/mysqli_mysqlnd_read_timeout.phpt | 5 ++-- .../mysqli_mysqlnd_read_timeout_long.phpt | 6 ++-- .../mysqli_mysqlnd_read_timeout_zero.phpt | 6 ++-- .../mysqli_options_int_and_float_native.phpt | 7 ++--- ext/mysqli/tests/mysqli_pam_sha256.phpt | 12 ++++---- .../mysqli_pam_sha256_public_key_ini.phpt | 12 ++++---- .../mysqli_pam_sha256_public_key_option.phpt | 12 ++++---- ..._pam_sha256_public_key_option_invalid.phpt | 12 ++++---- ext/mysqli/tests/mysqli_pconn_kill.phpt | 8 ++--- ext/mysqli/tests/mysqli_pconn_limits.phpt | 9 ++---- ext/mysqli/tests/mysqli_poll_reference.phpt | 8 ++--- .../tests/mysqli_query_stored_proc.phpt | 12 ++++---- ext/mysqli/tests/mysqli_query_unicode.phpt | 9 ++---- .../tests/mysqli_real_connect_pconn.phpt | 7 ++--- ext/mysqli/tests/mysqli_reconnect.phpt | 11 ++++--- .../tests/mysqli_release_savepoint.phpt | 14 ++++----- ext/mysqli/tests/mysqli_report.phpt | 8 ++--- ext/mysqli/tests/mysqli_report_new.phpt | 13 +++----- ext/mysqli/tests/mysqli_report_wo_ps.phpt | 13 +++----- .../mysqli_result_references_mysqlnd.phpt | 10 ++++--- ext/mysqli/tests/mysqli_rollback.phpt | 16 +++++----- ext/mysqli/tests/mysqli_savepoint.phpt | 12 ++++---- ext/mysqli/tests/mysqli_set_charset.phpt | 14 ++++----- ext/mysqli/tests/mysqli_ssl_set.phpt | 6 ++-- ext/mysqli/tests/mysqli_stmt_execute.phpt | 12 ++++---- .../mysqli_stmt_execute_stored_proc.phpt | 17 ++++++----- ..._stmt_execute_stored_proc_next_result.phpt | 11 ++++--- .../mysqli_stmt_execute_stored_proc_out.phpt | 11 ++++--- ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt | 18 ++++++----- .../tests/mysqli_stmt_get_result_bit.phpt | 27 +++++++++-------- .../tests/mysqli_stmt_get_warnings.phpt | 12 +++----- ext/mysqli/tests/mysqli_stmt_multires.phpt | 6 ++-- ...t_send_long_data_packet_size_libmysql.phpt | 2 +- ...mt_send_long_data_packet_size_mysqlnd.phpt | 2 +- .../tests/mysqli_warning_unclonable.phpt | 7 ++--- ext/mysqli/tests/skipifconnectfailure.inc | 1 - ext/mysqli/tests/table.inc | 2 +- 85 files changed, 381 insertions(+), 451 deletions(-) diff --git a/ext/mysqli/tests/014.phpt b/ext/mysqli/tests/014.phpt index 7da7765de9187..36e61b64e1ec2 100644 --- a/ext/mysqli/tests/014.phpt +++ b/ext/mysqli/tests/014.phpt @@ -4,19 +4,18 @@ mysqli autocommit/commit/rollback mysqli --SKIPIF-- errno, $link->error)); +if (!have_innodb($link)) { + die(sprintf("skip Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +} ?> --FILE-- --CLEAN-- --EXPECT-- Num_of_rows=1 diff --git a/ext/mysqli/tests/015.phpt b/ext/mysqli/tests/015.phpt index f9adb2fe2b0b3..9726afe780230 100644 --- a/ext/mysqli/tests/015.phpt +++ b/ext/mysqli/tests/015.phpt @@ -4,18 +4,18 @@ mysqli autocommit/commit/rollback with innodb mysqli --SKIPIF-- errno, $link->error)); +if (!have_innodb($link)) { + die(sprintf("skip Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +} ?> --FILE-- --CLEAN-- --EXPECT-- array(2) { diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt index 7db4a2a1bbcf2..213b27137dd07 100644 --- a/ext/mysqli/tests/045.phpt +++ b/ext/mysqli/tests/045.phpt @@ -4,9 +4,8 @@ mysqli_stmt_bind_result (SHOW) mysqli --SKIPIF-- --FILE-- --CLEAN-- --FILE-- real_connect($host, $user, $passwd, $db, $port, $socket); @@ -53,7 +52,7 @@ print "done!"; ?> --CLEAN-- errno, $link->error)); @@ -23,7 +23,7 @@ mysqli.allow_persistent=1 mysqli.max_persistent=1 --FILE-- --CLEAN-- --EXPECT-- array(2) { diff --git a/ext/mysqli/tests/bug51647.phpt b/ext/mysqli/tests/bug51647.phpt index 3e1e15a6e7a1d..38515245e7b0e 100644 --- a/ext/mysqli/tests/bug51647.phpt +++ b/ext/mysqli/tests/bug51647.phpt @@ -4,8 +4,7 @@ Bug #51647 (Certificate file without private key (pk in another file) doesn't wo mysqli --SKIPIF-- close(); ?> --FILE-- errno, $link->error)); mysqli_close($link); - ?> --INI-- mysqli.allow_local_infile=1 --FILE-- --CLEAN-- --FILE-- --FILE-- --FILE-- errno, $link->error)); diff --git a/ext/mysqli/tests/bug69899.phpt b/ext/mysqli/tests/bug69899.phpt index 6585f1048409b..66f997a4d3408 100644 --- a/ext/mysqli/tests/bug69899.phpt +++ b/ext/mysqli/tests/bug69899.phpt @@ -11,7 +11,6 @@ mysqli --SKIPIF-- server_version < 50709) { - die("skip MySQL 5.7.9+ needed. Found [". - intval(substr($link->server_version."", -5, 1)). - ".". - intval(substr($link->server_version."", -4, 2)). - ".". - intval(substr($link->server_version."", -2, 2)). - "]"); - } - } +require_once 'connect.inc'; +if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); +} + +if ($link->server_version < 50709) { + die("skip MySQL 5.7.9+ needed. Found [". + intval(substr($link->server_version."", -5, 1)). + ".". + intval(substr($link->server_version."", -4, 2)). + ".". + intval(substr($link->server_version."", -2, 2)). + "]"); +} ?> --FILE-- --CLEAN-- --EXPECT-- OK diff --git a/ext/mysqli/tests/bug70949.phpt b/ext/mysqli/tests/bug70949.phpt index 567b1131efdd3..995511e1c6624 100644 --- a/ext/mysqli/tests/bug70949.phpt +++ b/ext/mysqli/tests/bug70949.phpt @@ -4,15 +4,14 @@ Bug #70949 (SQL Result Sets With NULL Can Cause Fatal Memory Errors) mysqli --SKIPIF-- --FILE-- query("DROP TABLE IF EXISTS bug70949"); @@ -47,7 +46,7 @@ if ($stmt = $mysql->prepare($sql)) ?> --CLEAN-- --FILE-- --CLEAN-- = 5.6.4. */ if (mysqli_get_server_version($link) < 50604) { @@ -18,7 +18,7 @@ mysqli_close($link); ?> --FILE-- query('DROP TABLE IF EXISTS ts_test;'); @@ -96,7 +96,7 @@ string(13) "11:00:00.4444" string(15) "11:00:00.006054" --CLEAN-- query('DROP TABLE ts_test;'); $link->query('DROP TABLE t_test;'); diff --git a/ext/mysqli/tests/bug77956.phpt b/ext/mysqli/tests/bug77956.phpt index 8a579c0657d12..53c25c09697ce 100644 --- a/ext/mysqli/tests/bug77956.phpt +++ b/ext/mysqli/tests/bug77956.phpt @@ -4,17 +4,18 @@ ensure an error is returned when mysqli.allow_local_infile is off mysqli --SKIPIF-- errno, $link->error)); +mysqli_close($link); ?> --INI-- mysqli.allow_local_infile=0 diff --git a/ext/mysqli/tests/clean_table.inc b/ext/mysqli/tests/clean_table.inc index 229b42f5eddcc..2b03fc6fb2600 100644 --- a/ext/mysqli/tests/clean_table.inc +++ b/ext/mysqli/tests/clean_table.inc @@ -1,5 +1,5 @@ sqlstate is inaccessible mysqli --SKIPIF-- --FILE-- diff --git a/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt b/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt index 963603515400d..627c76ec539c3 100644 --- a/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt +++ b/ext/mysqli/tests/mysqli_allow_local_infile_overrides_local_infile_directory.phpt @@ -4,17 +4,17 @@ mysqli.allow_local_infile overrides mysqli.local_infile_directory mysqli --SKIPIF-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} diff --git a/ext/mysqli/tests/mysqli_autocommit.phpt b/ext/mysqli/tests/mysqli_autocommit.phpt index 0b410f1f05243..0da4e488e641f 100644 --- a/ext/mysqli/tests/mysqli_autocommit.phpt +++ b/ext/mysqli/tests/mysqli_autocommit.phpt @@ -4,10 +4,9 @@ mysqli_autocommit() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_autocommit_oo.phpt b/ext/mysqli/tests/mysqli_autocommit_oo.phpt index 6510c62ccbecf..0c0dbee834f34 100644 --- a/ext/mysqli/tests/mysqli_autocommit_oo.phpt +++ b/ext/mysqli/tests/mysqli_autocommit_oo.phpt @@ -4,13 +4,10 @@ mysqli->autocommit() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- my_mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt index c82b2c7fa0527..1e75ccc390402 100644 --- a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt @@ -4,8 +4,7 @@ mysqli_change_user() - LAST_INSERT_ID() - http://bugs.mysql.com/bug.php?id=45184 mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_change_user_new.phpt b/ext/mysqli/tests/mysqli_change_user_new.phpt index acf86ab517d33..d6a9a3bd137c4 100644 --- a/ext/mysqli/tests/mysqli_change_user_new.phpt +++ b/ext/mysqli/tests/mysqli_change_user_new.phpt @@ -4,9 +4,9 @@ mysqli_change_user(), MySQL 5.6+ mysqli --SKIPIF-- = 10_00_00) ?> --FILE-- change_user() mysqli --SKIPIF-- 50100)) { die("skip Your MySQL Server version has a known bug that will cause a crash"); } @@ -16,7 +16,7 @@ if (mysqli_get_server_version($link) >= 50600) ?> --FILE-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_change_user_set_names.phpt b/ext/mysqli/tests/mysqli_change_user_set_names.phpt index e09c7801b90ea..85c37b8a60157 100644 --- a/ext/mysqli/tests/mysqli_change_user_set_names.phpt +++ b/ext/mysqli/tests/mysqli_change_user_set_names.phpt @@ -4,10 +4,10 @@ mysqli_change_user() - SET NAMES mysqli --SKIPIF-- --FILE-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt index 56c90b866bfdc..fd4c1bbf008c6 100644 --- a/ext/mysqli/tests/mysqli_commit_oo.phpt +++ b/ext/mysqli/tests/mysqli_commit_oo.phpt @@ -4,18 +4,16 @@ mysqli_commit() mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECTF-- mysqli object is not fully initialized diff --git a/ext/mysqli/tests/mysqli_connect_attr.phpt b/ext/mysqli/tests/mysqli_connect_attr.phpt index eadf7b0fa0da7..75de208c4c5a2 100644 --- a/ext/mysqli/tests/mysqli_connect_attr.phpt +++ b/ext/mysqli/tests/mysqli_connect_attr.phpt @@ -4,13 +4,13 @@ mysqli check the session_connect_attrs table for connection attributes mysqli --SKIPIF-- --FILE-- --FILE-- +--CLEAN-- + --EXPECT-- string(32) "t:O,/tmp/mysqli_debug_phpt.trace" done! diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt index c252e645dc9c9..00a460a410e1f 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -4,8 +4,7 @@ mysqli_debug() - mysqlnd only control strings mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt index f651e573e3032..e920a7fffb081 100644 --- a/ext/mysqli/tests/mysqli_explain_metadata.phpt +++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt @@ -4,15 +4,13 @@ EXPLAIN - metadata mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt index cc92737f81ec5..3e2bfea66aee4 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -4,17 +4,16 @@ mysqli_fetch_assoc() - BIT mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt index a100057c86988..e2334fa7ece86 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt @@ -4,11 +4,10 @@ mysqli_fetch_assoc() - utf8 mysqli --SKIPIF-- --FILE-- +--CLEAN-- + --EXPECTF-- [003] array(3) { diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt index 031e5af6725b9..9874fff49f8ea 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt @@ -4,11 +4,9 @@ mysqli_fetch_field() - flags/field->flags mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt index 599376d0b9c26..52c97306e5052 100644 --- a/ext/mysqli/tests/mysqli_fork.phpt +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -4,7 +4,6 @@ Forking a child and using the same connection. mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --FILE-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt index 9cd13d27c7c8c..d8d210eee12cf 100644 --- a/ext/mysqli/tests/mysqli_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_get_warnings.phpt @@ -4,14 +4,13 @@ mysqli_get_warnings() - TODO mysqli --SKIPIF-- --FILE-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} @@ -22,7 +22,7 @@ mysqli.allow_local_infile=0 mysqli.local_infile_directory={PWD}/foo --FILE-- --CLEAN-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} @@ -22,7 +22,7 @@ mysqli.allow_local_infile=0 mysqli.local_infile_directory={PWD}/foo/bar --FILE-- --CLEAN-- errno, $link->error)); + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); mysqli_close($link); - ?> --INI-- open_basedir={PWD} diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt index be8c3aafa2e8f..472f88f97e860 100644 --- a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt @@ -4,8 +4,7 @@ mysqlnd.net_read_timeout limit check mysqli --SKIPIF-- default_socket_timeout mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_pam_sha256.phpt b/ext/mysqli/tests/mysqli_pam_sha256.phpt index 625e20ad4237e..5dc2ca8230eed 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256.phpt @@ -4,8 +4,6 @@ PAM: SHA-256 mysqli --SKIPIF-- --FILE-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); ?> diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt index 94db7fabe406c..42a9640f1ea99 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt @@ -4,8 +4,6 @@ PAM: SHA-256, mysqlnd.sha256_server_public_key mysqli --SKIPIF-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); $file = "test_sha256_ini"; diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt index 497a7300ca60b..e0abe65e24e44 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt @@ -4,8 +4,6 @@ PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY mysqli --SKIPIF-- --FILE-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd")); diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt index 3c6b53d43a7a2..5f13fa4f03f07 100644 --- a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt +++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt @@ -4,8 +4,6 @@ PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY (invalid) mysqli --SKIPIF-- --FILE-- --CLEAN-- query('DROP USER shatest'); $link->query('DROP USER shatest@localhost'); $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd")); diff --git a/ext/mysqli/tests/mysqli_pconn_kill.phpt b/ext/mysqli/tests/mysqli_pconn_kill.phpt index d53ed44995919..17af4fa42ec93 100644 --- a/ext/mysqli/tests/mysqli_pconn_kill.phpt +++ b/ext/mysqli/tests/mysqli_pconn_kill.phpt @@ -4,16 +4,14 @@ Killing a persistent connection. mysqli --SKIPIF-- --INI-- mysqli.allow_persistent=1 mysqli.max_persistent=2 --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_pconn_limits.phpt b/ext/mysqli/tests/mysqli_pconn_limits.phpt index 4dd65c18a1dd2..4d9f8eed01cad 100644 --- a/ext/mysqli/tests/mysqli_pconn_limits.phpt +++ b/ext/mysqli/tests/mysqli_pconn_limits.phpt @@ -4,8 +4,7 @@ Persistent connections - limits (-1, unlimited) mysqli --SKIPIF-- --INI-- mysqli.allow_persistent=1 @@ -13,9 +12,7 @@ mysqli.max_persistent=-1 mysqli.max_links=-1 --FILE-- --CLEAN-- --EXPECT-- Regular connection 1 - 'works..' diff --git a/ext/mysqli/tests/mysqli_poll_reference.phpt b/ext/mysqli/tests/mysqli_poll_reference.phpt index 359c26565f216..836870aeb7fb0 100644 --- a/ext/mysqli/tests/mysqli_poll_reference.phpt +++ b/ext/mysqli/tests/mysqli_poll_reference.phpt @@ -4,13 +4,13 @@ mysqli_poll() & references mysqli --SKIPIF-- --FILE-- --FILE-- --CLEAN-- --FILE-- @@ -15,7 +14,7 @@ mysqli.allow_persistent=1 mysqli.max_persistent=10 --FILE-- --CLEAN-- --EXPECTF-- Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d diff --git a/ext/mysqli/tests/mysqli_reconnect.phpt b/ext/mysqli/tests/mysqli_reconnect.phpt index 6cb13c5e36030..f5f2aca11bf6a 100644 --- a/ext/mysqli/tests/mysqli_reconnect.phpt +++ b/ext/mysqli/tests/mysqli_reconnect.phpt @@ -4,16 +4,15 @@ Trying implicit reconnect after wait_timeout and KILL using mysqli_ping() mysqli --SKIPIF-- --INI-- mysqli.reconnect=1 --FILE-- +--CLEAN-- + --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_release_savepoint.phpt b/ext/mysqli/tests/mysqli_release_savepoint.phpt index 64716524c3684..ec969f15cdad7 100644 --- a/ext/mysqli/tests/mysqli_release_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_release_savepoint.phpt @@ -4,20 +4,16 @@ mysqli_release_savepoint() mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli_release_savepoint(): Argument #2 ($name) cannot be empty diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index cb4010d0a87ec..110d25726cdbd 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -4,12 +4,10 @@ mysqli_report() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d diff --git a/ext/mysqli/tests/mysqli_report_new.phpt b/ext/mysqli/tests/mysqli_report_new.phpt index 9ef80da1d865c..e544bcb3664d6 100644 --- a/ext/mysqli/tests/mysqli_report_new.phpt +++ b/ext/mysqli/tests/mysqli_report_new.phpt @@ -4,9 +4,9 @@ mysqli_report(), change user, MySQL 5.6+ mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d diff --git a/ext/mysqli/tests/mysqli_report_wo_ps.phpt b/ext/mysqli/tests/mysqli_report_wo_ps.phpt index f030051dd5fc1..c757de773db50 100644 --- a/ext/mysqli/tests/mysqli_report_wo_ps.phpt +++ b/ext/mysqli/tests/mysqli_report_wo_ps.phpt @@ -4,9 +4,9 @@ mysqli_report(), MySQL < 5.6 mysqli --SKIPIF-- = 50600) ?> --FILE-- = 50600) if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_OFF))) printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - require('table.inc'); + require 'table.inc'; /* Internal macro MYSQL_REPORT_ERROR @@ -106,7 +101,7 @@ if (mysqli_get_server_version($link) >= 50600) ?> --CLEAN-- --EXPECTF-- Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d diff --git a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt index 61a60cb68735b..3a77078c69c58 100644 --- a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt @@ -4,15 +4,13 @@ References to result sets - mysqlnd (no copies but references) mysqli --SKIPIF-- --FILE-- +--CLEAN-- + --EXPECTF-- array(1) refcount(%d){ [0]=> diff --git a/ext/mysqli/tests/mysqli_rollback.phpt b/ext/mysqli/tests/mysqli_rollback.phpt index 0978308e8c3d3..2297a3351acba 100644 --- a/ext/mysqli/tests/mysqli_rollback.phpt +++ b/ext/mysqli/tests/mysqli_rollback.phpt @@ -4,18 +4,16 @@ mysqli_rollback() mysqli --SKIPIF-- errno, $link->error)); +if (!have_innodb($link)) + die(sprintf("skip Needs InnoDB support, [%d] %s", $link->errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_savepoint.phpt b/ext/mysqli/tests/mysqli_savepoint.phpt index a34c1aaee1366..71e0b2d21819e 100644 --- a/ext/mysqli/tests/mysqli_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_savepoint.phpt @@ -4,18 +4,16 @@ mysqli_savepoint() mysqli --SKIPIF-- errno, $link->error)); ?> --FILE-- --CLEAN-- --EXPECT-- mysqli_savepoint(): Argument #2 ($name) cannot be empty diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 075e193959e48..5ddc2f4aa8930 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -4,14 +4,12 @@ mysqli_set_charset() mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Exception: %s diff --git a/ext/mysqli/tests/mysqli_ssl_set.phpt b/ext/mysqli/tests/mysqli_ssl_set.phpt index 6abc84fb341b5..5ea79b964987c 100644 --- a/ext/mysqli/tests/mysqli_ssl_set.phpt +++ b/ext/mysqli/tests/mysqli_ssl_set.phpt @@ -4,13 +4,15 @@ mysqli_ssl_set() - test is a stub! mysqli --SKIPIF-- --FILE-- --FILE-- --CLEAN-- --EXPECT-- mysqli_stmt object is not fully initialized diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt index c7269e8cb47d6..3af364dfb550a 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt @@ -4,10 +4,9 @@ mysqli_stmt_execute() - Stored Procedures mysqli --SKIPIF-- --FILE-- --CLEAN-- --FILE-- --CLEAN-- --FILE-- --CLEAN-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt index 64a1b86340bf7..c3a68db0797df 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt @@ -4,20 +4,23 @@ Fetching BIT column values using the PS API mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt index 0dadb7bb4a1df..e372977844bba 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt @@ -4,11 +4,9 @@ mysqli_stmt_get_warnings() - TODO mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECT-- mysqli_stmt object is not fully initialized diff --git a/ext/mysqli/tests/mysqli_stmt_multires.phpt b/ext/mysqli/tests/mysqli_stmt_multires.phpt index 496fca4e4f6c3..7018a8b63e4f0 100644 --- a/ext/mysqli/tests/mysqli_stmt_multires.phpt +++ b/ext/mysqli/tests/mysqli_stmt_multires.phpt @@ -4,16 +4,14 @@ Multiple result set with PS mysqli --SKIPIF-- --FILE-- query('DROP PROCEDURE IF EXISTS p123')) { diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt index 21b0e4625dd32..57e371f360d9b 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt @@ -6,7 +6,7 @@ mysqli --FILE-- diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt index 07c2e144875cb..b11260cb0cac5 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt @@ -6,7 +6,7 @@ mysqli --FILE-- diff --git a/ext/mysqli/tests/mysqli_warning_unclonable.phpt b/ext/mysqli/tests/mysqli_warning_unclonable.phpt index f1aaad606b3bb..460334024b3ed 100644 --- a/ext/mysqli/tests/mysqli_warning_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_warning_unclonable.phpt @@ -4,14 +4,13 @@ Trying to clone mysqli_warning object mysqli --SKIPIF-- --FILE-- --CLEAN-- --EXPECTF-- Fatal error: Trying to clone an uncloneable object of class mysqli_warning in %s on line %d diff --git a/ext/mysqli/tests/skipifconnectfailure.inc b/ext/mysqli/tests/skipifconnectfailure.inc index ebdfae1a94b88..2e770426d4c0b 100644 --- a/ext/mysqli/tests/skipifconnectfailure.inc +++ b/ext/mysqli/tests/skipifconnectfailure.inc @@ -1,7 +1,6 @@ Date: Tue, 28 Dec 2021 09:52:27 +0100 Subject: [PATCH 047/227] Mark mysqli_driver properties readonly --- ext/mysqli/mysqli.stub.php | 3 +++ ext/mysqli/mysqli_arginfo.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index be0bbbc919b25..40f82e42e7036 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -4,10 +4,13 @@ final class mysqli_driver { + /** @readonly */ public string $client_info; + /** @readonly */ public int $client_version; + /** @readonly */ public int $driver_version; public bool $reconnect = false; diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index a0168a51c7a98..c177963d1548f 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 78662c05cd463735a8a4101c0357fd0d2698d48e */ + * Stub hash: baf4cb58df96edeb4fc14e4703fe9363cf5ed784 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) From 70b02d75f2abe3a292d49c4a4e9e4f850c2fee68 Mon Sep 17 00:00:00 2001 From: Jeremie Courreges-Anglas Date: Mon, 3 Jan 2022 11:57:29 +0100 Subject: [PATCH 048/227] riscv64 support for fibers We add riscv64 assembly files from Boost, needed for fibers support, and hook up riscv64 fibers support during configure. Closes GH-7879. --- NEWS | 1 + Zend/asm/jump_riscv64_sysv_elf_gas.S | 150 +++++++++++++++++++++++++++ Zend/asm/make_riscv64_sysv_elf_gas.S | 91 ++++++++++++++++ configure.ac | 2 + 4 files changed, 244 insertions(+) create mode 100644 Zend/asm/jump_riscv64_sysv_elf_gas.S create mode 100644 Zend/asm/make_riscv64_sysv_elf_gas.S diff --git a/NEWS b/NEWS index f28db7e2f40d3..b6fc1e949e34f 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PHP NEWS . Fixed bug GH-7757 (Multi-inherited final constant causes fatal error). (cmb) . Fixed zend_fibers.c build with ZEND_FIBER_UCONTEXT. (Petr Sumbera) + . Added riscv64 support for fibers. (Jeremie Courreges-Anglas) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/asm/jump_riscv64_sysv_elf_gas.S b/Zend/asm/jump_riscv64_sysv_elf_gas.S new file mode 100644 index 0000000000000..5417e5d5e3498 --- /dev/null +++ b/Zend/asm/jump_riscv64_sysv_elf_gas.S @@ -0,0 +1,150 @@ +/* + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | fs0 | fs1 | fs2 | fs3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | fs4 | fs5 | fs6 | fs7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | fs8 | fs9 | fs10 | fs11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | s0 | s1 | s2 | s3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | s4 | s5 | s6 | s7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * + * ------------------------------------------------- * + * | s8 | s9 | s10 | s11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | | | | | * + * ------------------------------------------------- * + * | 0xc0| 0xc4| 0xc8| 0xcc| | | | | * + * ------------------------------------------------- * + * | ra | pc | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.file "jump_riscv64_sysv_elf_gas.S" +.text +.align 1 +.global jump_fcontext +.type jump_fcontext, %function +jump_fcontext: + # prepare stack for GP + FPU + addi sp, sp, -0xd0 + + # save fs0 - fs11 + fsd fs0, 0x00(sp) + fsd fs1, 0x08(sp) + fsd fs2, 0x10(sp) + fsd fs3, 0x18(sp) + fsd fs4, 0x20(sp) + fsd fs5, 0x28(sp) + fsd fs6, 0x30(sp) + fsd fs7, 0x38(sp) + fsd fs8, 0x40(sp) + fsd fs9, 0x48(sp) + fsd fs10, 0x50(sp) + fsd fs11, 0x58(sp) + + # save s0-s11, ra + sd s0, 0x60(sp) + sd s1, 0x68(sp) + sd s2, 0x70(sp) + sd s3, 0x78(sp) + sd s4, 0x80(sp) + sd s5, 0x88(sp) + sd s6, 0x90(sp) + sd s7, 0x98(sp) + sd s8, 0xa0(sp) + sd s9, 0xa8(sp) + sd s10, 0xb0(sp) + sd s11, 0xb8(sp) + sd ra, 0xc0(sp) + + # save RA as PC + sd ra, 0xc8(sp) + + # store SP (pointing to context-data) in A2 + mv a2, sp + + # restore SP (pointing to context-data) from A0 + mv sp, a0 + + # load fs0 - fs11 + fld fs0, 0x00(sp) + fld fs1, 0x08(sp) + fld fs2, 0x10(sp) + fld fs3, 0x18(sp) + fld fs4, 0x20(sp) + fld fs5, 0x28(sp) + fld fs6, 0x30(sp) + fld fs7, 0x38(sp) + fld fs8, 0x40(sp) + fld fs9, 0x48(sp) + fld fs10, 0x50(sp) + fld fs11, 0x58(sp) + + # load s0-s11,ra + ld s0, 0x60(sp) + ld s1, 0x68(sp) + ld s2, 0x70(sp) + ld s3, 0x78(sp) + ld s4, 0x80(sp) + ld s5, 0x88(sp) + ld s6, 0x90(sp) + ld s7, 0x98(sp) + ld s8, 0xa0(sp) + ld s9, 0xa8(sp) + ld s10, 0xb0(sp) + ld s11, 0xb8(sp) + ld ra, 0xc0(sp) + + # return transfer_t from jump + # pass transfer_t as first arg in context function + # a0 == FCTX, a1 == DATA + mv a0, a2 + + # load pc + ld a2, 0xc8(sp) + + # restore stack from GP + FPU + addi sp, sp, 0xd0 + + jr a2 +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/Zend/asm/make_riscv64_sysv_elf_gas.S b/Zend/asm/make_riscv64_sysv_elf_gas.S new file mode 100644 index 0000000000000..5322e0fdbdec7 --- /dev/null +++ b/Zend/asm/make_riscv64_sysv_elf_gas.S @@ -0,0 +1,91 @@ +/* + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | fs0 | fs1 | fs2 | fs3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | fs4 | fs5 | fs6 | fs7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | fs8 | fs9 | fs10 | fs11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | s0 | s1 | s2 | s3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | s4 | s5 | s6 | s7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * + * ------------------------------------------------- * + * | s8 | s9 | s10 | s11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | | | | | * + * ------------------------------------------------- * + * | 0xc0| 0xc4| 0xc8| 0xcc| | | | | * + * ------------------------------------------------- * + * | ra | pc | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.file "make_riscv64_sysv_elf_gas.S" +.text +.align 1 +.global make_fcontext +.type make_fcontext, %function +make_fcontext: + # shift address in a0 (allocated stack) to lower 16 byte boundary + andi a0, a0, ~0xF + + # reserve space for context-data on context-stack + addi a0, a0, -0xd0 + + # third arg of make_fcontext() == address of context-function + # store address as a PC to jump in + sd a2, 0xc8(a0) + + # save address of finish as return-address for context-function + # will be entered after context-function returns (RA register) + lla a4, finish + sd a4, 0xc0(a0) + + ret // return pointer to context-data (a0) + +finish: + # exit code is zero + li a0, 0 + # exit application + tail _exit@plt + +.size make_fcontext,.-make_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/configure.ac b/configure.ac index 754603c149f7c..03403eee5efe2 100644 --- a/configure.ac +++ b/configure.ac @@ -1201,6 +1201,7 @@ AS_CASE([$host_cpu], [arm*], [fiber_cpu="arm32"], [ppc64*|powerpc64*], [fiber_cpu="ppc64"], [ppc*|powerpc*], [fiber_cpu="ppc32"], + [riscv64*], [fiber_cpu="riscv64"], [s390x*], [fiber_cpu="s390x"], [mips64*], [fiber_cpu="mips64"], [mips*], [fiber_cpu="mips32"], @@ -1220,6 +1221,7 @@ AS_CASE([$fiber_cpu], [arm32], [fiber_asm_file_prefix="arm_aapcs"], [ppc64], [fiber_asm_file_prefix="ppc64_sysv"], [ppc32], [fiber_asm_file_prefix="ppc32_sysv"], + [riscv64], [fiber_asm_file_prefix="riscv64_sysv"], [s390x], [fiber_asm_file_prefix="s390x_sysv"], [mips64], [fiber_asm_file_prefix="mips64_n64"], [mips32], [fiber_asm_file_prefix="mips32_o32"], From d70c69839cd84799484b4d74b6769a8ab3de326a Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 4 Jan 2022 09:40:46 -0300 Subject: [PATCH 049/227] Prepare for PHP 8.0.16 --- NEWS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7f2292bc4a732..f7a7a1eefa56a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 2022, PHP 8.0.15 +?? ??? 2022, PHP 8.0.16 + + +20 Jan 2022, PHP 8.0.15 - Core: . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) From f1d7f9570217a01e53bd62f82d27b74affd47c28 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 4 Jan 2022 13:08:33 +0100 Subject: [PATCH 050/227] [ci skip] Fix GH-7725: Adjust README instructions on referencing issues Also remove some references to git.php.net which is not used anymore. Closes GH-7882. --- README.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 18ee18a918489..e172501e92547 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,8 @@ Extension Community Library - [PECL](https://pecl.php.net). ## Contributing The PHP source code is located in the Git repository at -[git.php.net](https://git.php.net). Contributions are most welcome by forking -the [GitHub mirror repository](https://github.com/php/php-src) and sending a -pull request. +[github.com/php/php-src](https://github.com/php/php-src). Contributions are most +welcome by forking the repository and sending a pull request. Discussions are done on GitHub, but depending on the topic can also be relayed to the official PHP developer mailing list internals@lists.php.net. @@ -111,20 +110,15 @@ New features require an RFC and must be accepted by the developers. See [Voting on PHP features](https://wiki.php.net/rfc/voting) for more information on the process. -Bug fixes **do not** require an RFC but require a bug tracker ticket. Open a -ticket at [bugs.php.net](https://bugs.php.net) and reference the bug id using -`#NNNNNN`. +Bug fixes don't require an RFC. If the bug has a GitHub issue, reference it in +the commit message using `GH-NNNNNN`. Use `#NNNNNN` for tickets in the old +[bugs.php.net](https://bugs.php.net) bug tracker. + Fix GH-7815: php_uname doesn't recognise latest Windows versions Fix #55371: get_magic_quotes_gpc() throws deprecation warning - After removing magic quotes, the get_magic_quotes_gpc function caused a - deprecated warning. get_magic_quotes_gpc can be used to detect the - magic_quotes behavior and therefore should not raise a warning at any time. - The patch removes this warning. - -Pull requests are not merged directly on GitHub. All PRs will be pulled and -pushed through [git.php.net](https://git.php.net). See -[Git workflow](https://wiki.php.net/vcs/gitworkflow) for more details. +See [Git workflow](https://wiki.php.net/vcs/gitworkflow) for details on how pull +requests are merged. ### Guidelines for contributors From 09165ace379e15418034141394225794494be617 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 29 Dec 2021 08:53:56 +0000 Subject: [PATCH 051/227] Fix ext/sockets build on Haiku The `SOCK_RDM` datagram option is unsupported on Haiku; instead `ifreq` has direct access to `ifr_index`. Closes GH-7849. --- NEWS | 2 ++ ext/sockets/multicast.c | 2 +- ext/sockets/sockets.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f7a7a1eefa56a..1c1cdde218b10 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.16 +- Sockets: + . Fixed ext/sockets build on Haiku. (David Carlier) 20 Jan 2022, PHP 8.0.15 diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index 25203c0fbccae..d861d2f145ddf 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -718,7 +718,7 @@ int php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struct in_add return SUCCESS; } -#if !defined(ifr_ifindex) && defined(ifr_index) +#if !defined(ifr_ifindex) && (defined(ifr_index) || defined(__HAIKU__)) #define ifr_ifindex ifr_index #endif diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 16ad3e8013a4c..7976c9cc758a9 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -472,7 +472,9 @@ static PHP_MINIT_FUNCTION(sockets) REGISTER_LONG_CONSTANT("SOCK_DGRAM", SOCK_DGRAM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOCK_RAW", SOCK_RAW, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOCK_SEQPACKET",SOCK_SEQPACKET, CONST_CS | CONST_PERSISTENT); +#ifdef SOCK_RDM REGISTER_LONG_CONSTANT("SOCK_RDM", SOCK_RDM, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("MSG_OOB", MSG_OOB, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MSG_WAITALL", MSG_WAITALL, CONST_CS | CONST_PERSISTENT); From 4ae75623fdbc5330eb96ef6cb7d9571a2fcf9aca Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Tue, 4 Jan 2022 19:29:41 +0100 Subject: [PATCH 052/227] Preparing for 8.1.3-dev --- NEWS | 6 +++++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index f8e11f0374868..83931190930ad 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.2 +?? ??? ????, PHP 8.1.3 + + + +06 Jan 2022, PHP 8.1.2RC1 - Core: . Fixed bug #81216 (Nullsafe operator leaks dynamic property name). (Dmitry) diff --git a/Zend/zend.h b/Zend/zend.h index a5de7fc883bec..071901d4c5725 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.2-dev" +#define ZEND_VERSION "4.1.3-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 03403eee5efe2..4c111b8a9b3dd 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.2-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.3-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index a7f9fd6c283c9..e0e76bd6aaca1 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 -#define PHP_RELEASE_VERSION 2 +#define PHP_RELEASE_VERSION 3 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.2-dev" -#define PHP_VERSION_ID 80102 +#define PHP_VERSION "8.1.3-dev" +#define PHP_VERSION_ID 80103 From 46bec6de42be094edcf28cd70ded03358335a3f1 Mon Sep 17 00:00:00 2001 From: Stefano Arlandini Date: Tue, 28 Dec 2021 01:16:50 +0100 Subject: [PATCH 053/227] Fix the OpenMetrics response format returned by the FPM status page Closes GH-7843, closes GH-7842 --- NEWS | 4 ++++ sapi/fpm/fpm/fpm_status.c | 3 ++- sapi/fpm/tests/status.inc | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 83931190930ad..28d380f35920a 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,10 @@ PHP NEWS - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) +- FPM: + . Fixed bug GH-7842 (Invalid OpenMetrics response format returned by FPM + status page. (Stefano Arlandini) + - Hash: . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). (cmb) diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index b086566cc5498..24ac8afdc94be 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -430,7 +430,8 @@ int fpm_status_handle_request(void) /* {{{ */ "phpfpm_max_children_reached %u\n" "# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value.\n" "# TYPE phpfpm_slow_requests counter\n" - "phpfpm_slow_requests %lu\n"; + "phpfpm_slow_requests %lu\n" + "# EOF\n"; has_start_time = 0; if (!full) { diff --git a/sapi/fpm/tests/status.inc b/sapi/fpm/tests/status.inc index c8275567665f3..0e3f314b42209 100644 --- a/sapi/fpm/tests/status.inc +++ b/sapi/fpm/tests/status.inc @@ -241,7 +241,8 @@ class Status "phpfpm_max_children_reached " . $fields['max children reached'] . "\n" . "# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value\.\n" . "# TYPE phpfpm_slow_requests counter\n" . - "phpfpm_slow_requests " . $fields['slow requests'] . ")"; + "phpfpm_slow_requests " . $fields['slow requests'] . "\n" . + "# EOF)\n"; if (!preg_match($pattern, $body)) { echo "ERROR: Expected body does not match pattern\n"; From 0462719999230e16fed790d8e4b1532aa164db2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 22 Nov 2021 07:33:07 +0100 Subject: [PATCH 054/227] Fix class synopsis generation Closes GH-7891 --- build/gen_stub.php | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 5f74d26dbc37d..4e7a3cbb3c2c4 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1540,9 +1540,9 @@ public function getFieldSynopsisElement(DOMDocument $doc): DOMElement $fieldsynopsisElement->appendChild(new DOMText("\n ")); $fieldsynopsisElement->appendChild($this->getFieldSynopsisType()->getTypeForDoc($doc)); - $className = str_replace("\\", "-", $this->name->class->toLowerString()); + $className = str_replace(["\\", "_"], ["-", "-"], $this->name->class->toLowerString()); $varnameElement = $doc->createElement("varname", $this->name->property); - $varnameElement->setAttribute("linkend", "$className.props." . strtolower($this->name->property)); + $varnameElement->setAttribute("linkend", "$className.props." . strtolower(str_replace("_", "-", $this->name->property))); $fieldsynopsisElement->appendChild(new DOMText("\n ")); $fieldsynopsisElement->appendChild($varnameElement); @@ -1558,14 +1558,14 @@ public function getFieldSynopsisElement(DOMDocument $doc): DOMElement } private function getFieldSynopsisType(): Type { - if ($this->type) { - return $this->type; - } - if ($this->phpDocType) { return $this->phpDocType; } + if ($this->type) { + return $this->type; + } + throw new Exception("A property must have a type"); } @@ -2005,11 +2005,11 @@ private static function createOoElement( } public static function getClassSynopsisFilename(Name $name): string { - return strtolower(implode('-', $name->parts)); + return strtolower(str_replace("_", "-", implode('-', $name->parts))); } public static function getClassSynopsisReference(Name $name): string { - return "class." . strtolower(implode('-', $name->parts)); + return "class." . self::getClassSynopsisFilename($name); } /** @@ -2019,10 +2019,6 @@ public static function getClassSynopsisReference(Name $name): string { */ private function collectInheritedMembers(array &$parentsWithInheritedProperties, array &$parentsWithInheritedMethods, array $classMap): void { - if ($this->type !== "class") { - return; - } - foreach ($this->extends as $parent) { $parentInfo = $classMap[$parent->toString()] ?? null; if (!$parentInfo) { @@ -2033,7 +2029,7 @@ private function collectInheritedMembers(array &$parentsWithInheritedProperties, $parentsWithInheritedProperties[$parent->toString()] = $parent; } - if (!empty($parentInfo->funcInfos) && !isset($parentsWithInheritedMethods[$parent->toString()])) { + if (!isset($parentsWithInheritedMethods[$parent->toString()]) && $parentInfo->hasMethods()) { $parentsWithInheritedMethods[$parent->toString()] = $parent; } @@ -2986,12 +2982,14 @@ function replaceClassSynopses(string $targetDirectory, array $classMap): array $replacedXml = preg_replace( [ "/REPLACED-ENTITY-([A-Za-z0-9._{}%-]+?;)/", + "//i", "//i", "//i", "//i", ], [ "&$1", + "", "", "", "", From 62e4ac9439adbfee1f3330832f019c5cd79d2e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 6 Jan 2022 10:04:22 +0100 Subject: [PATCH 055/227] Add support for custom property links Closes GH-7892 --- build/gen_stub.php | 18 +++++++++++++++--- ext/mysqli/mysqli.stub.php | 31 +++++++++++++++++++++++++++++++ ext/mysqli/mysqli_arginfo.h | 2 +- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 4e7a3cbb3c2c4..486ff679499fc 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1398,6 +1398,8 @@ class PropertyInfo public $defaultValueString; /** @var bool */ public $isDocReadonly; + /** @var string|null */ + public $link; public function __construct( PropertyName $name, @@ -1406,7 +1408,8 @@ public function __construct( ?Type $phpDocType, ?Expr $defaultValue, ?string $defaultValueString, - bool $isDocReadonly + bool $isDocReadonly, + ?string $link ) { $this->name = $name; $this->flags = $flags; @@ -1415,6 +1418,7 @@ public function __construct( $this->defaultValue = $defaultValue; $this->defaultValueString = $defaultValueString; $this->isDocReadonly = $isDocReadonly; + $this->link = $link; } public function discardInfoForOldPhpVersions(): void { @@ -1542,7 +1546,11 @@ public function getFieldSynopsisElement(DOMDocument $doc): DOMElement $className = str_replace(["\\", "_"], ["-", "-"], $this->name->class->toLowerString()); $varnameElement = $doc->createElement("varname", $this->name->property); - $varnameElement->setAttribute("linkend", "$className.props." . strtolower(str_replace("_", "-", $this->name->property))); + if ($this->link) { + $varnameElement->setAttribute("linkend", $this->link); + } else { + $varnameElement->setAttribute("linkend", "$className.props." . strtolower(str_replace("_", "-", $this->name->property))); + } $fieldsynopsisElement->appendChild(new DOMText("\n ")); $fieldsynopsisElement->appendChild($varnameElement); @@ -2372,6 +2380,7 @@ function parseProperty( ): PropertyInfo { $phpDocType = null; $isDocReadonly = false; + $link = null; if ($comment) { $tags = parseDocComment($comment); @@ -2380,6 +2389,8 @@ function parseProperty( $phpDocType = $tag->getType(); } elseif ($tag->name === 'readonly') { $isDocReadonly = true; + } elseif ($tag->name === 'link') { + $link = $tag->value; } } } @@ -2407,7 +2418,8 @@ function parseProperty( $phpDocType ? Type::fromString($phpDocType) : null, $property->default, $property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null, - $isDocReadonly + $isDocReadonly, + $link ); } diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 40f82e42e7036..5add2523c54b9 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -20,40 +20,58 @@ final class mysqli_driver class mysqli { + /** @link mysqli.affected-rows */ public int|string $affected_rows; + /** @link mysqli.get-client-info */ public string $client_info; + /** @link mysqli.get-client-version */ public int $client_version; + /** @link mysqli.connect-errno */ public int $connect_errno; + /** @link mysqli.connect-error */ public ?string $connect_error; + /** @link mysqli.errno */ public int $errno; + /** @link mysqli.error */ public string $error; + /** @link mysqli.error-list */ public array $error_list; + /** @link mysqli.field-count */ public int $field_count; + /** @link mysqli.get-host-info */ public string $host_info; + /** @link mysqli.info */ public ?string $info; + /** @link mysqli.insert-id */ public int|string $insert_id; + /** @link mysqli.get-server-info */ public string $server_info; + /** @link mysqli.get-server-version */ public int $server_version; + /** @link mysqli.sqlstate */ public string $sqlstate; + /** @link mysqli.get-proto-info */ public int $protocol_version; + /** @link mysqli.thread-id */ public int $thread_id; + /** @link mysqli.warning-count */ public int $warning_count; public function __construct( @@ -355,12 +373,16 @@ public function refresh(int $flags): bool {} class mysqli_result implements IteratorAggregate { + /** @link mysqli-result.current-field */ public int $current_field; + /** @link mysqli-result.field-count */ public int $field_count; + /** @link mysqli-result.lengths */ public ?array $lengths; + /** @link mysqli-result.num-rows */ public int|string $num_rows; public int $type; @@ -458,22 +480,31 @@ public function getIterator(): Iterator {} class mysqli_stmt { + /** @link mysqli-stmt.affected-rows */ public int|string $affected_rows; + /** @link mysqli-stmt.insert-id */ public int|string $insert_id; + /** @link mysqli-stmt.num-rows */ public int|string $num_rows; + /** @link mysqli-stmt.param-count */ public int $param_count; + /** @link mysqli-stmt.field-count */ public int $field_count; + /** @link mysqli-stmt.errno */ public int $errno; + /** @link mysqli-stmt.error */ public string $error; + /** @link mysqli-stmt.error-list */ public array $error_list; + /** @link mysqli-stmt.sqlstate */ public string $sqlstate; public int $id; diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index c177963d1548f..b01179089a507 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: baf4cb58df96edeb4fc14e4703fe9363cf5ed784 */ + * Stub hash: 7901d2cbbf9663f2c0cc140870baed0fe04c2bd1 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) From 66eb96e7ad2d8a6d7f154feae505f2698240e7d7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 7 Jan 2022 14:02:40 +0100 Subject: [PATCH 056/227] Silence potential connection failure in SKIPIF section Otherwise the test will be reported as BORKED. --- ext/mysqli/tests/mysqli_fork.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt index 52c97306e5052..411b129387532 100644 --- a/ext/mysqli/tests/mysqli_fork.phpt +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -12,7 +12,7 @@ if (!function_exists('posix_getpid')) die("skip POSIX functions not available"); require_once 'connect.inc'; -if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); if (!have_innodb($link)) From 978108578283b41b56a129bea5f85c1bac7bf8a7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 5 Jan 2022 16:45:36 +0100 Subject: [PATCH 057/227] Fix ODBC test which may not properly clean up If these tests fail with a fatal error, they won't properly clean up, which likely causes other tests to fail as (several ODBC tests use the `odbcTEST` database and tables or stored procedures named `FOO`). This is particularly annoying during development, where you would need to clean up manually. We fix this by moving the cleanup code to the --CLEAN-- section, so that this code is executed no matter what. Closes GH-7886. --- ext/odbc/tests/odbc_exec_002.phpt | 8 +++++--- ext/odbc/tests/odbc_free_result_001.phpt | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/odbc/tests/odbc_exec_002.phpt b/ext/odbc/tests/odbc_exec_002.phpt index 309497e6c6b43..437532535af5a 100644 --- a/ext/odbc/tests/odbc_exec_002.phpt +++ b/ext/odbc/tests/odbc_exec_002.phpt @@ -21,11 +21,13 @@ $res = odbc_exec($conn, 'SELECT * FROM FOO'); var_dump(odbc_fetch_row($res)); var_dump(odbc_result($res, 'test')); var_dump(odbc_fetch_array($res)); - +?> +--CLEAN-- + --EXPECT-- bool(true) diff --git a/ext/odbc/tests/odbc_free_result_001.phpt b/ext/odbc/tests/odbc_free_result_001.phpt index 09b3e435fbb82..19660618f140e 100644 --- a/ext/odbc/tests/odbc_free_result_001.phpt +++ b/ext/odbc/tests/odbc_free_result_001.phpt @@ -37,11 +37,13 @@ try { } catch (TypeError $e) { echo $e->getMessage(), "\n"; } - +?> +--CLEAN-- + --EXPECT-- bool(true) From 51eec5086f0862d4dfab526b2f7d852d1d87502d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 7 Jan 2022 19:05:59 +0100 Subject: [PATCH 058/227] Run mb_send_mail tests on Windows, too We use the run-tests.php `{MAIL}` abstraction instead of `cat`. Closes GH-7908. --- ext/mbstring/tests/bug52681.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail01.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail02.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail03.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail04.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail05.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail06.phpt | 11 +++++++---- ext/mbstring/tests/mb_send_mail07.phpt | 11 +++++++---- 8 files changed, 56 insertions(+), 32 deletions(-) diff --git a/ext/mbstring/tests/bug52681.phpt b/ext/mbstring/tests/bug52681.phpt index 2086051e9412d..86295d3385dcd 100644 --- a/ext/mbstring/tests/bug52681.phpt +++ b/ext/mbstring/tests/bug52681.phpt @@ -4,15 +4,12 @@ Bug #52681 (mb_send_mail() appends an extra MIME-Version header) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/bug52681.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com diff --git a/ext/mbstring/tests/mb_send_mail01.phpt b/ext/mbstring/tests/mb_send_mail01.phpt index a71e212543624..4387d9f817433 100644 --- a/ext/mbstring/tests/mb_send_mail01.phpt +++ b/ext/mbstring/tests/mb_send_mail01.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 1 (lang=neutral) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail01.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail02.phpt b/ext/mbstring/tests/mb_send_mail02.phpt index 13f9dd0974775..edc4093825af6 100644 --- a/ext/mbstring/tests/mb_send_mail02.phpt +++ b/ext/mbstring/tests/mb_send_mail02.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 2 (lang=Japanese) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail02.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail03.phpt b/ext/mbstring/tests/mb_send_mail03.phpt index 124c94834e6cb..53cbf00a60f19 100644 --- a/ext/mbstring/tests/mb_send_mail03.phpt +++ b/ext/mbstring/tests/mb_send_mail03.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 3 (lang=English) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail03.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail04.phpt b/ext/mbstring/tests/mb_send_mail04.phpt index bf5bfef578bd0..2251771469e16 100644 --- a/ext/mbstring/tests/mb_send_mail04.phpt +++ b/ext/mbstring/tests/mb_send_mail04.phpt @@ -4,15 +4,12 @@ mb_send_mail() test 4 (lang=German) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail04.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail05.phpt b/ext/mbstring/tests/mb_send_mail05.phpt index b03ce8748e61f..251b918bdb85b 100644 --- a/ext/mbstring/tests/mb_send_mail05.phpt +++ b/ext/mbstring/tests/mb_send_mail05.phpt @@ -4,9 +4,6 @@ mb_send_mail() test 5 (lang=Simplified Chinese) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail05.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail06.phpt b/ext/mbstring/tests/mb_send_mail06.phpt index 2a81a4a482115..d2fd7a9bbf3ab 100644 --- a/ext/mbstring/tests/mb_send_mail06.phpt +++ b/ext/mbstring/tests/mb_send_mail06.phpt @@ -4,9 +4,6 @@ mb_send_mail() test 6 (lang=Traditional Chinese) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail06.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s diff --git a/ext/mbstring/tests/mb_send_mail07.phpt b/ext/mbstring/tests/mb_send_mail07.phpt index 56368942cfd13..662426a47d833 100644 --- a/ext/mbstring/tests/mb_send_mail07.phpt +++ b/ext/mbstring/tests/mb_send_mail07.phpt @@ -4,9 +4,6 @@ mb_send_mail() test 7 (lang=Korean) mbstring --SKIPIF-- --INI-- -sendmail_path=/bin/cat +sendmail_path={MAIL:{PWD}/mb_send_mail07.eml} mail.add_x_header=off --FILE-- +--CLEAN-- + --EXPECTF-- To: example@example.com Subject: %s From 9e80947e343b253e078abfc9d1d4f800342c26f8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 8 Jan 2022 19:57:54 +0100 Subject: [PATCH 059/227] VS 17 == MSVC v143 == Visual Studio 2022 == cl 19.3x --- win32/build/confutils.js | 6 ++++-- win32/winutil.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 1b12c4a8ff77f..9bf1bf28141d4 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -3101,9 +3101,11 @@ function toolset_get_compiler_name(short) version = probe_binary(PHP_CL).substr(0, 5).replace('.', ''); - if (version >= 1930) { + if (version >= 1940) { return name; - } if (version >= 1920) { + } else if (version >= 1930) { + name = short ? "VS17" : "Visual C++ 2022"; + } else if (version >= 1920) { /* NOTE - VS is intentional. Due to changes in recent Visual Studio versioning scheme referring to the exact VC++ version is hardly predictable. From this version on, it refers to diff --git a/win32/winutil.c b/win32/winutil.c index 3d41873310f6a..e09944d131b9b 100644 --- a/win32/winutil.c +++ b/win32/winutil.c @@ -448,7 +448,7 @@ static zend_always_inline BOOL is_compatible(HMODULE handle, BOOL is_smaller, ch DWORD minor = pNTHeader->OptionalHeader.MinorLinkerVersion; #if PHP_LINKER_MAJOR == 14 - /* VS 2015, 2017 and 2019 are binary compatible, but only forward compatible. + /* VS 2015, 2017, 2019 and 2022 are binary compatible, but only forward compatible. It should be fine, if we load a module linked with an older one into the core linked with the newer one, but not the otherway round. Analogously, it should be fine, if a PHP build linked with an older version From c99a026c9ccdd7c06f1774187552746fb0e5affc Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 8 Jan 2022 07:48:28 +0000 Subject: [PATCH 060/227] Fix memory leak on invalid port Closes GH-7911. --- NEWS | 3 +++ sapi/fpm/fpm/fpm_sockets.c | 1 + 2 files changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 1c1cdde218b10..0e0fe4f352674 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.16 +- FPM: + . Fixed memory leak on invalid port. (David Carlier) + - Sockets: . Fixed ext/sockets build on Haiku. (David Carlier) diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index c9c0acc7b738b..99205a8fcf968 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -336,6 +336,7 @@ static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /* if (port == 0) { zlog(ZLOG_ERROR, "invalid port value '%s'", port_str); + free(dup_address); return -1; } From 2f6a06ccb0ef78e6122bb9e67f9b8b1ad07776e1 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 5 Jan 2022 11:09:25 +0100 Subject: [PATCH 061/227] Fix #81430: Attribute instantiation leaves dangling pointer By switching attribute constructor stackframe to be called via trampoline the stack allocation is not causing dangling pointers in the zend_observer API anymore. Co-Authored-By: Florian Sowade Co-Authored-By: Christopher Becker Co-Authored-By: Dmitry Stogov Closes GH-7885. --- NEWS | 4 +++ ext/reflection/php_reflection.c | 1 + ext/zend_test/tests/observer_bug81430_1.phpt | 31 ++++++++++++++++++ ext/zend_test/tests/observer_bug81430_2.phpt | 33 ++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 ext/zend_test/tests/observer_bug81430_1.phpt create mode 100644 ext/zend_test/tests/observer_bug81430_2.phpt diff --git a/NEWS b/NEWS index 0e0fe4f352674..0490d3701cca0 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.16 +- Core: + . Fixed bug #81430 (Attribute instantiation leaves dangling pointer). + (beberlei) + - FPM: . Fixed memory leak on invalid port. (David Carlier) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index f9b888f1c166b..61df70c4ec8a4 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6315,6 +6315,7 @@ static int call_attribute_constructor( dummy_func.type = ZEND_USER_FUNCTION; dummy_func.common.fn_flags = attr->flags & ZEND_ATTRIBUTE_STRICT_TYPES ? ZEND_ACC_STRICT_TYPES : 0; + dummy_func.common.fn_flags |= ZEND_ACC_CALL_VIA_TRAMPOLINE; dummy_func.op_array.filename = filename; dummy_opline.opcode = ZEND_DO_FCALL; diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt new file mode 100644 index 0000000000000..cac53ef70cbbb --- /dev/null +++ b/ext/zend_test/tests/observer_bug81430_1.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #81430 (Attribute instantiation frame accessing invalid frame pointer) +--EXTENSIONS-- +zend_test +--INI-- +memory_limit=20M +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +--FILE-- +getAttributes(A::class)[0], 'newInstance']); +?> +--EXPECTF-- + + + + + + diff --git a/ext/zend_test/tests/observer_bug81430_2.phpt b/ext/zend_test/tests/observer_bug81430_2.phpt new file mode 100644 index 0000000000000..4d56248a80f34 --- /dev/null +++ b/ext/zend_test/tests/observer_bug81430_2.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #81430 (Attribute instantiation leaves dangling execute_data pointer) +--EXTENSIONS-- +zend_test +--INI-- +memory_limit=20M +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +--FILE-- +getAttributes(A::class)[0], 'newInstance']); +?> +--EXPECTF-- + + + + + +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d + + From be22018f35aecb96a84dc7e7f36253031b7a703f Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 9 Jan 2022 17:10:21 +0000 Subject: [PATCH 062/227] Fix pcntl_rfork build for DragonFlyBSD RFTSIGZMB flag unsupported, guarding with the said flag instead of system in case the implementaion catches up with FreeBSD's. Closes GH-7918. --- NEWS | 3 +++ ext/pcntl/pcntl.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 887abf3a90dc0..a285a9bb8b14b 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,9 @@ PHP NEWS - FPM: . Fixed memory leak on invalid port. (David Carlier) +- pcntl: + . Fixed pcntl_rfork build for DragonFlyBSD. (David Carlier) + 06 Jan 2022, PHP 8.1.2RC1 - Core: diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 54ed5c4b90e91..c1c99ab9a8d85 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1528,9 +1528,11 @@ PHP_FUNCTION(pcntl_rfork) flags |= RFPROC; } +#ifdef RFTSIGZMB if ((flags & RFTSIGZMB) != 0) { flags |= RFTSIGFLAGS(csignal); } +#endif pid = rfork(flags); From 4170d41a66d913b672e7f76d528aea2fe15d21de Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 15:37:36 +0300 Subject: [PATCH 063/227] JIT: Fix incorrect FETCH_THIS elimination Fizex oss-fuzz #43159 --- ext/opcache/jit/zend_jit_trace.c | 18 ++++++++++++++++-- ext/opcache/tests/jit/assign_obj_op_001.phpt | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_obj_op_001.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 9a310d3e35197..d885fe84cb3ea 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3147,8 +3147,9 @@ static void zend_jit_trace_setup_ret_counter(const zend_op *opline, size_t offse } } -static zend_bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ssa_opcodes, int var) +static zend_bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ssa *ssa, const zend_op **ssa_opcodes, const zend_ssa_op *ssa_op) { + int var = ssa_op->result_def; int i; int use = ssa->vars[var].use_chain; const zend_op *opline; @@ -3189,6 +3190,19 @@ static zend_bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ss return 0; } + if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { + if (opline->op1_type == IS_CV + && (opline+1)->op1_type == IS_CV + && (opline+1)->op1.var == opline->op1.var) { + /* skip $a->prop += $a; */ + return 0; + } + if (!zend_jit_supported_binary_op( + opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { + return 0; + } + } + for (i = ssa->vars[var].definition; i < use; i++) { if (ssa_opcodes[i]->opcode == ZEND_DO_UCALL || ssa_opcodes[i]->opcode == ZEND_DO_FCALL_BY_NAME @@ -5610,7 +5624,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_FETCH_THIS: delayed_fetch_this = 0; if (ssa_op->result_def >= 0 && opline->result_type != IS_CV) { - if (zend_jit_may_delay_fetch_this(ssa, ssa_opcodes, ssa_op->result_def)) { + if (zend_jit_may_delay_fetch_this(op_array, ssa, ssa_opcodes, ssa_op)) { ssa->var_info[ssa_op->result_def].delayed_fetch_this = 1; delayed_fetch_this = 1; } diff --git a/ext/opcache/tests/jit/assign_obj_op_001.phpt b/ext/opcache/tests/jit/assign_obj_op_001.phpt new file mode 100644 index 0000000000000..65ed5f7844a11 --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_op_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ASSIGN_OBJ_OP: Unsupported types +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +y.=[];})->call($test); +?> +--EXPECTF-- +Warning: Undefined property: Test::$y in %sassign_obj_op_001.php on line 6 + +Warning: Array to string conversion in %sassign_obj_op_001.php on line 6 From b80d30d821e64de96c36d24e7e931028678750de Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 16:03:54 +0300 Subject: [PATCH 064/227] Fix type inference for assign to string offset with invalid index. Fixes oss-fuzz #43277 --- ext/opcache/Optimizer/zend_inference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 46f0f1e076a9c..a1eff0ceb6550 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2623,7 +2623,7 @@ static zend_always_inline int _zend_update_type_info( if (ssa_op->result_def >= 0) { tmp = 0; if (t1 & MAY_BE_STRING) { - tmp |= MAY_BE_STRING; + tmp |= MAY_BE_STRING | MAY_BE_NULL; } if (t1 & (MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL|MAY_BE_UNDEF)) { tmp |= (OP1_DATA_INFO() & (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF)); From 71d650134639c0d2db45e004e6a847fbf1dc8ce9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 16:05:40 +0300 Subject: [PATCH 065/227] Added test --- ext/opcache/tests/jit/assign_dim_006.phpt | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_006.phpt diff --git a/ext/opcache/tests/jit/assign_dim_006.phpt b/ext/opcache/tests/jit/assign_dim_006.phpt new file mode 100644 index 0000000000000..d97663dc89fb3 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_006.phpt @@ -0,0 +1,29 @@ +--TEST-- +JIT ASSIGN_DIM: 006 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 + +Warning: Illegal string offset -5 in %sassign_dim_006.php on line 5 +NULL From 491793ae67982bd87c33abeb3bd0bca13dbbcc45 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 16:37:49 +0300 Subject: [PATCH 066/227] Fixed test --- ext/opcache/tests/jit/assign_obj_op_001.phpt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/opcache/tests/jit/assign_obj_op_001.phpt b/ext/opcache/tests/jit/assign_obj_op_001.phpt index 65ed5f7844a11..cb7c9a0b39e8a 100644 --- a/ext/opcache/tests/jit/assign_obj_op_001.phpt +++ b/ext/opcache/tests/jit/assign_obj_op_001.phpt @@ -14,6 +14,8 @@ $test = new Test; (function(){$this->y.=[];})->call($test); ?> --EXPECTF-- +Deprecated: Creation of dynamic property Test::$y is deprecated in %sassign_obj_op_001.php on line 6 + Warning: Undefined property: Test::$y in %sassign_obj_op_001.php on line 6 Warning: Array to string conversion in %sassign_obj_op_001.php on line 6 From c958ab121b087adb49e6db992fa8a97755ac6e22 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 17:27:00 +0300 Subject: [PATCH 067/227] JIT: Fix array separation after capturing by user error handler Fixes oss-fuzz #43288 --- ext/opcache/jit/zend_jit_helpers.c | 10 ++++++++- ext/opcache/tests/jit/assign_dim_007.phpt | 27 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/assign_dim_007.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 9a905c4c0175f..f1a24ea856b90 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1413,6 +1413,8 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval ZVAL_NULL(result); return; } + SEPARATE_ARRAY(object_ptr); + arr = Z_ARRVAL_P(object_ptr); zval *var; if (dim) { if (type == BP_VAR_W) { @@ -1517,6 +1519,8 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim } return; } + SEPARATE_ARRAY(object_ptr); + arr = Z_ARRVAL_P(object_ptr); zval *var = dim ? zend_jit_fetch_dim_w_helper(arr, dim) : zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval)); @@ -1595,6 +1599,8 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d zend_array_destroy(arr); return; } + SEPARATE_ARRAY(container); + arr = Z_ARRVAL_P(container); zval *var = dim ? zend_jit_fetch_dim_rw_helper(arr, dim) : zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval)); @@ -2371,9 +2377,11 @@ static zval * ZEND_FASTCALL zend_jit_prepare_assign_dim_ref(zval *ref) { return NULL; } if (Z_TYPE_P(val) == IS_FALSE) { + ZVAL_ARR(val, zend_new_array(8)); zend_false_to_array_deprecated(); + } else { + ZVAL_ARR(val, zend_new_array(8)); } - ZVAL_ARR(val, zend_new_array(8)); } return val; } diff --git a/ext/opcache/tests/jit/assign_dim_007.phpt b/ext/opcache/tests/jit/assign_dim_007.phpt new file mode 100644 index 0000000000000..c4aa228df3391 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_007.phpt @@ -0,0 +1,27 @@ +--TEST-- +JIT ASSIGN_DIM: 007 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECT-- +array(0) { +} +array(1) { + [0]=> + int(1) +} From 698ac23711503cb3a2c0ae1965447598597ac468 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 19:39:19 +0300 Subject: [PATCH 068/227] Fixed NAN handling in SCCP Fixes oss-fuzz #43341 --- ext/opcache/Optimizer/sccp.c | 3 ++- ext/opcache/tests/opt/sccp_036.phpt | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/sccp_036.phpt diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 0818a20e0bf97..64cfa676965d4 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -183,7 +183,8 @@ static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, zval *new) { } #if ZEND_DEBUG - ZEND_ASSERT(zend_is_identical(value, new)); + ZEND_ASSERT(zend_is_identical(value, new) || + (Z_TYPE_P(value) == IS_DOUBLE && Z_TYPE_P(new) == IS_DOUBLE && isnan(Z_DVAL_P(value)) && isnan(Z_DVAL_P(new)))); #endif } diff --git a/ext/opcache/tests/opt/sccp_036.phpt b/ext/opcache/tests/opt/sccp_036.phpt new file mode 100644 index 0000000000000..ce660ce1aad30 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_036.phpt @@ -0,0 +1,16 @@ +--TEST-- +SCCP 036: NAN handling +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECT-- +DONE From 796511f324d7e63a6e12a2783f8cfc0b45932424 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 9 Jan 2022 13:55:26 +0100 Subject: [PATCH 069/227] Fix php-cgi name in usage info Cf. . Closes GH-7916. --- sapi/cgi/cgi_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 75511ef3bd701..7d5f444d1c54a 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1020,7 +1020,7 @@ static void php_cgi_usage(char *argv0) if (prog) { prog++; } else { - prog = "php"; + prog = "php-cgi"; } php_printf( "Usage: %s [-q] [-h] [-s] [-v] [-i] [-f ]\n" From 1f58365438ca10662fff1a27298969cf29d2688c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 21:53:35 +0300 Subject: [PATCH 070/227] Fix type inference Fixes oss-fuzz #43367 --- ext/opcache/Optimizer/zend_inference.c | 3 --- ext/opcache/tests/jit/assign_dim_008.phpt | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_dim_008.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index a1eff0ceb6550..d3a483b889756 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2636,9 +2636,6 @@ static zend_always_inline int _zend_update_type_info( tmp |= MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING; } } - if (t1 & MAY_BE_OBJECT) { - tmp |= MAY_BE_REF; - } tmp |= MAY_BE_RC1 | MAY_BE_RCN; UPDATE_SSA_TYPE(tmp, ssa_op->result_def); } diff --git a/ext/opcache/tests/jit/assign_dim_008.phpt b/ext/opcache/tests/jit/assign_dim_008.phpt new file mode 100644 index 0000000000000..c0150809e40f6 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_008.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT ASSIGN_DIM: 008 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 4543cd32ae3cf0431963e729b22c0ed0c6cadb1f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Dec 2021 16:49:34 +0100 Subject: [PATCH 071/227] Remove JMPZNZ opcode While JMPZNZ can avoid execution of a separate JMP opcode in some cases, it also prevents smart branch optimization, so creating JMPZNZ may actually have a negative effect. It also adds additional complexity for optimizations. Drop JMPZNZ in favor of JMPZ+JMP or JMPNZ+JMP. Closes GH-7857. --- Zend/Optimizer/block_pass.c | 163 +- Zend/Optimizer/dce.c | 1 - Zend/Optimizer/dfa_pass.c | 48 - Zend/Optimizer/pass1.c | 17 - Zend/Optimizer/pass3.c | 95 -- Zend/Optimizer/sccp.c | 1 - Zend/Optimizer/zend_cfg.c | 14 +- Zend/Optimizer/zend_cfg.h | 1 - Zend/Optimizer/zend_inference.c | 1 - Zend/Optimizer/zend_optimizer.c | 12 - Zend/Optimizer/zend_ssa.c | 1 - Zend/zend_opcode.c | 4 - Zend/zend_vm_def.h | 35 - Zend/zend_vm_execute.h | 491 ++---- Zend/zend_vm_handlers.h | 2368 +++++++++++++-------------- Zend/zend_vm_opcodes.c | 4 +- Zend/zend_vm_opcodes.h | 1 - ext/opcache/jit/zend_jit.c | 33 +- ext/opcache/jit/zend_jit_arm64.dasc | 132 -- ext/opcache/jit/zend_jit_trace.c | 11 +- ext/opcache/jit/zend_jit_x86.dasc | 133 -- ext/opcache/zend_file_cache.c | 6 - ext/opcache/zend_persist.c | 3 - 23 files changed, 1376 insertions(+), 2199 deletions(-) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 4a88c58abc13a..a9c73306e14e4 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -613,53 +613,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } break; - case ZEND_JMPZNZ: - while (1) { - if (opline->op1_type == IS_CONST) { - ++(*opt_count); - if (zend_is_true(&ZEND_OP1_LITERAL(opline))) { - zend_op *target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - block->successors[0] = block->successors[1]; - } else { - zend_op *target_opline = ZEND_OP2_JMP_ADDR(opline); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - } - block->successors_count = 1; - opline->op1_type = IS_UNUSED; - opline->extended_value = 0; - opline->opcode = ZEND_JMP; - break; - } else if (opline->op1_type == IS_TMP_VAR && - !zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) { - src = VAR_SOURCE(opline->op1); - if (src) { - if (src->opcode == ZEND_BOOL_NOT) { - /* T = BOOL_NOT(X) + JMPZNZ(T,L1,L2) -> NOP, JMPZNZ(X,L2,L1) */ - uint32_t tmp; - - VAR_SOURCE(opline->op1) = NULL; - COPY_NODE(opline->op1, src->op1); - tmp = block->successors[0]; - block->successors[0] = block->successors[1]; - block->successors[1] = tmp; - MAKE_NOP(src); - ++(*opt_count); - continue; - } else if (src->opcode == ZEND_BOOL || - src->opcode == ZEND_QM_ASSIGN) { - VAR_SOURCE(opline->op1) = NULL; - COPY_NODE(opline->op1, src->op1); - MAKE_NOP(src); - ++(*opt_count); - continue; - } - } - } - break; - } - break; - case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: while (1) { @@ -1025,9 +978,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op case ZEND_JMP: ZEND_SET_OP_JMP_ADDR(opline, opline->op1, new_opcodes + blocks[b->successors[0]].start); break; - case ZEND_JMPZNZ: - opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[1]].start); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1239,20 +1189,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr block->len--; } else if (target_block->len == 1) { target = op_array->opcodes + target_block->start; - if (target->opcode == ZEND_JMPZNZ) { - /* JMP L, L: JMPZNZ L1,L2 -> JMPZNZ L1,L2 */ - *last_op = *target; - if (last_op->op1_type == IS_CONST) { - zval zv; - ZVAL_COPY(&zv, &ZEND_OP1_LITERAL(last_op)); - last_op->op1.constant = zend_optimizer_add_literal(op_array, &zv); - } - block->successors_count = 2; - block->successors[0] = target_block->successors[0]; - block->successors[1] = target_block->successors[1]; - ++(*opt_count); - goto optimize_jmpznz; - } else if ((target->opcode == ZEND_RETURN || + if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || target->opcode == ZEND_GENERATOR_RETURN || target->opcode == ZEND_EXIT) && @@ -1311,10 +1248,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr SAME_VAR(target->op1, last_op->op1)) { /* JMPZ(X, L), L: JMPNZ(X, L2) -> JMPZ(X, L+1) */ next = target_block->successors[1]; - } else if (target->opcode == ZEND_JMPZNZ && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZ(X, L), L: JMPZNZ(X, L2, L3) -> JMPZ(X, L2) */ - next = target_block->successors[last_op->opcode == ZEND_JMPNZ]; } else { break; } @@ -1366,16 +1299,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr break; } } - - /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ - if (last_op->opcode == ZEND_JMPZ) { - block->successors[1] = follow_block->successors[0]; - } else { - block->successors[1] = block->successors[0]; - block->successors[0] = follow_block->successors[0]; - } - last_op->opcode = ZEND_JMPZNZ; - ++(*opt_count); } } break; @@ -1402,11 +1325,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr SAME_VAR(target->op1, last_op->op1))) { /* T = JMPZ_EX(X, L1), L1: T = JMPZ_EX({X|T}, L2) -> T = JMPZ_EX(X, L2) */ next = target_block->successors[0]; - } else if (target->opcode == ZEND_JMPZNZ && - (SAME_VAR(target->op1, last_op->result) || - SAME_VAR(target->op1, last_op->op1))) { - /* T = JMPZ_EX(X, L), L: JMPZNZ({X|T}, L2, L3) -> T = JMPZ_EX(X, L2) */ - next = target_block->successors[last_op->opcode == ZEND_JMPNZ_EX]; } else if (target->opcode == INV_EX_COND(last_op->opcode) && (SAME_VAR(target->op1, last_op->result) || SAME_VAR(target->op1, last_op->op1))) { @@ -1453,85 +1371,6 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr break; } break; - - case ZEND_JMPZNZ: { -optimize_jmpznz: - jmp_hitlist_count = 0; - target_block = get_target_block(cfg, block, 0, opt_count); - while (target_block->len == 1) { - target = op_array->opcodes + target_block->start; - - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X, L1, L2), L1: JMP(L3) -> JMPZNZ(X, L3, L2) */ - next = target_block->successors[0]; - } else if ((target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - next = target_block->successors[0]; - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */ - next = target_block->successors[1]; - } else { - break; - } - CHECK_LOOP(next); - block->successors[0] = next; - ++(*opt_count); - target_block = get_target_block(cfg, block, 0, opt_count); - } - - jmp_hitlist_count = 0; - follow_block = get_target_block(cfg, block, 1, opt_count); - while (follow_block->len == 1) { - target = op_array->opcodes + follow_block->start; - - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X, L1, L2), L2: JMP(L3) -> JMPZNZ(X, L1, L3) */ - next = follow_block->successors[0]; - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L2: X = JMPNZ(X, L3) -> JMPZNZ(X, L1, L3) */ - next = follow_block->successors[0]; - } else if ((target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) && - SAME_VAR(target->op1, last_op->op1)) { - /* JMPZNZ(X, L1, L2), L2: JMPZ(X, L3) -> JMPZNZ(X, L1, L2+1) */ - next = follow_block->successors[1]; - } else { - break; - } - CHECK_LOOP(next); - block->successors[1] = next; - ++(*opt_count); - follow_block = get_target_block(cfg, block, 1, opt_count); - } - - next_block = get_next_block(cfg, block); - if (target_block == follow_block && - !(last_op->op1_type & (IS_VAR|IS_TMP_VAR))) { - /* JMPZNZ(?,L,L) -> JMP(L) */ - last_op->opcode = ZEND_JMP; - SET_UNUSED(last_op->op1); - SET_UNUSED(last_op->op2); - last_op->extended_value = 0; - block->successors_count = 1; - ++(*opt_count); - } else if (target_block == next_block) { - /* jumping to next on Z - can follow to it and jump only on NZ */ - /* JMPZNZ(X,L1,L2) L1: -> JMPNZ(X,L2) */ - int tmp = block->successors[0]; - last_op->opcode = ZEND_JMPNZ; - block->successors[0] = block->successors[1]; - block->successors[1] = tmp; - ++(*opt_count); - } else if (follow_block == next_block) { - /* jumping to next on NZ - can follow to it and jump only on Z */ - /* JMPZNZ(X,L1,L2) L2: -> JMPZ(X,L1) */ - last_op->opcode = ZEND_JMPZ; - ++(*opt_count); - } - break; - } } } diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index 087add4cbed66..6c7358daff266 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -139,7 +139,6 @@ static inline bool may_have_side_effects( case ZEND_JMP: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 114a1b8ce243a..bcd114ecfbb94 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -627,11 +627,6 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa ZEND_ASSERT(ZEND_OP1_JMP_ADDR(opline) == op_array->opcodes + old->start); ZEND_SET_OP_JMP_ADDR(opline, opline->op1, op_array->opcodes + dst->start); break; - case ZEND_JMPZNZ: - if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) == old->start) { - opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, dst->start); - } - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -809,49 +804,6 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) } } break; - case ZEND_JMPZNZ: - if (opline->op1_type == IS_CONST) { - if (zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) { - zend_op *target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - take_successor_1(ssa, block_num, block); - } else { - zend_op *target_opline = ZEND_OP2_JMP_ADDR(opline); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - take_successor_0(ssa, block_num, block); - } - opline->op1_type = IS_UNUSED; - opline->extended_value = 0; - opline->opcode = ZEND_JMP; - goto optimize_jmp; - } else if (block->successors_count == 2) { - if (block->successors[0] == block->successors[1]) { - take_successor_0(ssa, block_num, block); - if (block->successors[0] == next_block_num && can_follow) { - if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_UNDEF)) { - opline->opcode = ZEND_CHECK_VAR; - opline->op2.num = 0; - } else if (opline->op1_type == IS_CV || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - zend_ssa_remove_instr(ssa, opline, ssa_op); - removed_ops++; - goto optimize_nop; - } else { - opline->opcode = ZEND_FREE; - opline->op2.num = 0; - } - } else if ((opline->op1_type == IS_CV && !(OP1_INFO() & MAY_BE_UNDEF)) || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - ZEND_ASSERT(ssa_op->op1_use >= 0); - zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use); - ssa_op->op1_use = -1; - ssa_op->op1_use_chain = -1; - opline->opcode = ZEND_JMP; - opline->op1_type = IS_UNUSED; - opline->op1.num = opline->op2.num; - goto optimize_jmp; - } - } - } - break; case ZEND_JMPZ_EX: if (ssa->vars[ssa_op->result_def].use_chain < 0 && ssa->vars[ssa_op->result_def].phi_use_chain == NULL) { diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 4a8f4d4f8ecf9..770f4ce2dc231 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -335,23 +335,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) collect_constants = 0; break; - case ZEND_JMPZNZ: - if (opline->op1_type == IS_CONST) { - zend_op *target_opline; - - if (zend_is_true(&ZEND_OP1_LITERAL(opline))) { - target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); /* JMPNZ */ - } else { - target_opline = ZEND_OP2_JMP_ADDR(opline); /* JMPZ */ - } - literal_dtor(&ZEND_OP1_LITERAL(opline)); - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - opline->op1_type = IS_UNUSED; - opline->opcode = ZEND_JMP; - } - collect_constants = 0; - break; - case ZEND_RETURN: case ZEND_RETURN_BY_REF: case ZEND_GENERATOR_RETURN: diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 39e1d65c20806..93e431fece440 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -86,19 +86,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (target == opline + 1) { /* convert L: JMP L+1 to NOP */ MAKE_NOP(opline); - } else if (target->opcode == ZEND_JMPZNZ) { - /* JMP L, L: JMPZNZ L1,L2 -> JMPZNZ L1,L2 */ - *opline = *target; - if (opline->op1_type == IS_CONST) { - zval zv; - ZVAL_COPY(&zv, &ZEND_OP1_LITERAL(opline)); - opline->op1.constant = zend_optimizer_add_literal(op_array, &zv); - } - /* Jump addresses may be encoded as offsets, recompute them. */ - ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(target)); - opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, - ZEND_OFFSET_TO_OPLINE(target, target->extended_value)); - goto optimize_jmpznz; } else if ((target->opcode == ZEND_RETURN || target->opcode == ZEND_RETURN_BY_REF || target->opcode == ZEND_GENERATOR_RETURN || @@ -117,15 +104,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (ZEND_OP2_JMP_ADDR(opline-1) == target) { /* JMPZ(X,L1), JMP(L1) -> NOP, JMP(L1) */ zend_optimizer_convert_to_free_op1(op_array, opline - 1); - } else { - /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ - if ((opline-1)->opcode == ZEND_JMPZ) { - (opline-1)->extended_value = ZEND_OPLINE_TO_OFFSET((opline-1), target); - } else { - (opline-1)->extended_value = ZEND_OPLINE_TO_OFFSET((opline-1), ZEND_OP2_JMP_ADDR(opline-1)); - ZEND_SET_OP_JMP_ADDR((opline-1), (opline-1)->op2, target); - } - (opline-1)->opcode = ZEND_JMPZNZ; } } break; @@ -170,12 +148,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* convert JMPZ(X,L1), L1: JMPNZ(X,L2) to JMPZ(X,L1+1) */ target = target + 1; - } else if (target->opcode == ZEND_JMPZNZ && - SAME_VAR(opline->op1, target->op1)) { - target = (opline->opcode == ZEND_JMPZ) ? - ZEND_OP2_JMP_ADDR(target) : - ZEND_OFFSET_TO_OPLINE(target, target->extended_value); - CHECK_LOOP(target); } else if (target->opcode == ZEND_NOP) { target = target + 1; } else { @@ -216,14 +188,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) JMPZ_EX(X,L2) */ target = ZEND_OP2_JMP_ADDR(target); CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPZNZ && - (SAME_VAR(target->op1, opline->result) || - SAME_VAR(target->op1, opline->op1))) { - /* Check for JMPZNZ with same cond variable */ - target = (opline->opcode == ZEND_JMPZ_EX) ? - ZEND_OP2_JMP_ADDR(target) : - ZEND_OFFSET_TO_OPLINE(target, target->extended_value); - CHECK_LOOP(target); } else if (target->opcode == INV_EX_COND(opline->opcode) && (SAME_VAR(target->op1, opline->result) || SAME_VAR(target->op1, opline->op1))) { @@ -268,65 +232,6 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) opline->op2.num = 0; } break; - - case ZEND_JMPZNZ: -optimize_jmpznz: - jmp_hitlist_count = 0; - target = ZEND_OP2_JMP_ADDR(opline); - while (1) { - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X,L1,L2), L1: JMP(L3) => JMPZNZ(X,L3,L2), L1: JMP(L3) */ - target = ZEND_OP1_JMP_ADDR(target); - CHECK_LOOP(target); - } else if ((target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - target = ZEND_OP2_JMP_ADDR(target); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */ - target = target + 1; - } else if (target->opcode == ZEND_NOP) { - target = target + 1; - } else { - break; - } - ZEND_SET_OP_JMP_ADDR(opline, opline->op2, target); - } - - jmp_hitlist_count = 0; - target = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - while (1) { - if (target->opcode == ZEND_JMP) { - /* JMPZNZ(X,L1,L2), L2: JMP(L3) => JMPZNZ(X,L1,L3), L2: JMP(L3) */ - target = ZEND_OP1_JMP_ADDR(target); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPNZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */ - target = ZEND_OP2_JMP_ADDR(target); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_JMPZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - target = target + 1; - } else if (target->opcode == ZEND_JMPZNZ && - SAME_VAR(target->op1, opline->op1)) { - /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */ - target = ZEND_OFFSET_TO_OPLINE(target, target->extended_value); - CHECK_LOOP(target); - } else if (target->opcode == ZEND_NOP) { - target = target + 1; - } else { - break; - } - opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, target); - } - - /* Don't convert JMPZNZ back to JMPZ/JMPNZ, because the - following JMP is not removed yet. */ - break; } opline++; } diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index 1e4e55e4f9266..69a7c4ed6a590 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -1786,7 +1786,6 @@ static void sccp_mark_feasible_successors( switch (opline->opcode) { case ZEND_JMPZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: { if (ct_eval_bool_cast(&zv, op1) == FAILURE) { diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index 380286cc0bf56..8b83ccad67726 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -76,7 +76,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc } } else { ZEND_ASSERT(b->successors_count == 2); - if (i == 0 || opcode == ZEND_JMPZNZ) { + if (i == 0) { succ->flags |= ZEND_BB_TARGET; } else { succ->flags |= ZEND_BB_FOLLOW; @@ -361,13 +361,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, BB_START(i + 1); } break; - case ZEND_JMPZNZ: - BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes); - BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); - if (i + 1 < op_array->last) { - BB_START(i + 1); - } - break; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -519,11 +512,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, block->successors_count = 1; block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes]; break; - case ZEND_JMPZNZ: - block->successors_count = 2; - block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes]; - block->successors[1] = block_map[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]; - break; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: diff --git a/Zend/Optimizer/zend_cfg.h b/Zend/Optimizer/zend_cfg.h index 152502978dad4..93d455060686e 100644 --- a/Zend/Optimizer/zend_cfg.h +++ b/Zend/Optimizer/zend_cfg.h @@ -62,7 +62,6 @@ typedef struct _zend_basic_block { |JMP |ADR| | |OP1| - | |JMPZ | |ADR| |OP2|FOL| |JMPNZ | |ADR| |OP2|FOL| -|JMPZNZ | |ADR|ADR|OP2|EXT| |JMPZ_EX | |ADR| |OP2|FOL| |JMPNZ_EX | |ADR| |OP2|FOL| |JMP_SET | |ADR| |OP2|FOL| diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 25ce3527cebe3..4193c196e7356 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -4619,7 +4619,6 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_BOOL: diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index 58512f751b667..e7d429ddeff47 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -704,9 +704,6 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z case ZEND_FAST_CALL: ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op1, ZEND_OP1_JMP_ADDR(opline)); break; - case ZEND_JMPZNZ: - new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -750,9 +747,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_ case ZEND_FAST_CALL: ZEND_SET_OP_JMP_ADDR(opline, opline->op1, ZEND_OP1_JMP_ADDR(opline) - shiftlist[ZEND_OP1_JMP_ADDR(opline) - op_array->opcodes]); break; - case ZEND_JMPZNZ: - opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1139,9 +1133,6 @@ static void zend_redo_pass_two(zend_op_array *op_array) case ZEND_FAST_CALL: opline->op1.jmp_addr = &op_array->opcodes[opline->op1.jmp_addr - old_opcodes]; break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1262,9 +1253,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) case ZEND_FAST_CALL: opline->op1.jmp_addr = &op_array->opcodes[opline->op1.jmp_addr - old_opcodes]; break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 2cd1d4276e7fa..11f25b6825fee 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -257,7 +257,6 @@ static void place_essa_pis( */ switch (opline->opcode) { case ZEND_JMPZ: - case ZEND_JMPZNZ: bf = blocks[j].successors[0]; bt = blocks[j].successors[1]; break; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index b215e5120af5b..830c63aaae0e3 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -1077,10 +1077,6 @@ ZEND_API void pass_two(zend_op_array *op_array) case ZEND_JMP: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); break; - case ZEND_JMPZNZ: - /* absolute index to relative offset */ - opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); - ZEND_FALLTHROUGH; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index f0ad4037eb145..dffd3924be82b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3010,41 +3010,6 @@ ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = OP1_TYPE; - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 78dab76a303fb..7e4078a7a2da7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4086,41 +4086,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_ ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = RT_CONSTANT(opline, opline->op1); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = IS_CONST; - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -14241,41 +14206,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_ ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = (IS_TMP_VAR|IS_VAR); - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -38123,41 +38053,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HAND ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_uchar op1_type; - - val = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = IS_CV; - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -53094,11 +52989,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_JMPNZ_SPEC_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMPNZ_SPEC_CV_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_CONST_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_JMPZNZ_SPEC_CV_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_CONST_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL, @@ -55718,10 +55608,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_JMPNZ_SPEC_CONST) ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_CONST): - VM_TRACE(ZEND_JMPZNZ_SPEC_CONST) - ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_JMPZ_EX_SPEC_CONST): VM_TRACE(ZEND_JMPZ_EX_SPEC_CONST) ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56997,10 +56883,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_JMPNZ_SPEC_TMPVAR) ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_TMPVAR): - VM_TRACE(ZEND_JMPZNZ_SPEC_TMPVAR) - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMPVAR): VM_TRACE(ZEND_JMPZ_EX_SPEC_TMPVAR) ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -58763,10 +58645,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_JMPNZ_SPEC_CV) ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_CV): - VM_TRACE(ZEND_JMPZNZ_SPEC_CV) - ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_JMPZ_EX_SPEC_CV): VM_TRACE(ZEND_JMPZ_EX_SPEC_CV) ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -61154,11 +61032,6 @@ void zend_vm_init(void) ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, ZEND_JMPZ_EX_SPEC_CONST_HANDLER, ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, @@ -63389,165 +63262,165 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, + 3448, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, - 1276 | SPEC_RULE_OP1, - 1281 | SPEC_RULE_OP2, - 1286, - 1287 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1276 | SPEC_RULE_OP2, + 1281, + 1282 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1292 | SPEC_RULE_OP1, 1297 | SPEC_RULE_OP1, - 1302 | SPEC_RULE_OP1, - 1307 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1302 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1327 | SPEC_RULE_OP2, 1332 | SPEC_RULE_OP2, 1337 | SPEC_RULE_OP2, - 1342 | SPEC_RULE_OP2, - 1347, - 1348, + 1342, + 1343, + 1344, + 1345 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, 1349, - 1350 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 1354, - 1355 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1365, - 1366, - 1367 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1392 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 1442 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1467 | SPEC_RULE_OP1, - 1472, - 1473, - 1474 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1499 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1524 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1534 | SPEC_RULE_OP1, - 1539 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1564 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1589 | SPEC_RULE_OP1, - 1594, - 1595, - 1596 | SPEC_RULE_OP1, - 1601 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1626 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1651 | SPEC_RULE_OP1, - 1656 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1681 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1706 | SPEC_RULE_OP1, - 1711 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1736 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1761 | SPEC_RULE_OP1, - 1766 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1791 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1816 | SPEC_RULE_OP1, - 1821 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1846 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1871 | SPEC_RULE_OP1, - 1876 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1901 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1926 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 1951, - 1952 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 1962, - 1963, - 1964, - 1965, - 1966, - 1967 | SPEC_RULE_OP2, - 1972, - 1973 | SPEC_RULE_OP1, - 1978 | SPEC_RULE_OP2, - 1983 | SPEC_RULE_OP1, - 1988 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 1998 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2023 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2048 | SPEC_RULE_OP1, - 2053 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2078 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, - 2128 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2153 | SPEC_RULE_OP2, - 2158, + 1350 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1360, + 1361, + 1362 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1387 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1437 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1462 | SPEC_RULE_OP1, + 1467, + 1468, + 1469 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1494 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1519 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1529 | SPEC_RULE_OP1, + 1534 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1584 | SPEC_RULE_OP1, + 1589, + 1590, + 1591 | SPEC_RULE_OP1, + 1596 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1621 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1646 | SPEC_RULE_OP1, + 1651 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1676 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1701 | SPEC_RULE_OP1, + 1706 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1731 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1756 | SPEC_RULE_OP1, + 1761 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1786 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1811 | SPEC_RULE_OP1, + 1816 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1841 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1866 | SPEC_RULE_OP1, + 1871 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1896 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1921 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1946, + 1947 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 1957, + 1958, + 1959, + 1960, + 1961, + 1962 | SPEC_RULE_OP2, + 1967, + 1968 | SPEC_RULE_OP1, + 1973 | SPEC_RULE_OP2, + 1978 | SPEC_RULE_OP1, + 1983 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 1993 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2018 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2043 | SPEC_RULE_OP1, + 2048 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2073 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG, + 2123 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2148 | SPEC_RULE_OP2, + 2153, + 2154 | SPEC_RULE_OP1, 2159 | SPEC_RULE_OP1, - 2164 | SPEC_RULE_OP1, - 2169, + 2164, + 2165 | SPEC_RULE_OP1, 2170 | SPEC_RULE_OP1, 2175 | SPEC_RULE_OP1, - 2180 | SPEC_RULE_OP1, - 2185, - 2186, - 2187 | SPEC_RULE_OP2, - 2192 | SPEC_RULE_RETVAL, - 2194 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2198 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, - 2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2252 | SPEC_RULE_OP1, - 2257, - 2258 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2283, - 2284 | SPEC_RULE_OP1, + 2180, + 2181, + 2182 | SPEC_RULE_OP2, + 2187 | SPEC_RULE_RETVAL, + 2189 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2193 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER, + 2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2247 | SPEC_RULE_OP1, + 2252, + 2253 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2278, + 2279 | SPEC_RULE_OP1, + 2284, + 2285, + 2286, + 2287, + 2288, 2289, 2290, - 2291, - 2292, - 2293, - 2294, - 2295, - 2296 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2321, - 2322, - 2323, - 2324 | SPEC_RULE_OP1, - 2329, - 2330 | SPEC_RULE_ISSET, - 2332 | SPEC_RULE_OP2, - 2337, - 2338 | SPEC_RULE_OP1, - 2343 | SPEC_RULE_OBSERVER, - 2345, - 2346 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2371 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, - 2381, - 2382, - 2383, - 2384, - 2385 | SPEC_RULE_OP1, - 2390, - 2391, - 2392 | SPEC_RULE_OP1, - 2397 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2422, - 2423 | SPEC_RULE_OP1, + 2291 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2316, + 2317, + 2318, + 2319 | SPEC_RULE_OP1, + 2324, + 2325 | SPEC_RULE_ISSET, + 2327 | SPEC_RULE_OP2, + 2332, + 2333 | SPEC_RULE_OP1, + 2338 | SPEC_RULE_OBSERVER, + 2340, + 2341 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2366 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER, + 2376, + 2377, + 2378, + 2379, + 2380 | SPEC_RULE_OP1, + 2385, + 2386, + 2387 | SPEC_RULE_OP1, + 2392 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2417, + 2418 | SPEC_RULE_OP1, + 2423, + 2424, + 2425, + 2426, + 2427, 2428, 2429, 2430, - 2431, - 2432, - 2433, - 2434, - 2435, - 2436 | SPEC_RULE_OP1, - 2441, - 2442, - 2443, - 2444 | SPEC_RULE_OP2, - 2449, + 2431 | SPEC_RULE_OP1, + 2436, + 2437, + 2438, + 2439 | SPEC_RULE_OP2, + 2444, + 2445 | SPEC_RULE_OP1, 2450 | SPEC_RULE_OP1, 2455 | SPEC_RULE_OP1, 2460 | SPEC_RULE_OP1, 2465 | SPEC_RULE_OP1, - 2470 | SPEC_RULE_OP1, - 2475, - 2476 | SPEC_RULE_OP1, - 2481 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2506 | SPEC_RULE_OP1, - 2511 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2470, + 2471 | SPEC_RULE_OP1, + 2476 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2501 | SPEC_RULE_OP1, + 2506 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2531 | SPEC_RULE_OP1, 2536 | SPEC_RULE_OP1, - 2541 | SPEC_RULE_OP1, - 2546, - 2547, - 2548, - 2549, - 3453 + 2541, + 2542, + 2543, + 2544, + 3448 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -63720,7 +63593,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2552 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2547 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -63728,7 +63601,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2577 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2572 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -63736,7 +63609,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2602 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2597 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -63747,17 +63620,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2627 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2622 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2652 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2647 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2677 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2672 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -63768,17 +63641,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2702 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2697 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2727 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2722 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2752 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2747 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -63789,14 +63662,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2772 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3077 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3072 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -63807,14 +63680,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2922 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2997 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3082 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3077 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -63825,12 +63698,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2772 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -63841,12 +63714,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2922 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2997 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -63854,12 +63727,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3087 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3082 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3162 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3157 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -63867,74 +63740,74 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3237 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3232 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3312 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3307 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3399 | SPEC_RULE_OP1; + spec = 3394 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3404 | SPEC_RULE_OP1; + spec = 3399 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3409 | SPEC_RULE_OP1; + spec = 3404 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3387 | SPEC_RULE_RETVAL; + spec = 3382 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3389 | SPEC_RULE_RETVAL; + spec = 3384 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3391 | SPEC_RULE_RETVAL; + spec = 3386 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3393 | SPEC_RULE_RETVAL; + spec = 3388 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3395; + spec = 3390; } else if (op1_info == MAY_BE_LONG) { - spec = 3396; + spec = 3391; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3397; + spec = 3392; } else if (op1_info == MAY_BE_LONG) { - spec = 3398; + spec = 3393; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2551; + spec = 2546; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2550; + spec = 2545; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3449; + spec = 3444; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3444 | SPEC_RULE_OP1; + spec = 3439 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3451 | SPEC_RULE_RETVAL; + spec = 3446 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -63942,17 +63815,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3414 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3409 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3450; + spec = 3445; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3439 | SPEC_RULE_OP1; + spec = 3434 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index a5796187e11be..6ac1fba363417 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -575,1278 +575,1274 @@ _(1262, ZEND_JMPNZ_SPEC_TMPVAR) \ _(1263, ZEND_JMPNZ_SPEC_TMPVAR) \ _(1265, ZEND_JMPNZ_SPEC_CV) \ - _(1266, ZEND_JMPZNZ_SPEC_CONST) \ - _(1267, ZEND_JMPZNZ_SPEC_TMPVAR) \ - _(1268, ZEND_JMPZNZ_SPEC_TMPVAR) \ - _(1270, ZEND_JMPZNZ_SPEC_CV) \ - _(1271, ZEND_JMPZ_EX_SPEC_CONST) \ - _(1272, ZEND_JMPZ_EX_SPEC_TMPVAR) \ - _(1273, ZEND_JMPZ_EX_SPEC_TMPVAR) \ - _(1275, ZEND_JMPZ_EX_SPEC_CV) \ - _(1276, ZEND_JMPNZ_EX_SPEC_CONST) \ - _(1277, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ - _(1278, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ - _(1280, ZEND_JMPNZ_EX_SPEC_CV) \ - _(1281, ZEND_CASE_SPEC_TMPVAR_CONST) \ - _(1282, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ - _(1283, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ - _(1285, ZEND_CASE_SPEC_TMPVAR_CV) \ - _(1286, ZEND_CHECK_VAR_SPEC_CV_UNUSED) \ - _(1287, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ - _(1288, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ - _(1293, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED) \ - _(1294, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK) \ - _(1297, ZEND_CAST_SPEC_CONST) \ - _(1298, ZEND_CAST_SPEC_TMP) \ - _(1299, ZEND_CAST_SPEC_VAR) \ - _(1301, ZEND_CAST_SPEC_CV) \ - _(1302, ZEND_BOOL_SPEC_CONST) \ - _(1303, ZEND_BOOL_SPEC_TMPVAR) \ - _(1304, ZEND_BOOL_SPEC_TMPVAR) \ - _(1306, ZEND_BOOL_SPEC_CV) \ - _(1307, ZEND_FAST_CONCAT_SPEC_CONST_CONST) \ - _(1308, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ - _(1309, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ - _(1311, ZEND_FAST_CONCAT_SPEC_CONST_CV) \ + _(1266, ZEND_JMPZ_EX_SPEC_CONST) \ + _(1267, ZEND_JMPZ_EX_SPEC_TMPVAR) \ + _(1268, ZEND_JMPZ_EX_SPEC_TMPVAR) \ + _(1270, ZEND_JMPZ_EX_SPEC_CV) \ + _(1271, ZEND_JMPNZ_EX_SPEC_CONST) \ + _(1272, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ + _(1273, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ + _(1275, ZEND_JMPNZ_EX_SPEC_CV) \ + _(1276, ZEND_CASE_SPEC_TMPVAR_CONST) \ + _(1277, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ + _(1278, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ + _(1280, ZEND_CASE_SPEC_TMPVAR_CV) \ + _(1281, ZEND_CHECK_VAR_SPEC_CV_UNUSED) \ + _(1282, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ + _(1283, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ + _(1288, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED) \ + _(1289, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK) \ + _(1292, ZEND_CAST_SPEC_CONST) \ + _(1293, ZEND_CAST_SPEC_TMP) \ + _(1294, ZEND_CAST_SPEC_VAR) \ + _(1296, ZEND_CAST_SPEC_CV) \ + _(1297, ZEND_BOOL_SPEC_CONST) \ + _(1298, ZEND_BOOL_SPEC_TMPVAR) \ + _(1299, ZEND_BOOL_SPEC_TMPVAR) \ + _(1301, ZEND_BOOL_SPEC_CV) \ + _(1302, ZEND_FAST_CONCAT_SPEC_CONST_CONST) \ + _(1303, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ + _(1304, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ + _(1306, ZEND_FAST_CONCAT_SPEC_CONST_CV) \ + _(1307, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ + _(1308, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ + _(1309, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ + _(1311, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ _(1312, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ _(1313, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ _(1314, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ _(1316, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ - _(1317, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ - _(1318, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1319, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1321, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ - _(1327, ZEND_FAST_CONCAT_SPEC_CV_CONST) \ - _(1328, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ - _(1329, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ - _(1331, ZEND_FAST_CONCAT_SPEC_CV_CV) \ - _(1332, ZEND_ROPE_INIT_SPEC_UNUSED_CONST) \ - _(1333, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ - _(1334, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ - _(1336, ZEND_ROPE_INIT_SPEC_UNUSED_CV) \ - _(1337, ZEND_ROPE_ADD_SPEC_TMP_CONST) \ - _(1338, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ - _(1339, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ - _(1341, ZEND_ROPE_ADD_SPEC_TMP_CV) \ - _(1342, ZEND_ROPE_END_SPEC_TMP_CONST) \ - _(1343, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ - _(1344, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ - _(1346, ZEND_ROPE_END_SPEC_TMP_CV) \ - _(1347, ZEND_BEGIN_SILENCE_SPEC) \ - _(1348, ZEND_END_SILENCE_SPEC_TMP) \ - _(1349, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST) \ - _(1350, ZEND_DO_FCALL_SPEC_RETVAL_UNUSED) \ - _(1351, ZEND_DO_FCALL_SPEC_RETVAL_USED) \ - _(1352, ZEND_DO_FCALL_SPEC_OBSERVER) \ - _(1353, ZEND_DO_FCALL_SPEC_OBSERVER) \ - _(1354, ZEND_INIT_FCALL_SPEC_CONST) \ - _(1355, ZEND_RETURN_SPEC_CONST) \ - _(1356, ZEND_RETURN_SPEC_OBSERVER) \ - _(1357, ZEND_RETURN_SPEC_TMP) \ - _(1358, ZEND_RETURN_SPEC_OBSERVER) \ - _(1359, ZEND_RETURN_SPEC_VAR) \ - _(1360, ZEND_RETURN_SPEC_OBSERVER) \ - _(1363, ZEND_RETURN_SPEC_CV) \ - _(1364, ZEND_RETURN_SPEC_OBSERVER) \ - _(1365, ZEND_RECV_SPEC_UNUSED) \ - _(1366, ZEND_RECV_INIT_SPEC_CONST) \ - _(1367, ZEND_SEND_VAL_SPEC_CONST_CONST) \ - _(1370, ZEND_SEND_VAL_SPEC_CONST_UNUSED) \ + _(1322, ZEND_FAST_CONCAT_SPEC_CV_CONST) \ + _(1323, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ + _(1324, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ + _(1326, ZEND_FAST_CONCAT_SPEC_CV_CV) \ + _(1327, ZEND_ROPE_INIT_SPEC_UNUSED_CONST) \ + _(1328, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ + _(1329, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ + _(1331, ZEND_ROPE_INIT_SPEC_UNUSED_CV) \ + _(1332, ZEND_ROPE_ADD_SPEC_TMP_CONST) \ + _(1333, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ + _(1334, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ + _(1336, ZEND_ROPE_ADD_SPEC_TMP_CV) \ + _(1337, ZEND_ROPE_END_SPEC_TMP_CONST) \ + _(1338, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ + _(1339, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ + _(1341, ZEND_ROPE_END_SPEC_TMP_CV) \ + _(1342, ZEND_BEGIN_SILENCE_SPEC) \ + _(1343, ZEND_END_SILENCE_SPEC_TMP) \ + _(1344, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST) \ + _(1345, ZEND_DO_FCALL_SPEC_RETVAL_UNUSED) \ + _(1346, ZEND_DO_FCALL_SPEC_RETVAL_USED) \ + _(1347, ZEND_DO_FCALL_SPEC_OBSERVER) \ + _(1348, ZEND_DO_FCALL_SPEC_OBSERVER) \ + _(1349, ZEND_INIT_FCALL_SPEC_CONST) \ + _(1350, ZEND_RETURN_SPEC_CONST) \ + _(1351, ZEND_RETURN_SPEC_OBSERVER) \ + _(1352, ZEND_RETURN_SPEC_TMP) \ + _(1353, ZEND_RETURN_SPEC_OBSERVER) \ + _(1354, ZEND_RETURN_SPEC_VAR) \ + _(1355, ZEND_RETURN_SPEC_OBSERVER) \ + _(1358, ZEND_RETURN_SPEC_CV) \ + _(1359, ZEND_RETURN_SPEC_OBSERVER) \ + _(1360, ZEND_RECV_SPEC_UNUSED) \ + _(1361, ZEND_RECV_INIT_SPEC_CONST) \ + _(1362, ZEND_SEND_VAL_SPEC_CONST_CONST) \ + _(1365, ZEND_SEND_VAL_SPEC_CONST_UNUSED) \ + _(1367, ZEND_SEND_VAL_SPEC_TMPVAR_CONST) \ + _(1370, ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) \ _(1372, ZEND_SEND_VAL_SPEC_TMPVAR_CONST) \ _(1375, ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) \ - _(1377, ZEND_SEND_VAL_SPEC_TMPVAR_CONST) \ - _(1380, ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) \ - _(1412, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ - _(1413, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ - _(1418, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED) \ - _(1419, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK) \ - _(1432, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ - _(1433, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ - _(1438, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED) \ - _(1439, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK) \ - _(1452, ZEND_SEND_REF_SPEC_VAR_CONST) \ - _(1455, ZEND_SEND_REF_SPEC_VAR_UNUSED) \ - _(1462, ZEND_SEND_REF_SPEC_CV_CONST) \ - _(1465, ZEND_SEND_REF_SPEC_CV_UNUSED) \ - _(1467, ZEND_NEW_SPEC_CONST_UNUSED) \ - _(1469, ZEND_NEW_SPEC_VAR_UNUSED) \ - _(1470, ZEND_NEW_SPEC_UNUSED_UNUSED) \ - _(1472, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST) \ - _(1473, ZEND_FREE_SPEC_TMPVAR) \ - _(1474, ZEND_INIT_ARRAY_SPEC_CONST_CONST) \ - _(1475, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ - _(1476, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ - _(1477, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED) \ - _(1478, ZEND_INIT_ARRAY_SPEC_CONST_CV) \ - _(1479, ZEND_INIT_ARRAY_SPEC_TMP_CONST) \ - _(1480, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ - _(1481, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ - _(1482, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) \ - _(1483, ZEND_INIT_ARRAY_SPEC_TMP_CV) \ - _(1484, ZEND_INIT_ARRAY_SPEC_VAR_CONST) \ - _(1485, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ - _(1486, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ - _(1487, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \ - _(1488, ZEND_INIT_ARRAY_SPEC_VAR_CV) \ - _(1489, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \ - _(1490, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ - _(1491, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ - _(1492, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \ - _(1493, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \ - _(1494, ZEND_INIT_ARRAY_SPEC_CV_CONST) \ - _(1495, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ - _(1496, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ - _(1497, ZEND_INIT_ARRAY_SPEC_CV_UNUSED) \ - _(1498, ZEND_INIT_ARRAY_SPEC_CV_CV) \ - _(1499, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST) \ - _(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ - _(1501, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ - _(1502, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED) \ - _(1503, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV) \ - _(1504, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) \ - _(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ - _(1506, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ - _(1507, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED) \ - _(1508, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) \ - _(1509, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST) \ - _(1510, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ - _(1511, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ - _(1512, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED) \ - _(1513, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV) \ - _(1519, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST) \ - _(1520, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ - _(1521, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ - _(1522, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED) \ - _(1523, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV) \ - _(1524, ZEND_INCLUDE_OR_EVAL_SPEC_CONST) \ - _(1525, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1526, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ - _(1527, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1528, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ - _(1529, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1532, ZEND_INCLUDE_OR_EVAL_SPEC_CV) \ - _(1533, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1534, ZEND_UNSET_VAR_SPEC_CONST_UNUSED) \ - _(1535, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ - _(1536, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ - _(1538, ZEND_UNSET_VAR_SPEC_CV_UNUSED) \ - _(1549, ZEND_UNSET_DIM_SPEC_VAR_CONST) \ - _(1550, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ - _(1551, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ - _(1553, ZEND_UNSET_DIM_SPEC_VAR_CV) \ - _(1559, ZEND_UNSET_DIM_SPEC_CV_CONST) \ - _(1560, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ - _(1561, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ - _(1563, ZEND_UNSET_DIM_SPEC_CV_CV) \ - _(1574, ZEND_UNSET_OBJ_SPEC_VAR_CONST) \ - _(1575, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ - _(1576, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ - _(1578, ZEND_UNSET_OBJ_SPEC_VAR_CV) \ - _(1579, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) \ - _(1580, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ - _(1581, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ - _(1583, ZEND_UNSET_OBJ_SPEC_UNUSED_CV) \ - _(1584, ZEND_UNSET_OBJ_SPEC_CV_CONST) \ - _(1585, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ - _(1586, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ - _(1588, ZEND_UNSET_OBJ_SPEC_CV_CV) \ - _(1589, ZEND_FE_RESET_R_SPEC_CONST) \ - _(1590, ZEND_FE_RESET_R_SPEC_TMP) \ - _(1591, ZEND_FE_RESET_R_SPEC_VAR) \ - _(1593, ZEND_FE_RESET_R_SPEC_CV) \ - _(1594, ZEND_FE_FETCH_R_SPEC_VAR) \ - _(1595, ZEND_EXIT_SPEC) \ - _(1596, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ - _(1597, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1598, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1600, ZEND_FETCH_R_SPEC_CV_UNUSED) \ - _(1601, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ - _(1602, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1603, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1605, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ + _(1407, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ + _(1408, ZEND_SEND_VAR_EX_SPEC_VAR_CONST) \ + _(1413, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED) \ + _(1414, ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK) \ + _(1427, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ + _(1428, ZEND_SEND_VAR_EX_SPEC_CV_CONST) \ + _(1433, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED) \ + _(1434, ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK) \ + _(1447, ZEND_SEND_REF_SPEC_VAR_CONST) \ + _(1450, ZEND_SEND_REF_SPEC_VAR_UNUSED) \ + _(1457, ZEND_SEND_REF_SPEC_CV_CONST) \ + _(1460, ZEND_SEND_REF_SPEC_CV_UNUSED) \ + _(1462, ZEND_NEW_SPEC_CONST_UNUSED) \ + _(1464, ZEND_NEW_SPEC_VAR_UNUSED) \ + _(1465, ZEND_NEW_SPEC_UNUSED_UNUSED) \ + _(1467, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST) \ + _(1468, ZEND_FREE_SPEC_TMPVAR) \ + _(1469, ZEND_INIT_ARRAY_SPEC_CONST_CONST) \ + _(1470, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ + _(1471, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ + _(1472, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED) \ + _(1473, ZEND_INIT_ARRAY_SPEC_CONST_CV) \ + _(1474, ZEND_INIT_ARRAY_SPEC_TMP_CONST) \ + _(1475, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ + _(1476, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ + _(1477, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) \ + _(1478, ZEND_INIT_ARRAY_SPEC_TMP_CV) \ + _(1479, ZEND_INIT_ARRAY_SPEC_VAR_CONST) \ + _(1480, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ + _(1481, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ + _(1482, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \ + _(1483, ZEND_INIT_ARRAY_SPEC_VAR_CV) \ + _(1484, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \ + _(1485, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1486, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1487, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \ + _(1488, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \ + _(1489, ZEND_INIT_ARRAY_SPEC_CV_CONST) \ + _(1490, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ + _(1491, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ + _(1492, ZEND_INIT_ARRAY_SPEC_CV_UNUSED) \ + _(1493, ZEND_INIT_ARRAY_SPEC_CV_CV) \ + _(1494, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST) \ + _(1495, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ + _(1496, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ + _(1497, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED) \ + _(1498, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV) \ + _(1499, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) \ + _(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ + _(1501, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ + _(1502, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED) \ + _(1503, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) \ + _(1504, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST) \ + _(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ + _(1506, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ + _(1507, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED) \ + _(1508, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV) \ + _(1514, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST) \ + _(1515, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ + _(1516, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ + _(1517, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED) \ + _(1518, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV) \ + _(1519, ZEND_INCLUDE_OR_EVAL_SPEC_CONST) \ + _(1520, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1521, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ + _(1522, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1523, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ + _(1524, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1527, ZEND_INCLUDE_OR_EVAL_SPEC_CV) \ + _(1528, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ + _(1529, ZEND_UNSET_VAR_SPEC_CONST_UNUSED) \ + _(1530, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ + _(1531, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ + _(1533, ZEND_UNSET_VAR_SPEC_CV_UNUSED) \ + _(1544, ZEND_UNSET_DIM_SPEC_VAR_CONST) \ + _(1545, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ + _(1546, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ + _(1548, ZEND_UNSET_DIM_SPEC_VAR_CV) \ + _(1554, ZEND_UNSET_DIM_SPEC_CV_CONST) \ + _(1555, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ + _(1556, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ + _(1558, ZEND_UNSET_DIM_SPEC_CV_CV) \ + _(1569, ZEND_UNSET_OBJ_SPEC_VAR_CONST) \ + _(1570, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ + _(1571, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ + _(1573, ZEND_UNSET_OBJ_SPEC_VAR_CV) \ + _(1574, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) \ + _(1575, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ + _(1576, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ + _(1578, ZEND_UNSET_OBJ_SPEC_UNUSED_CV) \ + _(1579, ZEND_UNSET_OBJ_SPEC_CV_CONST) \ + _(1580, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ + _(1581, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ + _(1583, ZEND_UNSET_OBJ_SPEC_CV_CV) \ + _(1584, ZEND_FE_RESET_R_SPEC_CONST) \ + _(1585, ZEND_FE_RESET_R_SPEC_TMP) \ + _(1586, ZEND_FE_RESET_R_SPEC_VAR) \ + _(1588, ZEND_FE_RESET_R_SPEC_CV) \ + _(1589, ZEND_FE_FETCH_R_SPEC_VAR) \ + _(1590, ZEND_EXIT_SPEC) \ + _(1591, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ + _(1592, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ + _(1593, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ + _(1595, ZEND_FETCH_R_SPEC_CV_UNUSED) \ + _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ + _(1597, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ + _(1598, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ + _(1600, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ + _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ + _(1602, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ + _(1603, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ + _(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ _(1607, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1608, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ _(1610, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1611, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ - _(1612, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1613, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1615, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ - _(1621, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ - _(1622, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1623, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1625, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ - _(1626, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ - _(1627, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1628, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1630, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ + _(1616, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ + _(1617, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ + _(1618, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ + _(1620, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ + _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ + _(1622, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ + _(1623, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ + _(1625, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ + _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ + _(1627, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ + _(1628, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ + _(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ _(1632, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ _(1633, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ _(1635, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1636, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ - _(1637, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1638, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1640, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ - _(1641, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ - _(1642, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1643, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1645, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ - _(1646, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ - _(1647, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1648, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1650, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ - _(1651, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ - _(1652, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1653, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1655, ZEND_FETCH_W_SPEC_CV_UNUSED) \ - _(1666, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ - _(1667, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1668, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1669, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ - _(1670, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ - _(1676, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ - _(1677, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1678, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1679, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ - _(1680, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ - _(1691, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ - _(1692, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1693, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1695, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ - _(1696, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ - _(1697, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1698, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1700, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ - _(1701, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ - _(1702, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1703, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1705, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ - _(1706, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ - _(1707, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1708, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1710, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ - _(1721, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ - _(1722, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1723, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1724, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ - _(1725, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ - _(1731, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ - _(1732, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1733, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1734, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ - _(1735, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ - _(1746, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ - _(1747, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1748, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1750, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ - _(1751, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ - _(1752, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1753, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1755, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ - _(1756, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ - _(1757, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1758, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1760, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ - _(1761, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ - _(1762, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1763, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1765, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ - _(1766, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ - _(1767, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1768, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1770, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ + _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ + _(1637, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ + _(1638, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ + _(1640, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ + _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ + _(1642, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ + _(1643, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ + _(1645, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ + _(1646, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ + _(1647, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ + _(1648, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ + _(1650, ZEND_FETCH_W_SPEC_CV_UNUSED) \ + _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ + _(1662, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ + _(1663, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ + _(1664, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ + _(1665, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ + _(1671, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ + _(1672, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ + _(1673, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ + _(1674, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ + _(1675, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ + _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ + _(1687, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ + _(1688, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ + _(1690, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ + _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ + _(1692, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ + _(1693, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ + _(1695, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ + _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ + _(1697, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ + _(1698, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ + _(1700, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ + _(1701, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ + _(1702, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ + _(1703, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ + _(1705, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ + _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ + _(1717, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ + _(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ + _(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ + _(1720, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ + _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ + _(1727, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ + _(1728, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ + _(1729, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ + _(1730, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ + _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ + _(1742, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ + _(1743, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ + _(1745, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ + _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ + _(1747, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ + _(1748, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ + _(1750, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ + _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ + _(1752, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ + _(1753, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ + _(1755, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ + _(1756, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ + _(1757, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ + _(1758, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ + _(1760, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ + _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ + _(1762, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ + _(1763, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ + _(1765, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ + _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ + _(1767, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ + _(1768, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ + _(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ _(1772, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1773, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ _(1775, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1776, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ - _(1777, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1778, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1780, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ - _(1786, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ - _(1787, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1788, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1790, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ - _(1791, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ - _(1792, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1793, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1795, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ + _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ + _(1782, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ + _(1783, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ + _(1785, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ + _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ + _(1787, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ + _(1788, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ + _(1790, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ + _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ + _(1792, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ + _(1793, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ + _(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ _(1797, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ _(1798, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ _(1800, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1801, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ - _(1802, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1803, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1805, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ - _(1806, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ - _(1807, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1808, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1810, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ - _(1811, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ - _(1812, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1813, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1815, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ - _(1816, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1817, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1818, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1820, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ - _(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ - _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ - _(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ - _(1830, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ - _(1831, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ - _(1832, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1833, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1834, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(1835, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ - _(1841, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ - _(1842, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1843, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1844, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ - _(1845, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ - _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ - _(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1848, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ - _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ - _(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1853, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ - _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ - _(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1858, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ - _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1863, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1865, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ - _(1866, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ - _(1867, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1868, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1870, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ - _(1871, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ - _(1872, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1873, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1875, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ - _(1886, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ - _(1887, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1888, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1890, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ - _(1896, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ - _(1897, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1898, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1900, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ - _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ - _(1912, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1913, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ - _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ - _(1917, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1918, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1920, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ - _(1921, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ - _(1922, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1923, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1925, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ - _(1926, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ - _(1927, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1928, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1930, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ + _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ + _(1802, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ + _(1803, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ + _(1805, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ + _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ + _(1807, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ + _(1808, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ + _(1810, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ + _(1811, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1812, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ + _(1813, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ + _(1815, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ + _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ + _(1817, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ + _(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ + _(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ + _(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ + _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ + _(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ + _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ + _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ + _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ + _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ + _(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ + _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ + _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(1830, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ + _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ + _(1837, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ + _(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ + _(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ + _(1840, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ + _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ + _(1842, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ + _(1843, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ + _(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ + _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ + _(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ + _(1848, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ + _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ + _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ + _(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ + _(1853, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ + _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ + _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ + _(1858, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ + _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ + _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ + _(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ + _(1863, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ + _(1865, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ + _(1866, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ + _(1867, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ + _(1868, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ + _(1870, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ + _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ + _(1882, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ + _(1883, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ + _(1885, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ + _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ + _(1892, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ + _(1893, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ + _(1895, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ + _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ + _(1907, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ + _(1908, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ + _(1910, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ + _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ + _(1912, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ + _(1913, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ + _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ + _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ + _(1917, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ + _(1918, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ + _(1920, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ + _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ + _(1922, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ + _(1923, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ + _(1925, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ + _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1927, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1928, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ _(1932, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1933, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ _(1935, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1936, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1937, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1938, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1940, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1946, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1947, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1948, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1950, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ - _(1951, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ - _(1952, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1958, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ - _(1959, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ - _(1962, ZEND_EXT_STMT_SPEC) \ - _(1963, ZEND_EXT_FCALL_BEGIN_SPEC) \ - _(1964, ZEND_EXT_FCALL_END_SPEC) \ - _(1965, ZEND_EXT_NOP_SPEC) \ - _(1966, ZEND_TICKS_SPEC) \ - _(1967, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ - _(1970, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ - _(1972, ZEND_CATCH_SPEC_CONST) \ - _(1973, ZEND_THROW_SPEC_CONST) \ - _(1974, ZEND_THROW_SPEC_TMPVAR) \ - _(1975, ZEND_THROW_SPEC_TMPVAR) \ - _(1977, ZEND_THROW_SPEC_CV) \ - _(1978, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ - _(1979, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1980, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1981, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ - _(1982, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ - _(1983, ZEND_CLONE_SPEC_CONST) \ - _(1984, ZEND_CLONE_SPEC_TMPVAR) \ - _(1985, ZEND_CLONE_SPEC_TMPVAR) \ - _(1986, ZEND_CLONE_SPEC_UNUSED) \ - _(1987, ZEND_CLONE_SPEC_CV) \ - _(1988, ZEND_RETURN_BY_REF_SPEC_CONST) \ - _(1989, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1990, ZEND_RETURN_BY_REF_SPEC_TMP) \ - _(1991, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1992, ZEND_RETURN_BY_REF_SPEC_VAR) \ - _(1993, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1996, ZEND_RETURN_BY_REF_SPEC_CV) \ - _(1997, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ - _(1998, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ - _(1999, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2000, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2002, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ + _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ + _(1942, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1943, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1945, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ + _(1946, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ + _(1947, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1948, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ + _(1953, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED) \ + _(1954, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK) \ + _(1957, ZEND_EXT_STMT_SPEC) \ + _(1958, ZEND_EXT_FCALL_BEGIN_SPEC) \ + _(1959, ZEND_EXT_FCALL_END_SPEC) \ + _(1960, ZEND_EXT_NOP_SPEC) \ + _(1961, ZEND_TICKS_SPEC) \ + _(1962, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \ + _(1965, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ + _(1967, ZEND_CATCH_SPEC_CONST) \ + _(1968, ZEND_THROW_SPEC_CONST) \ + _(1969, ZEND_THROW_SPEC_TMPVAR) \ + _(1970, ZEND_THROW_SPEC_TMPVAR) \ + _(1972, ZEND_THROW_SPEC_CV) \ + _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ + _(1974, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ + _(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ + _(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ + _(1977, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ + _(1978, ZEND_CLONE_SPEC_CONST) \ + _(1979, ZEND_CLONE_SPEC_TMPVAR) \ + _(1980, ZEND_CLONE_SPEC_TMPVAR) \ + _(1981, ZEND_CLONE_SPEC_UNUSED) \ + _(1982, ZEND_CLONE_SPEC_CV) \ + _(1983, ZEND_RETURN_BY_REF_SPEC_CONST) \ + _(1984, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1985, ZEND_RETURN_BY_REF_SPEC_TMP) \ + _(1986, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1987, ZEND_RETURN_BY_REF_SPEC_VAR) \ + _(1988, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1991, ZEND_RETURN_BY_REF_SPEC_CV) \ + _(1992, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ + _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ + _(1994, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ + _(1995, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ + _(1997, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ + _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ + _(1999, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ + _(2000, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ + _(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ _(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ _(2004, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ _(2005, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ _(2007, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2008, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ - _(2009, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2010, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2012, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2013, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ - _(2014, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2015, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2017, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2018, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ - _(2019, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2020, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2022, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ - _(2023, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ - _(2024, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2025, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2026, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ - _(2027, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ - _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ - _(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ - _(2037, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ - _(2038, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ - _(2039, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2040, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2041, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ - _(2042, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ - _(2048, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ - _(2049, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2050, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2052, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ - _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ - _(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2055, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ + _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2009, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ + _(2010, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ + _(2012, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ + _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ + _(2014, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ + _(2015, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ + _(2017, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ + _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ + _(2019, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ + _(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ + _(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ + _(2022, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ + _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ + _(2029, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ + _(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ + _(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ + _(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ + _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ + _(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ + _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ + _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ + _(2037, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ + _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ + _(2044, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ + _(2045, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ + _(2047, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ + _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ + _(2049, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ + _(2050, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ + _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ + _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ + _(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ + _(2055, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ + _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ _(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ _(2059, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2060, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2062, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2063, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ - _(2064, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2065, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2067, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2073, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ - _(2074, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2075, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2077, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ - _(2078, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ - _(2084, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ - _(2085, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ - _(2088, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ - _(2094, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ - _(2095, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ - _(2138, ZEND_SEND_VAR_SPEC_VAR_CONST) \ - _(2141, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ - _(2148, ZEND_SEND_VAR_SPEC_CV_CONST) \ - _(2151, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ - _(2153, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ - _(2154, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2155, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2157, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ - _(2158, ZEND_SEND_ARRAY_SPEC) \ - _(2159, ZEND_SEND_USER_SPEC_CONST) \ - _(2160, ZEND_SEND_USER_SPEC_TMP) \ - _(2161, ZEND_SEND_USER_SPEC_VAR) \ - _(2163, ZEND_SEND_USER_SPEC_CV) \ - _(2164, ZEND_STRLEN_SPEC_CONST) \ - _(2165, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2166, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2168, ZEND_STRLEN_SPEC_CV) \ - _(2169, ZEND_DEFINED_SPEC_CONST) \ - _(2170, ZEND_TYPE_CHECK_SPEC_CONST) \ - _(2171, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2172, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2174, ZEND_TYPE_CHECK_SPEC_CV) \ - _(2175, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ - _(2176, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ - _(2177, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ - _(2178, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ - _(2179, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ - _(2180, ZEND_FE_RESET_RW_SPEC_CONST) \ - _(2181, ZEND_FE_RESET_RW_SPEC_TMP) \ - _(2182, ZEND_FE_RESET_RW_SPEC_VAR) \ - _(2184, ZEND_FE_RESET_RW_SPEC_CV) \ - _(2185, ZEND_FE_FETCH_RW_SPEC_VAR) \ - _(2186, ZEND_FE_FREE_SPEC_TMPVAR) \ - _(2187, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ - _(2188, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2189, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2191, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ - _(2192, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ - _(2193, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ - _(2194, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ - _(2195, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ - _(2196, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2197, ZEND_DO_UCALL_SPEC_OBSERVER) \ - _(2198, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ - _(2199, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ - _(2200, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2201, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ - _(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ - _(2213, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2214, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2216, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ - _(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ - _(2218, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2219, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2221, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ - _(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ - _(2223, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2224, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2226, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ - _(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ - _(2238, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2239, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2241, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ - _(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ - _(2243, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2244, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2246, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ - _(2247, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ - _(2248, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2249, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2251, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ - _(2252, ZEND_ECHO_SPEC_CONST) \ - _(2253, ZEND_ECHO_SPEC_TMPVAR) \ - _(2254, ZEND_ECHO_SPEC_TMPVAR) \ - _(2256, ZEND_ECHO_SPEC_CV) \ + _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ + _(2069, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ + _(2070, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ + _(2072, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ + _(2073, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ + _(2074, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ + _(2079, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \ + _(2080, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \ + _(2083, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ + _(2084, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \ + _(2089, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \ + _(2090, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \ + _(2133, ZEND_SEND_VAR_SPEC_VAR_CONST) \ + _(2136, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \ + _(2143, ZEND_SEND_VAR_SPEC_CV_CONST) \ + _(2146, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ + _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ + _(2149, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ + _(2150, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ + _(2152, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ + _(2153, ZEND_SEND_ARRAY_SPEC) \ + _(2154, ZEND_SEND_USER_SPEC_CONST) \ + _(2155, ZEND_SEND_USER_SPEC_TMP) \ + _(2156, ZEND_SEND_USER_SPEC_VAR) \ + _(2158, ZEND_SEND_USER_SPEC_CV) \ + _(2159, ZEND_STRLEN_SPEC_CONST) \ + _(2160, ZEND_STRLEN_SPEC_TMPVAR) \ + _(2161, ZEND_STRLEN_SPEC_TMPVAR) \ + _(2163, ZEND_STRLEN_SPEC_CV) \ + _(2164, ZEND_DEFINED_SPEC_CONST) \ + _(2165, ZEND_TYPE_CHECK_SPEC_CONST) \ + _(2166, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ + _(2167, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ + _(2169, ZEND_TYPE_CHECK_SPEC_CV) \ + _(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ + _(2171, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ + _(2172, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \ + _(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \ + _(2174, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \ + _(2175, ZEND_FE_RESET_RW_SPEC_CONST) \ + _(2176, ZEND_FE_RESET_RW_SPEC_TMP) \ + _(2177, ZEND_FE_RESET_RW_SPEC_VAR) \ + _(2179, ZEND_FE_RESET_RW_SPEC_CV) \ + _(2180, ZEND_FE_FETCH_RW_SPEC_VAR) \ + _(2181, ZEND_FE_FREE_SPEC_TMPVAR) \ + _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ + _(2183, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ + _(2184, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ + _(2186, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ + _(2187, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ + _(2188, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ + _(2189, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \ + _(2190, ZEND_DO_UCALL_SPEC_RETVAL_USED) \ + _(2191, ZEND_DO_UCALL_SPEC_OBSERVER) \ + _(2192, ZEND_DO_UCALL_SPEC_OBSERVER) \ + _(2193, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \ + _(2194, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \ + _(2195, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ + _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ + _(2207, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ + _(2208, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2211, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ + _(2212, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2213, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2216, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ + _(2217, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ + _(2218, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2221, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ + _(2232, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ + _(2233, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2236, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ + _(2237, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ + _(2238, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2241, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ + _(2242, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ + _(2243, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2246, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ + _(2247, ZEND_ECHO_SPEC_CONST) \ + _(2248, ZEND_ECHO_SPEC_TMPVAR) \ + _(2249, ZEND_ECHO_SPEC_TMPVAR) \ + _(2251, ZEND_ECHO_SPEC_CV) \ + _(2258, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ + _(2260, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ + _(2261, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ _(2263, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ _(2265, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ _(2266, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2268, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2270, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2271, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2278, ZEND_INSTANCEOF_SPEC_CV_CONST) \ - _(2280, ZEND_INSTANCEOF_SPEC_CV_VAR) \ - _(2281, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ - _(2283, ZEND_GENERATOR_CREATE_SPEC) \ - _(2286, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ - _(2288, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ - _(2289, ZEND_DECLARE_FUNCTION_SPEC) \ - _(2290, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ - _(2291, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ - _(2292, ZEND_DECLARE_CLASS_SPEC_CONST) \ - _(2293, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ - _(2294, ZEND_DECLARE_ANON_CLASS_SPEC) \ - _(2295, ZEND_ADD_ARRAY_UNPACK_SPEC) \ - _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ - _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ + _(2273, ZEND_INSTANCEOF_SPEC_CV_CONST) \ + _(2275, ZEND_INSTANCEOF_SPEC_CV_VAR) \ + _(2276, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ + _(2278, ZEND_GENERATOR_CREATE_SPEC) \ + _(2281, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \ + _(2283, ZEND_MAKE_REF_SPEC_CV_UNUSED) \ + _(2284, ZEND_DECLARE_FUNCTION_SPEC) \ + _(2285, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \ + _(2286, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \ + _(2287, ZEND_DECLARE_CLASS_SPEC_CONST) \ + _(2288, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \ + _(2289, ZEND_DECLARE_ANON_CLASS_SPEC) \ + _(2290, ZEND_ADD_ARRAY_UNPACK_SPEC) \ + _(2291, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ + _(2292, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ + _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ + _(2295, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ + _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ + _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ + _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ + _(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ _(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ _(2305, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ - _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2310, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ - _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ - _(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ - _(2317, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2318, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2320, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ - _(2321, ZEND_HANDLE_EXCEPTION_SPEC) \ - _(2322, ZEND_USER_OPCODE_SPEC) \ - _(2323, ZEND_ASSERT_CHECK_SPEC) \ - _(2324, ZEND_JMP_SET_SPEC_CONST) \ - _(2325, ZEND_JMP_SET_SPEC_TMP) \ - _(2326, ZEND_JMP_SET_SPEC_VAR) \ - _(2328, ZEND_JMP_SET_SPEC_CV) \ - _(2329, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ - _(2330, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ - _(2331, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ - _(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ - _(2333, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2334, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2336, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ - _(2337, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ - _(2339, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2340, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2341, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ - _(2342, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ - _(2343, ZEND_CALL_TRAMPOLINE_SPEC) \ - _(2344, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ - _(2345, ZEND_DISCARD_EXCEPTION_SPEC) \ - _(2346, ZEND_YIELD_SPEC_CONST_CONST) \ - _(2347, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2348, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2349, ZEND_YIELD_SPEC_CONST_UNUSED) \ - _(2350, ZEND_YIELD_SPEC_CONST_CV) \ - _(2351, ZEND_YIELD_SPEC_TMP_CONST) \ - _(2352, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2353, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2354, ZEND_YIELD_SPEC_TMP_UNUSED) \ - _(2355, ZEND_YIELD_SPEC_TMP_CV) \ - _(2356, ZEND_YIELD_SPEC_VAR_CONST) \ - _(2357, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2358, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2359, ZEND_YIELD_SPEC_VAR_UNUSED) \ - _(2360, ZEND_YIELD_SPEC_VAR_CV) \ - _(2361, ZEND_YIELD_SPEC_UNUSED_CONST) \ - _(2362, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2363, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2364, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ - _(2365, ZEND_YIELD_SPEC_UNUSED_CV) \ - _(2366, ZEND_YIELD_SPEC_CV_CONST) \ - _(2367, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2368, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2369, ZEND_YIELD_SPEC_CV_UNUSED) \ - _(2370, ZEND_YIELD_SPEC_CV_CV) \ - _(2371, ZEND_GENERATOR_RETURN_SPEC_CONST) \ - _(2372, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2373, ZEND_GENERATOR_RETURN_SPEC_TMP) \ - _(2374, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2375, ZEND_GENERATOR_RETURN_SPEC_VAR) \ - _(2376, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2379, ZEND_GENERATOR_RETURN_SPEC_CV) \ - _(2380, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ - _(2381, ZEND_FAST_CALL_SPEC) \ - _(2382, ZEND_FAST_RET_SPEC) \ - _(2383, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ - _(2384, ZEND_SEND_UNPACK_SPEC) \ - _(2385, ZEND_YIELD_FROM_SPEC_CONST) \ - _(2386, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2387, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2389, ZEND_YIELD_FROM_SPEC_CV) \ - _(2390, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ - _(2391, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ - _(2392, ZEND_COALESCE_SPEC_CONST) \ - _(2393, ZEND_COALESCE_SPEC_TMP) \ - _(2394, ZEND_COALESCE_SPEC_VAR) \ - _(2396, ZEND_COALESCE_SPEC_CV) \ - _(2397, ZEND_SPACESHIP_SPEC_CONST_CONST) \ - _(2398, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2399, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2401, ZEND_SPACESHIP_SPEC_CONST_CV) \ + _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ + _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2310, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ + _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ + _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ + _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ + _(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ + _(2316, ZEND_HANDLE_EXCEPTION_SPEC) \ + _(2317, ZEND_USER_OPCODE_SPEC) \ + _(2318, ZEND_ASSERT_CHECK_SPEC) \ + _(2319, ZEND_JMP_SET_SPEC_CONST) \ + _(2320, ZEND_JMP_SET_SPEC_TMP) \ + _(2321, ZEND_JMP_SET_SPEC_VAR) \ + _(2323, ZEND_JMP_SET_SPEC_CV) \ + _(2324, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ + _(2325, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ + _(2326, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ + _(2327, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ + _(2328, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ + _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ + _(2331, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ + _(2332, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ + _(2334, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ + _(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ + _(2336, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ + _(2337, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ + _(2338, ZEND_CALL_TRAMPOLINE_SPEC) \ + _(2339, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ + _(2340, ZEND_DISCARD_EXCEPTION_SPEC) \ + _(2341, ZEND_YIELD_SPEC_CONST_CONST) \ + _(2342, ZEND_YIELD_SPEC_CONST_TMPVAR) \ + _(2343, ZEND_YIELD_SPEC_CONST_TMPVAR) \ + _(2344, ZEND_YIELD_SPEC_CONST_UNUSED) \ + _(2345, ZEND_YIELD_SPEC_CONST_CV) \ + _(2346, ZEND_YIELD_SPEC_TMP_CONST) \ + _(2347, ZEND_YIELD_SPEC_TMP_TMPVAR) \ + _(2348, ZEND_YIELD_SPEC_TMP_TMPVAR) \ + _(2349, ZEND_YIELD_SPEC_TMP_UNUSED) \ + _(2350, ZEND_YIELD_SPEC_TMP_CV) \ + _(2351, ZEND_YIELD_SPEC_VAR_CONST) \ + _(2352, ZEND_YIELD_SPEC_VAR_TMPVAR) \ + _(2353, ZEND_YIELD_SPEC_VAR_TMPVAR) \ + _(2354, ZEND_YIELD_SPEC_VAR_UNUSED) \ + _(2355, ZEND_YIELD_SPEC_VAR_CV) \ + _(2356, ZEND_YIELD_SPEC_UNUSED_CONST) \ + _(2357, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ + _(2358, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ + _(2359, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ + _(2360, ZEND_YIELD_SPEC_UNUSED_CV) \ + _(2361, ZEND_YIELD_SPEC_CV_CONST) \ + _(2362, ZEND_YIELD_SPEC_CV_TMPVAR) \ + _(2363, ZEND_YIELD_SPEC_CV_TMPVAR) \ + _(2364, ZEND_YIELD_SPEC_CV_UNUSED) \ + _(2365, ZEND_YIELD_SPEC_CV_CV) \ + _(2366, ZEND_GENERATOR_RETURN_SPEC_CONST) \ + _(2367, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2368, ZEND_GENERATOR_RETURN_SPEC_TMP) \ + _(2369, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2370, ZEND_GENERATOR_RETURN_SPEC_VAR) \ + _(2371, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2374, ZEND_GENERATOR_RETURN_SPEC_CV) \ + _(2375, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \ + _(2376, ZEND_FAST_CALL_SPEC) \ + _(2377, ZEND_FAST_RET_SPEC) \ + _(2378, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ + _(2379, ZEND_SEND_UNPACK_SPEC) \ + _(2380, ZEND_YIELD_FROM_SPEC_CONST) \ + _(2381, ZEND_YIELD_FROM_SPEC_TMPVAR) \ + _(2382, ZEND_YIELD_FROM_SPEC_TMPVAR) \ + _(2384, ZEND_YIELD_FROM_SPEC_CV) \ + _(2385, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ + _(2386, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ + _(2387, ZEND_COALESCE_SPEC_CONST) \ + _(2388, ZEND_COALESCE_SPEC_TMP) \ + _(2389, ZEND_COALESCE_SPEC_VAR) \ + _(2391, ZEND_COALESCE_SPEC_CV) \ + _(2392, ZEND_SPACESHIP_SPEC_CONST_CONST) \ + _(2393, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ + _(2394, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ + _(2396, ZEND_SPACESHIP_SPEC_CONST_CV) \ + _(2397, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ + _(2398, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ + _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ + _(2401, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ _(2402, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ _(2406, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2407, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ - _(2408, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2409, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2411, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2417, ZEND_SPACESHIP_SPEC_CV_CONST) \ - _(2418, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2419, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2421, ZEND_SPACESHIP_SPEC_CV_CV) \ - _(2422, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ - _(2423, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ - _(2426, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ - _(2428, ZEND_FETCH_STATIC_PROP_R_SPEC) \ - _(2429, ZEND_FETCH_STATIC_PROP_W_SPEC) \ - _(2430, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ - _(2431, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ - _(2432, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ - _(2433, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ - _(2434, ZEND_UNSET_STATIC_PROP_SPEC) \ - _(2435, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ - _(2436, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ - _(2438, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ - _(2439, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ - _(2441, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ - _(2442, ZEND_BIND_STATIC_SPEC_CV_UNUSED) \ - _(2443, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ - _(2444, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ - _(2447, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ - _(2449, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ - _(2450, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ - _(2451, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2452, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2454, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ - _(2455, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ - _(2456, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2457, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2459, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ - _(2460, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ - _(2461, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ - _(2462, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ - _(2464, ZEND_IN_ARRAY_SPEC_CV_CONST) \ - _(2465, ZEND_COUNT_SPEC_CONST_UNUSED) \ - _(2466, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2467, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2469, ZEND_COUNT_SPEC_CV_UNUSED) \ - _(2470, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ - _(2471, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2472, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2473, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ - _(2474, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ - _(2475, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ - _(2476, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ - _(2477, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ - _(2478, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ - _(2480, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ - _(2481, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ - _(2482, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2483, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2485, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ + _(2412, ZEND_SPACESHIP_SPEC_CV_CONST) \ + _(2413, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ + _(2414, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ + _(2416, ZEND_SPACESHIP_SPEC_CV_CV) \ + _(2417, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ + _(2418, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ + _(2421, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \ + _(2423, ZEND_FETCH_STATIC_PROP_R_SPEC) \ + _(2424, ZEND_FETCH_STATIC_PROP_W_SPEC) \ + _(2425, ZEND_FETCH_STATIC_PROP_RW_SPEC) \ + _(2426, ZEND_FETCH_STATIC_PROP_IS_SPEC) \ + _(2427, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \ + _(2428, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \ + _(2429, ZEND_UNSET_STATIC_PROP_SPEC) \ + _(2430, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \ + _(2431, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \ + _(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \ + _(2434, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \ + _(2436, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \ + _(2437, ZEND_BIND_STATIC_SPEC_CV_UNUSED) \ + _(2438, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \ + _(2439, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \ + _(2442, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \ + _(2444, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \ + _(2445, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \ + _(2446, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2447, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2449, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \ + _(2450, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \ + _(2451, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2452, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2454, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ + _(2455, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ + _(2456, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ + _(2457, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ + _(2459, ZEND_IN_ARRAY_SPEC_CV_CONST) \ + _(2460, ZEND_COUNT_SPEC_CONST_UNUSED) \ + _(2461, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ + _(2462, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ + _(2464, ZEND_COUNT_SPEC_CV_UNUSED) \ + _(2465, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ + _(2466, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ + _(2467, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ + _(2468, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ + _(2469, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ + _(2470, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ + _(2471, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ + _(2472, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ + _(2473, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ + _(2475, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ + _(2476, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ + _(2477, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ + _(2478, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ + _(2480, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ + _(2481, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ + _(2482, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ + _(2483, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ + _(2485, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ _(2486, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ _(2487, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2488, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ _(2490, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2491, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ - _(2492, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2493, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2495, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ - _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2505, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ - _(2506, ZEND_MATCH_SPEC_CONST_CONST) \ - _(2507, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2508, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2510, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2516, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ - _(2517, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ - _(2518, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ - _(2520, ZEND_CASE_STRICT_SPEC_TMP_CV) \ - _(2521, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ - _(2522, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ - _(2523, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ - _(2525, ZEND_CASE_STRICT_SPEC_VAR_CV) \ - _(2536, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ - _(2537, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2538, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2540, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2541, ZEND_JMP_NULL_SPEC_CONST) \ - _(2542, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2543, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2545, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2546, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ - _(2547, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ - _(2548, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ - _(2549, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ - _(2550, ZEND_RECV_NOTYPE_SPEC) \ - _(2551, ZEND_JMP_FORWARD_SPEC) \ + _(2496, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ + _(2497, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ + _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ + _(2500, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ + _(2501, ZEND_MATCH_SPEC_CONST_CONST) \ + _(2502, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2503, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2505, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ + _(2511, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ + _(2512, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ + _(2513, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ + _(2515, ZEND_CASE_STRICT_SPEC_TMP_CV) \ + _(2516, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ + _(2517, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ + _(2518, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ + _(2520, ZEND_CASE_STRICT_SPEC_VAR_CV) \ + _(2531, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2532, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2533, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2535, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2536, ZEND_JMP_NULL_SPEC_CONST) \ + _(2537, ZEND_JMP_NULL_SPEC_TMPVARCV) \ + _(2538, ZEND_JMP_NULL_SPEC_TMPVARCV) \ + _(2540, ZEND_JMP_NULL_SPEC_TMPVARCV) \ + _(2541, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ + _(2542, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ + _(2543, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ + _(2544, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ + _(2545, ZEND_RECV_NOTYPE_SPEC) \ + _(2546, ZEND_JMP_FORWARD_SPEC) \ + _(2552, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2553, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2554, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2556, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2557, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2558, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2559, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2561, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2562, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2563, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2564, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2566, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2573, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2574, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2567, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2568, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2569, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2571, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2577, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2578, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2579, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2581, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2582, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(2583, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2584, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2586, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2587, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2588, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2589, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2591, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2598, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2599, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2592, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2593, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2594, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2596, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2602, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2603, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2604, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2606, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2607, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2608, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2609, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2611, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2612, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2613, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2614, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2623, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2624, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2628, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2629, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2631, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2617, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2618, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2619, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2621, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2623, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2624, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2626, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2627, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2628, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2629, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2631, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2632, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2633, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2634, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2636, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2637, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2638, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2639, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2648, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2649, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2653, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2654, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2656, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2642, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2644, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2648, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2649, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2651, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2652, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2653, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2654, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2656, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2657, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(2658, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2659, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2661, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2662, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2663, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2664, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2673, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2674, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2678, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2679, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2681, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2667, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2668, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2669, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2671, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2673, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2674, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2676, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2677, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2678, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2679, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2681, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2682, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2683, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2684, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2686, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2687, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2688, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2689, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2691, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2698, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2699, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2692, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2693, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2694, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2696, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2702, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2703, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2704, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2706, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2707, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2708, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2709, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2711, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2712, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2713, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2714, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2716, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2723, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2724, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2717, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2718, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2719, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2721, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2727, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2728, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2729, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2731, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2732, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(2733, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2734, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2736, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2737, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2738, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2739, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2748, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2749, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2742, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2743, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2744, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2746, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2752, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2753, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2754, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2756, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2757, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2758, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2759, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2761, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2762, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2763, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2764, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2773, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2774, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2792, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2793, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2794, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2795, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2796, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2797, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2798, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2867, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2868, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2869, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2870, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2871, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2872, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2873, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2942, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2943, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2944, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2945, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2946, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2947, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2948, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3017, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3018, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3019, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3020, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3021, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3022, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3023, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3077, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3081, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3082, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3086, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3091, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3092, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3093, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3094, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3099, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3100, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3101, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3106, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3107, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3108, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3109, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3121, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3122, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3131, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3166, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3167, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3168, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3169, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3174, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3175, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3176, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3181, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3182, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3183, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3184, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3241, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3242, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3243, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3244, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3256, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3257, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3258, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3259, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3316, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3317, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3318, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3319, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3333, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3334, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3387, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3388, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3389, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3390, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3391, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3392, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3393, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3394, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3395, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3396, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3397, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3398, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3399, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ - _(3400, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3401, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3403, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3404, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(3405, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3406, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3408, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3409, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(3410, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3411, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3413, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3415, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3416, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3418, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(2767, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2768, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2769, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2771, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2787, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2788, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2789, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2790, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2791, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2792, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2793, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2794, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2795, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2801, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2802, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2803, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2816, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2862, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2863, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2864, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2865, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2866, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2867, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2868, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2869, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2870, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2876, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2877, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2878, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2891, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2937, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2938, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2939, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2940, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2941, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2942, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2943, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2944, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2945, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2951, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2952, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2953, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2966, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3012, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3013, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3014, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3015, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3016, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3017, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3018, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3019, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3020, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3026, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3027, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3028, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3041, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3072, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3076, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3077, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3081, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3085, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3086, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3087, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3088, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3089, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3094, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3096, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3097, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3098, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3099, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3100, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3101, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3109, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3111, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3112, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3113, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3160, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3161, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3162, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3163, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3164, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3169, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3171, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3172, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3173, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3174, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3175, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3176, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3184, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3186, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3187, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3188, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3235, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3236, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3237, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3238, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3239, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3244, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3246, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3247, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3248, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3259, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3310, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3311, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3312, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3313, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3314, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3319, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3321, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3322, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3323, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3334, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3382, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3383, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3384, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3385, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3386, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3387, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3388, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3389, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3390, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3391, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3392, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3393, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3394, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3395, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3396, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3398, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3399, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3400, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3401, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3403, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3404, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3405, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3406, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3408, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3410, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3411, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3413, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3414, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3415, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3416, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3418, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3419, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(3420, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3421, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3423, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3424, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3425, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3426, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3428, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3434, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3435, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3436, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3438, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3441, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3443, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3446, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3448, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3449, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3450, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3451, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3452, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3452+1, ZEND_NULL) + _(3429, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3430, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3431, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3433, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3436, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3438, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3441, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3443, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3444, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3445, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3446, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3447, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3447+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 085c473d59578..cbb0346821474 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -68,7 +68,7 @@ static const char *zend_vm_opcodes_names[203] = { "ZEND_JMP", "ZEND_JMPZ", "ZEND_JMPNZ", - "ZEND_JMPZNZ", + NULL, "ZEND_JMPZ_EX", "ZEND_JMPNZ_EX", "ZEND_CASE", @@ -274,7 +274,7 @@ static uint32_t zend_vm_opcodes_flags[203] = { 0x00000020, 0x00002007, 0x00002007, - 0x03002007, + 0x00000000, 0x00002007, 0x00002007, 0x00000705, diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 83e409a9233c9..165e914e1cd53 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -128,7 +128,6 @@ END_EXTERN_C() #define ZEND_JMP 42 #define ZEND_JMPZ 43 #define ZEND_JMPNZ 44 -#define ZEND_JMPZNZ 45 #define ZEND_JMPZ_EX 46 #define ZEND_JMPNZ_EX 47 #define ZEND_CASE 48 diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 5d365504454a6..8f92da6df271d 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -316,7 +316,6 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_INIT_USER_CALL: case ZEND_FAST_CALL: case ZEND_JMP: - case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -399,7 +398,6 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_INIT_USER_CALL: case ZEND_FAST_CALL: case ZEND_JMP: - case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -3426,8 +3424,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op && ((opline+1)->opcode == ZEND_JMPZ || (opline+1)->opcode == ZEND_JMPNZ || (opline+1)->opcode == ZEND_JMPZ_EX - || (opline+1)->opcode == ZEND_JMPNZ_EX - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ_EX) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3460,8 +3457,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3486,8 +3482,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3510,8 +3505,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3606,7 +3600,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto done; } ZEND_FALLTHROUGH; - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: if (opline->result_type == IS_UNDEF) { @@ -3630,8 +3623,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3660,8 +3652,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -3717,8 +3708,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ - || (opline+1)->opcode == ZEND_JMPNZ - || (opline+1)->opcode == ZEND_JMPZNZ) + || (opline+1)->opcode == ZEND_JMPNZ) && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; @@ -4004,15 +3994,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } is_terminated = 1; break; - case ZEND_JMPZNZ: - if (!zend_jit_handler(&dasm_state, opline, - zend_may_throw(opline, ssa_op, op_array, ssa)) || - !zend_jit_cond_jmp(&dasm_state, OP_JMP_ADDR(opline, opline->op2), ssa->cfg.blocks[b].successors[1]) || - !zend_jit_jmp(&dasm_state, ssa->cfg.blocks[b].successors[0])) { - goto jit_failure; - } - is_terminated = 1; - break; case ZEND_JMPZ: case ZEND_JMPNZ: if (opline > op_array->opcodes + ssa->cfg.blocks[b].start && diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 7bae3752d7137..d464b21348b77 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3330,11 +3330,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra OP_JMP_ADDR(opline, opline->op2) : opline + 1; break; - case ZEND_JMPZNZ: - exit_opline = (trace->opline == OP_JMP_ADDR(opline, opline->op2)) ? - ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : - OP_JMP_ADDR(opline, opline->op2); - break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: if (opline->op2_type == IS_CV) { @@ -6496,12 +6491,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, if (result) { | b => target_label } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - if (!result) { - | b => target_label - } else { - | b => target_label2 - } } else { ZEND_UNREACHABLE(); } @@ -6697,36 +6686,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | bne => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | beq => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | ble => target_label - } else { - | bge => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | blt => target_label - } else { - | bgt => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | b => target_label2 } else { ZEND_UNREACHABLE(); } @@ -6908,39 +6867,6 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | bne => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | bvs => target_label2 - | beq => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | bvs => target_label - | bls => target_label - } else { - | bhs => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | bvs => target_label - | blo => target_label - } else { - | bhi => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | b => target_label2 } else if (smart_branch_opcode == ZEND_JMPZ_EX) { switch (opline->opcode) { case ZEND_IS_EQUAL: @@ -7233,25 +7159,6 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_CASE: - | bne => target_label - break; - case ZEND_IS_NOT_EQUAL: - | beq => target_label - break; - case ZEND_IS_SMALLER: - | bge => target_label - break; - case ZEND_IS_SMALLER_OR_EQUAL: - | bgt => target_label - break; - default: - ZEND_UNREACHABLE(); - } - | b => target_label2 } else { ZEND_UNREACHABLE(); } @@ -7533,9 +7440,6 @@ static int zend_jit_identical(dasm_State **Dst, not_identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - not_identical_label = target_label; - identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -7544,9 +7448,6 @@ static int zend_jit_identical(dasm_State **Dst, identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { not_identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - identical_label = target_label; - not_identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -7922,9 +7823,6 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_ false_label = target_label; } else if (branch_opcode == ZEND_JMPNZ) { true_label = target_label; - } else if (branch_opcode == ZEND_JMPZNZ) { - true_label = target_label2; - false_label = target_label; } else if (branch_opcode == ZEND_JMPZ_EX) { set_bool = 1; false_label = target_label; @@ -10194,8 +10092,6 @@ static int zend_jit_smart_true(dasm_State **Dst, const zend_op *opline, int jmp, } } else if (smart_branch_opcode == ZEND_JMPNZ) { | b =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10220,8 +10116,6 @@ static int zend_jit_smart_false(dasm_State **Dst, const zend_op *opline, int jmp if (jmp) { | b >7 } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label } else { ZEND_UNREACHABLE(); } @@ -10249,9 +10143,6 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, zend_uchar undefined_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { defined_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - undefined_label = target_label; - defined_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -10487,9 +10378,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | beq =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | bne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | beq =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10574,9 +10462,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | beq =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | bne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | beq =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10585,9 +10470,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | bne =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | beq =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | bne =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11747,8 +11629,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, | b =>target_label2 } else if (smart_branch_opcode == ZEND_JMPNZ) { | b =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11780,8 +11660,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, if (smart_branch_opcode == ZEND_JMPZ) { | b =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label } else { ZEND_UNREACHABLE(); } @@ -14306,8 +14184,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui } else if (smart_branch_opcode) { if (smart_branch_opcode == ZEND_JMPNZ) { | b =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | b =>target_label2 } } else { | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 @@ -14337,9 +14213,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui | ble =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | bgt =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | ble =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -14687,9 +14560,6 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o | cbz RETVALx, =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | cbnz RETVALx, =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | cbz RETVALx, =>target_label - | b =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -14985,7 +14855,6 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa ZEND_FALLTHROUGH; case ZEND_BOOL: case ZEND_BOOL_NOT: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: return 1; @@ -15302,7 +15171,6 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: op1_info = OP1_INFO(); diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index f6227a6c63094..4f0b4df1594c9 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -310,7 +310,6 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op return 1; } break; - case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1835,7 +1834,6 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin break; case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_BOOL: @@ -5357,7 +5355,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: op1_info = OP1_INFO(); @@ -5377,13 +5374,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { smart_branch_opcode = ZEND_JMPNZ; } - exit_opline = (opline->opcode == ZEND_JMPZNZ) ? - ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : - opline + 1; - } else if (opline->opcode == ZEND_JMPZNZ) { - ZEND_ASSERT((p+1)->opline == ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value)); - smart_branch_opcode = ZEND_JMPZ; - exit_opline = OP_JMP_ADDR(opline, opline->op2); + exit_opline = opline + 1; } else if ((p+1)->opline == opline + 1) { /* not taken branch */ smart_branch_opcode = opline->opcode; diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 5f09e41eaed3e..e3f4c15e6a902 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3660,11 +3660,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra OP_JMP_ADDR(opline, opline->op2) : opline + 1; break; - case ZEND_JMPZNZ: - exit_opline = (trace->opline == OP_JMP_ADDR(opline, opline->op2)) ? - ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) : - OP_JMP_ADDR(opline, opline->op2); - break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: if (opline->op2_type == IS_CV) { @@ -7048,12 +7043,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, if (result) { | jmp => target_label } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - if (!result) { - | jmp => target_label - } else { - | jmp => target_label2 - } } else { ZEND_UNREACHABLE(); } @@ -7250,36 +7239,6 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | jne => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | je => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | jle => target_label - } else { - | jge => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | jl => target_label - } else { - | jg => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | jmp => target_label2 } else { ZEND_UNREACHABLE(); } @@ -7463,40 +7422,6 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_IS_IDENTICAL: - case ZEND_CASE: - case ZEND_CASE_STRICT: - | jne => target_label - | jp => target_label - break; - case ZEND_IS_NOT_EQUAL: - case ZEND_IS_NOT_IDENTICAL: - | jp => target_label2 - | je => target_label - break; - case ZEND_IS_SMALLER: - if (swap) { - | jbe => target_label - } else { - | jae => target_label - | jp => target_label - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (swap) { - | jb => target_label - } else { - | ja => target_label - | jp => target_label - } - break; - default: - ZEND_UNREACHABLE(); - } - | jmp => target_label2 } else if (smart_branch_opcode == ZEND_JMPZ_EX) { switch (opline->opcode) { case ZEND_IS_EQUAL: @@ -7793,25 +7718,6 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a default: ZEND_UNREACHABLE(); } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - switch (opline->opcode) { - case ZEND_IS_EQUAL: - case ZEND_CASE: - | jne => target_label - break; - case ZEND_IS_NOT_EQUAL: - | je => target_label - break; - case ZEND_IS_SMALLER: - | jge => target_label - break; - case ZEND_IS_SMALLER_OR_EQUAL: - | jg => target_label - break; - default: - ZEND_UNREACHABLE(); - } - | jmp => target_label2 } else { ZEND_UNREACHABLE(); } @@ -8110,9 +8016,6 @@ static int zend_jit_identical(dasm_State **Dst, not_identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - not_identical_label = target_label; - identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -8121,9 +8024,6 @@ static int zend_jit_identical(dasm_State **Dst, identical_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { not_identical_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - identical_label = target_label; - not_identical_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -8501,9 +8401,6 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_ false_label = target_label; } else if (branch_opcode == ZEND_JMPNZ) { true_label = target_label; - } else if (branch_opcode == ZEND_JMPZNZ) { - true_label = target_label2; - false_label = target_label; } else if (branch_opcode == ZEND_JMPZ_EX) { set_bool = 1; false_label = target_label; @@ -10846,8 +10743,6 @@ static int zend_jit_smart_true(dasm_State **Dst, const zend_op *opline, int jmp, } } else if (smart_branch_opcode == ZEND_JMPNZ) { | jmp =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -10872,8 +10767,6 @@ static int zend_jit_smart_false(dasm_State **Dst, const zend_op *opline, int jmp if (jmp) { | jmp >7 } - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label } else { ZEND_UNREACHABLE(); } @@ -10901,9 +10794,6 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, zend_uchar undefined_label = target_label; } else if (smart_branch_opcode == ZEND_JMPNZ) { defined_label = target_label; - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - undefined_label = target_label; - defined_label = target_label2; } else { ZEND_UNREACHABLE(); } @@ -11141,9 +11031,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | je =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | je =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11225,9 +11112,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | je =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jne =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | je =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -11236,9 +11120,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t | jne =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | je =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jne =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -12452,8 +12333,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, | jmp =>target_label2 } else if (smart_branch_opcode == ZEND_JMPNZ) { | jmp =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -12485,8 +12364,6 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, if (smart_branch_opcode == ZEND_JMPZ) { | jmp =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label } else { ZEND_UNREACHABLE(); } @@ -15196,8 +15073,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui } else if (smart_branch_opcode) { if (smart_branch_opcode == ZEND_JMPNZ) { | jmp =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jmp =>target_label2 } } else { | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE @@ -15226,9 +15101,6 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui | jle =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jg =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jle =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -15580,9 +15452,6 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o | jz =>target_label } else if (smart_branch_opcode == ZEND_JMPNZ) { | jnz =>target_label - } else if (smart_branch_opcode == ZEND_JMPZNZ) { - | jz =>target_label - | jmp =>target_label2 } else { ZEND_UNREACHABLE(); } @@ -15875,7 +15744,6 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa ZEND_FALLTHROUGH; case ZEND_BOOL: case ZEND_BOOL_NOT: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: return 1; @@ -16263,7 +16131,6 @@ bw_op: case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: - case ZEND_JMPZNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: op1_info = OP1_INFO(); diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index ef59254d70937..b822f8992d4f4 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -542,9 +542,6 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra case ZEND_FAST_CALL: SERIALIZE_PTR(opline->op1.jmp_addr); break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: @@ -1369,9 +1366,6 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr case ZEND_FAST_CALL: UNSERIALIZE_PTR(opline->op1.jmp_addr); break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 2ccfff3d04321..e21fa4cb9af2b 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -590,9 +590,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc case ZEND_FAST_CALL: opline->op1.jmp_addr = &new_opcodes[opline->op1.jmp_addr - op_array->opcodes]; break; - case ZEND_JMPZNZ: - /* relative extended_value don't have to be changed */ - /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: From 703cac33db5184f1c1d0c0feb2bfcf91b2e4944e Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 10 Jan 2022 17:57:46 +0100 Subject: [PATCH 072/227] Fix GH-7867: FFI::cast() from pointer to array is broken Casting from pointer to array is special, so we must not fall back to the general FFI casting. There is a particular issue regarding the size comparison, namely that the pointer size is always 8 for 64bit architectures, but the size of an array is determined by its declaration, so as is casting a pointer to an array with more than 8 elements would fail, but casting to an array with less than 9 elements succeeds, but the internal pointer would point to some arbitrary memory. We fix this by properly supporting the cast. An alternative would be to deny this kind of cast generally, since it is not necessarily safe. However, FFI isn't necessarily safe anyway. We also check pointer/array type compatibility when casting. Co-authored-by: Dmitry Stogov Closes GH-7876. --- NEWS | 4 +++ ext/ffi/ffi.c | 11 ++++-- ext/ffi/tests/gh7867.phpt | 75 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 ext/ffi/tests/gh7867.phpt diff --git a/NEWS b/NEWS index 0490d3701cca0..8a2fa41b3d5ef 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed bug #81430 (Attribute instantiation leaves dangling pointer). (beberlei) +- FFI: + . Fixed bug GH-7867 (FFI::cast() from pointer to array is broken). (cmb, + dmitry) + - FPM: . Fixed memory leak on invalid port. (David Carlier) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index e3da06698f659..8f4a25b0d6227 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -3904,9 +3904,14 @@ ZEND_METHOD(FFI, cast) /* {{{ */ /* automatically dereference void* pointers ??? */ cdata->ptr = *(void**)ptr; } else if (old_type->kind == ZEND_FFI_TYPE_ARRAY - && type->kind == ZEND_FFI_TYPE_POINTER) { - cdata->ptr = &cdata->ptr_holder; - cdata->ptr_holder = old_cdata->ptr; + && type->kind == ZEND_FFI_TYPE_POINTER + && zend_ffi_is_compatible_type(ZEND_FFI_TYPE(old_type->array.type), ZEND_FFI_TYPE(type->pointer.type))) { cdata->ptr = &cdata->ptr_holder; + cdata->ptr = &cdata->ptr_holder; + cdata->ptr_holder = old_cdata->ptr; + } else if (old_type->kind == ZEND_FFI_TYPE_POINTER + && type->kind == ZEND_FFI_TYPE_ARRAY + && zend_ffi_is_compatible_type(ZEND_FFI_TYPE(old_type->pointer.type), ZEND_FFI_TYPE(type->array.type))) { + cdata->ptr = old_cdata->ptr_holder; } else if (type->size > old_type->size) { zend_object_release(&cdata->std); zend_throw_error(zend_ffi_exception_ce, "attempt to cast to larger type"); diff --git a/ext/ffi/tests/gh7867.phpt b/ext/ffi/tests/gh7867.phpt new file mode 100644 index 0000000000000..7728d15b1c616 --- /dev/null +++ b/ext/ffi/tests/gh7867.phpt @@ -0,0 +1,75 @@ +--TEST-- +GH-7867 (FFI::cast() from pointer to array is broken) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +cast from start +object(FFI\CData:char*)#%d (1) { + [0]=> + string(1) "a" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" +} + +cast with offset +object(FFI\CData:char*)#%d (1) { + [0]=> + string(1) "e" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "e" + [1]=> + string(1) "f" + [2]=> + string(1) "g" + [3]=> + string(1) "h" +} +object(FFI\CData:char[4])#%d (4) { + [0]=> + string(1) "e" + [1]=> + string(1) "f" + [2]=> + string(1) "g" + [3]=> + string(1) "h" +} From d7db5f6e210109a8a3c7c5e123c233ca59fbebe0 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Fri, 5 Nov 2021 13:50:57 +0100 Subject: [PATCH 073/227] Fix TSRM ignoring done --- TSRM/TSRM.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index fc6c932065b0e..3d93accddde77 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -188,11 +188,16 @@ TSRM_API void tsrm_shutdown(void) next_p = p->next; for (j=0; jcount; j++) { if (p->storage[j]) { - if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j]); - } - if (!resource_types_table[j].fast_offset) { - free(p->storage[j]); + if (resource_types_table) { + if (!resource_types_table[j].done) { + if (resource_types_table[j].dtor) { + resource_types_table[j].dtor(p->storage[j]); + } + + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); + } + } } } } @@ -531,11 +536,13 @@ void ts_free_id(ts_rsrc_id id) while (p) { if (p->count > j && p->storage[j]) { - if (resource_types_table && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j]); - } - if (!resource_types_table[j].fast_offset) { - free(p->storage[j]); + if (resource_types_table) { + if (resource_types_table[j].dtor) { + resource_types_table[j].dtor(p->storage[j]); + } + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); + } } p->storage[j] = NULL; } From e1782c08bff84e8aae0397b68f71236d8d1fd13f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 11 Jan 2022 09:13:22 +0300 Subject: [PATCH 074/227] Fix ASAN undefined behavior (unsigned char << 24) ext/mbstring/libmbfl/filters/mbfilter_utf32.c:259:20: runtime error: left shift of 128 by 24 places cannot be represented in type 'int' --- ext/mbstring/libmbfl/filters/mbfilter_ucs4.c | 24 +++++++++---------- ext/mbstring/libmbfl/filters/mbfilter_utf32.c | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c index c7f5fb2ac04fa..09796390b3df6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c @@ -320,10 +320,10 @@ static size_t mb_ucs4_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf return mb_ucs4le_to_wchar(in, in_len, buf, bufsize, NULL); } else if (*in_len >= 4) { unsigned char *p = *in; - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; if (w == 0xFFFE0000) { @@ -349,10 +349,10 @@ static size_t mb_ucs4be_to_wchar(unsigned char **in, size_t *in_len, uint32_t *b uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; *out++ = w; } @@ -393,10 +393,10 @@ static size_t mb_ucs4le_to_wchar(unsigned char **in, size_t *in_len, uint32_t *b uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c4 << 24) | (c3 << 16) | (c2 << 8) | c1; *out++ = w; } diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c index c654e4cf51020..a6594ed75162e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c @@ -252,10 +252,10 @@ static size_t mb_utf32_to_wchar(unsigned char **in, size_t *in_len, uint32_t *bu return mb_utf32le_to_wchar(in, in_len, buf, bufsize, NULL); } else if (*in_len >= 4) { unsigned char *p = *in; - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; if (w == 0xFFFE0000) { @@ -281,10 +281,10 @@ static size_t mb_utf32be_to_wchar(unsigned char **in, size_t *in_len, uint32_t * uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; if (w < MBFL_WCSPLANE_UTF32MAX && (w < 0xD800 || w > 0xDFFF)) { @@ -330,10 +330,10 @@ static size_t mb_utf32le_to_wchar(unsigned char **in, size_t *in_len, uint32_t * uint32_t *out = buf, *limit = buf + bufsize; while (p < e && out < limit) { - unsigned char c1 = *p++; - unsigned char c2 = *p++; - unsigned char c3 = *p++; - unsigned char c4 = *p++; + uint32_t c1 = *p++; + uint32_t c2 = *p++; + uint32_t c3 = *p++; + uint32_t c4 = *p++; uint32_t w = (c4 << 24) | (c3 << 16) | (c2 << 8) | c1; if (w < MBFL_WCSPLANE_UTF32MAX && (w < 0xD800 || w > 0xDFFF)) { From d8b0337cff18d4a7e6ec288dd470efa2e720ecf8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 11 Jan 2022 13:02:55 +0300 Subject: [PATCH 075/227] Fix register allocation on x86 Fixes oss-fuzz #43119 --- ext/opcache/jit/zend_jit_x86.dasc | 28 ++++++++++++++++---------- ext/opcache/tests/jit/assign_049.phpt | 29 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_049.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 54b1f1ce09c90..ee56f424b37c8 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -6039,6 +6039,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 0); } else { zend_jit_addr ref_addr; + zend_reg type_reg = tmp_reg; if (in_cold) { | IF_NOT_ZVAL_TYPE val_addr, IS_REFERENCE, >1 @@ -6047,21 +6048,24 @@ static int zend_jit_simple_assign(dasm_State **Dst, |.cold_code |1: } - if (Z_REG(val_addr) == ZREG_R2) { - | mov aword T1, r2 // save - } | // zend_refcounted *ref = Z_COUNTED_P(retval_ptr); | GET_ZVAL_PTR r2, val_addr | GC_DELREF r2 | // ZVAL_COPY_VALUE(return_value, &ref->value); ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 8); if (!res_addr) { - | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, tmp_reg + | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, type_reg, tmp_reg } else { - | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, tmp_reg + | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, type_reg, tmp_reg } | je >2 - | IF_NOT_REFCOUNTED dh, >3 + if (tmp_reg == ZREG_R0) { + | IF_NOT_REFCOUNTED ah, >3 + } else { + | IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >3 + } + | GET_ZVAL_PTR Ra(tmp_reg), var_addr + if (!res_addr) { | GC_ADDREF Ra(tmp_reg) } else { @@ -6070,17 +6074,19 @@ static int zend_jit_simple_assign(dasm_State **Dst, | jmp >3 |2: if (res_addr) { - | IF_NOT_REFCOUNTED dh, >2 + if (tmp_reg == ZREG_R0) { + | IF_NOT_REFCOUNTED ah, >2 + } else { + | IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >2 + } + | GET_ZVAL_PTR Ra(tmp_reg), var_addr | GC_ADDREF Ra(tmp_reg) |2: } - if (Z_REG(val_addr) == ZREG_R2) { - | mov r2, aword T1 // restore - } if (save_r1) { | mov aword T1, FCARG1a // save } - | EFREE_REFERENCE aword [Ra(Z_REG(val_addr))+Z_OFFSET(val_addr)] + | EFREE_REFERENCE r2 if (save_r1) { | mov FCARG1a, aword T1 // restore } diff --git a/ext/opcache/tests/jit/assign_049.phpt b/ext/opcache/tests/jit/assign_049.phpt new file mode 100644 index 0000000000000..f085e51f3234a --- /dev/null +++ b/ext/opcache/tests/jit/assign_049.phpt @@ -0,0 +1,29 @@ +--TEST-- +JIT ASSIGN: register allocation on x86 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- +a = a(1); + } +} + +$a = new A; +$a->test(); +$a->test(); +?> +DONE +--EXPECT-- +DONE From 522406c0ec8d35f12683acfb3f4ee8d5b6ea6f13 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 11 Jan 2022 22:23:44 +0300 Subject: [PATCH 076/227] JIT: Fix incorrect flag check Fixes oss-fuzz #43538 --- ext/opcache/jit/zend_jit_x86.dasc | 4 ++-- ext/opcache/tests/jit/assign_dim_009.phpt | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_dim_009.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ee56f424b37c8..e9068c39e5e4a 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -6062,7 +6062,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, if (tmp_reg == ZREG_R0) { | IF_NOT_REFCOUNTED ah, >3 } else { - | IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >3 + | IF_NOT_FLAGS Rd(tmp_reg), (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT), >3 } | GET_ZVAL_PTR Ra(tmp_reg), var_addr @@ -6077,7 +6077,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, if (tmp_reg == ZREG_R0) { | IF_NOT_REFCOUNTED ah, >2 } else { - | IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >2 + | IF_NOT_FLAGS Rd(tmp_reg), (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT), >2 } | GET_ZVAL_PTR Ra(tmp_reg), var_addr | GC_ADDREF Ra(tmp_reg) diff --git a/ext/opcache/tests/jit/assign_dim_009.phpt b/ext/opcache/tests/jit/assign_dim_009.phpt new file mode 100644 index 0000000000000..bea28098a5e9b --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_009.phpt @@ -0,0 +1,14 @@ +--TEST-- +JIT ASSIGN_DIM: 009 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From f7c3f6e7e25471da9cfb2ba082a77cc3c85bc6ed Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 12 Jan 2022 12:08:59 +0300 Subject: [PATCH 077/227] Fix ext/zend_test/tests/observer_bug81430_2.phpt failure --- ext/reflection/php_reflection.c | 48 ++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 61df70c4ec8a4..c2c379be2823a 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6290,9 +6290,7 @@ static int call_attribute_constructor( zval *args, uint32_t argc, HashTable *named_params, zend_string *filename) { zend_function *ctor = ce->constructor; - zend_execute_data *prev_execute_data, dummy_frame; - zend_function dummy_func; - zend_op dummy_opline; + zend_execute_data *call = NULL; ZEND_ASSERT(ctor != NULL); if (!(ctor->common.fn_flags & ZEND_ACC_PUBLIC)) { @@ -6303,31 +6301,43 @@ static int call_attribute_constructor( if (filename) { /* Set up dummy call frame that makes it look like the attribute was invoked * from where it occurs in the code. */ - memset(&dummy_frame, 0, sizeof(zend_execute_data)); - memset(&dummy_func, 0, sizeof(zend_function)); - memset(&dummy_opline, 0, sizeof(zend_op)); + zend_function dummy_func; + zend_op *opline; - prev_execute_data = EG(current_execute_data); - dummy_frame.prev_execute_data = prev_execute_data; - dummy_frame.func = &dummy_func; - dummy_frame.opline = &dummy_opline; + memset(&dummy_func, 0, sizeof(zend_function)); - dummy_func.type = ZEND_USER_FUNCTION; - dummy_func.common.fn_flags = + call = zend_vm_stack_push_call_frame_ex( + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_execute_data), sizeof(zval)) + + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_op), sizeof(zval)) + + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_function), sizeof(zval)), + 0, &dummy_func, 0, NULL); + + opline = (zend_op*)(call + 1); + memset(opline, 0, sizeof(zend_op)); + opline->opcode = ZEND_DO_FCALL; + opline->lineno = attr->lineno; + + call->opline = opline; + call->call = NULL; + call->return_value = NULL; + call->func = (zend_function*)(call->opline + 1); + call->prev_execute_data = EG(current_execute_data); + + memset(call->func, 0, sizeof(zend_function)); + call->func->type = ZEND_USER_FUNCTION; + call->func->op_array.fn_flags = attr->flags & ZEND_ATTRIBUTE_STRICT_TYPES ? ZEND_ACC_STRICT_TYPES : 0; - dummy_func.common.fn_flags |= ZEND_ACC_CALL_VIA_TRAMPOLINE; - dummy_func.op_array.filename = filename; - - dummy_opline.opcode = ZEND_DO_FCALL; - dummy_opline.lineno = attr->lineno; + call->func->op_array.fn_flags |= ZEND_ACC_CALL_VIA_TRAMPOLINE; + call->func->op_array.filename = filename; - EG(current_execute_data) = &dummy_frame; + EG(current_execute_data) = call; } zend_call_known_function(ctor, obj, obj->ce, NULL, argc, args, named_params); if (filename) { - EG(current_execute_data) = prev_execute_data; + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_call_frame(call); } if (EG(exception)) { From 78974a4776a25425d836a8e842b8519b14d4127b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 11 Jan 2022 22:23:44 +0300 Subject: [PATCH 078/227] JIT: Fix incorrect flag check Fixes oss-fuzz #43538 --- ext/opcache/jit/zend_jit_x86.dasc | 4 ++-- ext/opcache/tests/jit/assign_dim_009.phpt | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_dim_009.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ff272256c3267..20d76010c2e81 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -6135,7 +6135,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, if (tmp_reg == ZREG_R0) { | IF_NOT_REFCOUNTED ah, >3 } else { - | IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >3 + | IF_NOT_FLAGS Rd(tmp_reg), (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT), >3 } | GET_ZVAL_PTR Ra(tmp_reg), var_addr @@ -6150,7 +6150,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, if (tmp_reg == ZREG_R0) { | IF_NOT_REFCOUNTED ah, >2 } else { - | IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >2 + | IF_NOT_FLAGS Rd(tmp_reg), (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT), >2 } | GET_ZVAL_PTR Ra(tmp_reg), var_addr | GC_ADDREF Ra(tmp_reg) diff --git a/ext/opcache/tests/jit/assign_dim_009.phpt b/ext/opcache/tests/jit/assign_dim_009.phpt new file mode 100644 index 0000000000000..bea28098a5e9b --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_009.phpt @@ -0,0 +1,14 @@ +--TEST-- +JIT ASSIGN_DIM: 009 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 7e6558edf1570ebf09390624feb06747385f0224 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 12 Jan 2022 12:08:59 +0300 Subject: [PATCH 079/227] Fix ext/zend_test/tests/observer_bug81430_2.phpt failure --- ext/reflection/php_reflection.c | 48 ++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a1c97ae9ec037..b344943bf2288 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6522,9 +6522,7 @@ static int call_attribute_constructor( zval *args, uint32_t argc, HashTable *named_params, zend_string *filename) { zend_function *ctor = ce->constructor; - zend_execute_data *prev_execute_data, dummy_frame; - zend_function dummy_func; - zend_op dummy_opline; + zend_execute_data *call = NULL; ZEND_ASSERT(ctor != NULL); if (!(ctor->common.fn_flags & ZEND_ACC_PUBLIC)) { @@ -6535,31 +6533,43 @@ static int call_attribute_constructor( if (filename) { /* Set up dummy call frame that makes it look like the attribute was invoked * from where it occurs in the code. */ - memset(&dummy_frame, 0, sizeof(zend_execute_data)); - memset(&dummy_func, 0, sizeof(zend_function)); - memset(&dummy_opline, 0, sizeof(zend_op)); + zend_function dummy_func; + zend_op *opline; - prev_execute_data = EG(current_execute_data); - dummy_frame.prev_execute_data = prev_execute_data; - dummy_frame.func = &dummy_func; - dummy_frame.opline = &dummy_opline; + memset(&dummy_func, 0, sizeof(zend_function)); - dummy_func.type = ZEND_USER_FUNCTION; - dummy_func.common.fn_flags = + call = zend_vm_stack_push_call_frame_ex( + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_execute_data), sizeof(zval)) + + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_op), sizeof(zval)) + + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_function), sizeof(zval)), + 0, &dummy_func, 0, NULL); + + opline = (zend_op*)(call + 1); + memset(opline, 0, sizeof(zend_op)); + opline->opcode = ZEND_DO_FCALL; + opline->lineno = attr->lineno; + + call->opline = opline; + call->call = NULL; + call->return_value = NULL; + call->func = (zend_function*)(call->opline + 1); + call->prev_execute_data = EG(current_execute_data); + + memset(call->func, 0, sizeof(zend_function)); + call->func->type = ZEND_USER_FUNCTION; + call->func->op_array.fn_flags = attr->flags & ZEND_ATTRIBUTE_STRICT_TYPES ? ZEND_ACC_STRICT_TYPES : 0; - dummy_func.common.fn_flags |= ZEND_ACC_CALL_VIA_TRAMPOLINE; - dummy_func.op_array.filename = filename; - - dummy_opline.opcode = ZEND_DO_FCALL; - dummy_opline.lineno = attr->lineno; + call->func->op_array.fn_flags |= ZEND_ACC_CALL_VIA_TRAMPOLINE; + call->func->op_array.filename = filename; - EG(current_execute_data) = &dummy_frame; + EG(current_execute_data) = call; } zend_call_known_function(ctor, obj, obj->ce, NULL, argc, args, named_params); if (filename) { - EG(current_execute_data) = prev_execute_data; + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_call_frame(call); } if (EG(exception)) { From 524ce9041862159ed1bbaf29d387782c6f8d534c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 7 Jan 2022 15:04:36 +0100 Subject: [PATCH 080/227] fix GH-7899 Regression in unpack for negative int value --- NEWS | 3 +++ ext/standard/pack.c | 11 +++++++++-- ext/standard/tests/strings/pack64.phpt | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 812b1005ccb19..cbcabd058ac8c 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS - pcntl: . Fixed pcntl_rfork build for DragonFlyBSD. (David Carlier) +- Standard: + . Fixed bug GH-7899 (Regression in unpack for negative int value). (Remi) + 06 Jan 2022, PHP 8.1.2RC1 - Core: diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 46856874bc2a1..8736d291fb246 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -62,6 +62,7 @@ typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t); typedef ZEND_SET_ALIGNED(1, uint32_t unaligned_uint32_t); typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t); typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_uint); +typedef ZEND_SET_ALIGNED(1, int unaligned_int); /* Mapping of byte from char (8bit) to long for machine endian */ static int byte_map[1]; @@ -1043,8 +1044,14 @@ PHP_FUNCTION(unpack) case 'i': /* signed integer, machine size, machine endian */ case 'I': { /* unsigned integer, machine size, machine endian */ - unsigned int x = *((unaligned_uint*) &input[inputpos]); - zend_long v = (type == 'i') ? (int) x : x; + zend_long v; + if (type == 'i') { + int x = *((unaligned_int*) &input[inputpos]); + v = x; + } else { + unsigned int x = *((unaligned_uint*) &input[inputpos]); + v = x; + } ZVAL_LONG(&val, v); zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val); diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt index 753821f654299..84e69008284d4 100644 --- a/ext/standard/tests/strings/pack64.phpt +++ b/ext/standard/tests/strings/pack64.phpt @@ -31,6 +31,11 @@ print_r(unpack("q", pack("q", 0))); print_r(unpack("q", pack("q", 0x8000000000000002))); print_r(unpack("q", pack("q", -1))); print_r(unpack("q", pack("q", 0x8000000000000000))); + +print_r(unpack("i", pack("i", 2147483647))); // Max int32 +print_r(unpack("i", pack("i", -2147483647))); +print_r(unpack("i", pack("i", -2147483648))); // Min int32 +print_r(unpack("I", pack("I", 4294967295))); // Max uint32 ?> --EXPECT-- Array @@ -113,3 +118,19 @@ Array ( [1] => -9223372036854775808 ) +Array +( + [1] => 2147483647 +) +Array +( + [1] => -2147483647 +) +Array +( + [1] => -2147483648 +) +Array +( + [1] => 4294967295 +) From e31c54d02592caa31d6a59aaefeaa96aab2d7b27 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 7 Jan 2022 15:04:36 +0100 Subject: [PATCH 081/227] fix GH-7899 Regression in unpack for negative int value --- NEWS | 3 +++ ext/standard/pack.c | 11 +++++++++-- ext/standard/tests/strings/pack64.phpt | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 812b1005ccb19..cbcabd058ac8c 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS - pcntl: . Fixed pcntl_rfork build for DragonFlyBSD. (David Carlier) +- Standard: + . Fixed bug GH-7899 (Regression in unpack for negative int value). (Remi) + 06 Jan 2022, PHP 8.1.2RC1 - Core: diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 46856874bc2a1..8736d291fb246 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -62,6 +62,7 @@ typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t); typedef ZEND_SET_ALIGNED(1, uint32_t unaligned_uint32_t); typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t); typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_uint); +typedef ZEND_SET_ALIGNED(1, int unaligned_int); /* Mapping of byte from char (8bit) to long for machine endian */ static int byte_map[1]; @@ -1043,8 +1044,14 @@ PHP_FUNCTION(unpack) case 'i': /* signed integer, machine size, machine endian */ case 'I': { /* unsigned integer, machine size, machine endian */ - unsigned int x = *((unaligned_uint*) &input[inputpos]); - zend_long v = (type == 'i') ? (int) x : x; + zend_long v; + if (type == 'i') { + int x = *((unaligned_int*) &input[inputpos]); + v = x; + } else { + unsigned int x = *((unaligned_uint*) &input[inputpos]); + v = x; + } ZVAL_LONG(&val, v); zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val); diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt index 753821f654299..84e69008284d4 100644 --- a/ext/standard/tests/strings/pack64.phpt +++ b/ext/standard/tests/strings/pack64.phpt @@ -31,6 +31,11 @@ print_r(unpack("q", pack("q", 0))); print_r(unpack("q", pack("q", 0x8000000000000002))); print_r(unpack("q", pack("q", -1))); print_r(unpack("q", pack("q", 0x8000000000000000))); + +print_r(unpack("i", pack("i", 2147483647))); // Max int32 +print_r(unpack("i", pack("i", -2147483647))); +print_r(unpack("i", pack("i", -2147483648))); // Min int32 +print_r(unpack("I", pack("I", 4294967295))); // Max uint32 ?> --EXPECT-- Array @@ -113,3 +118,19 @@ Array ( [1] => -9223372036854775808 ) +Array +( + [1] => 2147483647 +) +Array +( + [1] => -2147483647 +) +Array +( + [1] => -2147483648 +) +Array +( + [1] => 4294967295 +) From 079c5af9ec516e0e60c6209135b127e3e1a86c64 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 14 Jan 2022 13:41:16 +0300 Subject: [PATCH 082/227] JIT: Fix register allocation Fixes oss-fuzz #43598 --- ext/opcache/jit/zend_jit_trace.c | 4 ++- ext/opcache/tests/jit/reg_alloc_006.phpt | 34 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/reg_alloc_006.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index d885fe84cb3ea..a1243926337bf 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3075,7 +3075,9 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace intervals[use]->used_as_hint = NULL; intervals[use]->list_next = NULL; } - } else if (intervals[use] && !ssa->vars[phi->ssa_var].no_val) { + } else if (intervals[use] + && (!ssa->vars[def].no_val + || ssa->var_info[def].type != ssa->var_info[use].type)) { if (ssa->vars[use].use_chain >= 0) { intervals[use]->flags |= ZREG_STORE; } else { diff --git a/ext/opcache/tests/jit/reg_alloc_006.phpt b/ext/opcache/tests/jit/reg_alloc_006.phpt new file mode 100644 index 0000000000000..4f4c3fb5fa2b4 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_006.phpt @@ -0,0 +1,34 @@ +--TEST-- +Register Alloction 006: Incorrect type store elimination +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 + +Warning: Undefined variable $y in %sreg_alloc_006.php on line 5 +DONE \ No newline at end of file From ee8f9d75c0ced8bdbcae01dd98654d13e29ae8c0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 14 Jan 2022 16:43:50 +0300 Subject: [PATCH 083/227] JIT: Fix trace type inference Fixes oss-fuzz #43597 --- ext/opcache/jit/zend_jit_trace.c | 5 +++++ ext/opcache/tests/jit/assign_dim_010.phpt | 24 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_010.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index a1243926337bf..b871304aea812 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1556,6 +1556,11 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin if (opline->result_type != IS_UNUSED) { break; } + if (op3_type != IS_UNKNOWN + && !zend_jit_supported_binary_op( + opline->extended_value, MAY_BE_ANY, (1<op1_type == IS_CV) { diff --git a/ext/opcache/tests/jit/assign_dim_010.phpt b/ext/opcache/tests/jit/assign_dim_010.phpt new file mode 100644 index 0000000000000..313638e77fb7f --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_010.phpt @@ -0,0 +1,24 @@ +--TEST-- +JIT ASSIGN_DIM: 010 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $a in %sassign_dim_010.php on line 4 + +Warning: Undefined variable $y in %sassign_dim_010.php on line 4 +DONE From 655e578e816e6eec767b25963e93d8e044a9f392 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 14 Jan 2022 17:24:23 +0300 Subject: [PATCH 084/227] JIT: Fix exception handling Fixes oss-fuzz #43618 --- ext/opcache/jit/zend_jit_helpers.c | 3 +++ ext/opcache/tests/jit/assign_dim_011.phpt | 25 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_011.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index f1a24ea856b90..a36cccb40145c 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2379,6 +2379,9 @@ static zval * ZEND_FASTCALL zend_jit_prepare_assign_dim_ref(zval *ref) { if (Z_TYPE_P(val) == IS_FALSE) { ZVAL_ARR(val, zend_new_array(8)); zend_false_to_array_deprecated(); + if (EG(exception)) { + return NULL; + } } else { ZVAL_ARR(val, zend_new_array(8)); } diff --git a/ext/opcache/tests/jit/assign_dim_011.phpt b/ext/opcache/tests/jit/assign_dim_011.phpt new file mode 100644 index 0000000000000..941033a8ac6cd --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_011.phpt @@ -0,0 +1,25 @@ +--TEST-- +JIT ASSIGN_DIM: 011 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +getMessage() . "\n"; +} +?> +DONE +--EXPECT-- +Err: Automatic conversion of false to array is deprecated +Exception: Cannot use a scalar value as an array +DONE From 944b6b6bbd6f05ad905f5f4ad07445792bee4027 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 16 Jan 2022 13:31:58 -0500 Subject: [PATCH 085/227] Merge concatenated literal strings while compiling. (#7948) The output of token_get_all is unaffected, so projects such as the userland nikic/php-parser are unaffected. Extensions such as nikic/php-ast which expose the internal php ast would see literals be flattened, though. This makes php significantly faster at parsing code such as `$x = eval('return ' . var_export(str_repeat("\0", 100), true) . ';');` and avoids the stack overflow from recursing 100000 times in zend_eval_const_expr to process `'' . "\0" . '' . "\0" . ...` Closes GH-7946 * Don't create binary op if unnecessary * Update Zend/zend_ast.c Co-authored-by: Nikita Popov --- Zend/zend_ast.c | 13 +++++++++++++ Zend/zend_ast.h | 3 +++ Zend/zend_language_parser.y | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 0d69bfbaca369..e08a140a35541 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -420,6 +420,19 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki } #endif +zend_ast *zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1) { + if (op0->kind == ZEND_AST_ZVAL && op1->kind == ZEND_AST_ZVAL) { + zval *zv0 = zend_ast_get_zval(op0); + zval *zv1 = zend_ast_get_zval(op1); + if (!zend_binary_op_produces_error(ZEND_CONCAT, zv0, zv1) && + concat_function(zv0, zv0, zv1) == SUCCESS) { + zval_ptr_dtor_nogc(zv1); + return zend_ast_create_zval(zv0); + } + } + return zend_ast_create_binary_op(ZEND_CONCAT, op0, op1); +} + static inline bool is_power_of_two(uint32_t n) { return ((n != 0) && (n == (n & (~n + 1)))); } diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 86f153580063c..d2940bbe633a8 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -355,6 +355,9 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { static zend_always_inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(ZEND_AST_BINARY_OP, opcode, op0, op1); } + +zend_ast *zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1); + static zend_always_inline zend_ast *zend_ast_create_assign_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(ZEND_AST_ASSIGN_OP, opcode, op0, op1); } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index a8bddfae50a3e..f6ba5465abebb 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1129,7 +1129,7 @@ expr: | expr T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } | expr '^' expr { $$ = zend_ast_create_binary_op(ZEND_BW_XOR, $1, $3); } - | expr '.' expr { $$ = zend_ast_create_binary_op(ZEND_CONCAT, $1, $3); } + | expr '.' expr { $$ = zend_ast_create_concat_op($1, $3); } | expr '+' expr { $$ = zend_ast_create_binary_op(ZEND_ADD, $1, $3); } | expr '-' expr { $$ = zend_ast_create_binary_op(ZEND_SUB, $1, $3); } | expr '*' expr { $$ = zend_ast_create_binary_op(ZEND_MUL, $1, $3); } From 478edcdacbae8326d6299935334dd4083f84168d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 4 Jan 2022 15:44:56 +0100 Subject: [PATCH 086/227] Fix GH-7875: mails are sent even if failure to log throws exception MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We explicitly check for an exception after the logging attempt, and bail out in that case. Co-authored-by: Tim Düsterhus Closes GH-7878. --- NEWS | 4 ++++ ext/standard/mail.c | 4 ++++ ext/standard/tests/mail/gh7875.phpt | 35 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 ext/standard/tests/mail/gh7875.phpt diff --git a/NEWS b/NEWS index 8a2fa41b3d5ef..e09d6129c66f1 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ PHP NEWS - Sockets: . Fixed ext/sockets build on Haiku. (David Carlier) +- Standard: + . Fixed bug GH-7875 (mails are sent even if failure to log throws exception). + (cmb) + 20 Jan 2022, PHP 8.0.15 - Core: diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 3080a3957bb9c..edc85a1becc8e 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -473,6 +473,10 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co efree(logline); } + if (EG(exception)) { + MAIL_RET(0); + } + if (PG(mail_x_header)) { const char *tmp = zend_get_executed_filename(); zend_string *f; diff --git a/ext/standard/tests/mail/gh7875.phpt b/ext/standard/tests/mail/gh7875.phpt new file mode 100644 index 0000000000000..f19fe5f3194f5 --- /dev/null +++ b/ext/standard/tests/mail/gh7875.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-7875 (mails are sent even if failure to log throws exception) +--INI-- +sendmail_path={MAIL:{PWD}/gh7875.mail.out} +mail.log={PWD}/gh7875.mail.log +--FILE-- +getMessage(), PHP_EOL; + var_dump(file_exists(__DIR__ . "/gh7875.mail.out")); +} +?> +--CLEAN-- + +--EXPECTF-- +mail(%s): Failed to open stream: Permission denied +bool(false) From 93a3c71eb49aa8fcb8f87df967d427e40d782613 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 11 Jan 2022 13:43:42 +0100 Subject: [PATCH 087/227] Fix GH-7896: Environment vars may be mangled on Windows When bug 77574[1] has been fixed, the fix only catered to variables retrieved via `getenv()` with a `$varname` passed, but neither to `getenv()` without arguments nor to the general import of environment variables into `$_ENV` and `$_SERVER`. We catch up on this by using `GetEnvironmentStringsW()` in `_php_import_environment_variables()` and converting the encoding to whatever had been chosen by the user. [1] Closes GH-7928. --- NEWS | 1 + main/php_variables.c | 12 ++++++++---- tests/basic/gh7896.phpt | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 tests/basic/gh7896.phpt diff --git a/NEWS b/NEWS index e09d6129c66f1..4b5d96f48e5ee 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ PHP NEWS - Core: . Fixed bug #81430 (Attribute instantiation leaves dangling pointer). (beberlei) + . Fixed bug GH-7896 (Environment vars may be mangled on Windows). (cmb) - FFI: . Fixed bug GH-7867 (FFI::cast() from pointer to array is broken). (cmb, diff --git a/main/php_variables.c b/main/php_variables.c index 312c22ef07db7..6a8ff5e1f0910 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -571,11 +571,15 @@ void _php_import_environment_variables(zval *array_ptr) import_environment_variable(Z_ARRVAL_P(array_ptr), *env); } #else - char *environment = GetEnvironmentStringsA(); - for (char *env = environment; env != NULL && *env; env += strlen(env) + 1) { - import_environment_variable(Z_ARRVAL_P(array_ptr), env); + wchar_t *environmentw = GetEnvironmentStringsW(); + for (wchar_t *envw = environmentw; envw != NULL && *envw; envw += wcslen(envw) + 1) { + char *env = php_win32_cp_w_to_any(envw); + if (env != NULL) { + import_environment_variable(Z_ARRVAL_P(array_ptr), env); + free(env); + } } - FreeEnvironmentStringsA(environment); + FreeEnvironmentStringsW(environmentw); #endif tsrm_env_unlock(); diff --git a/tests/basic/gh7896.phpt b/tests/basic/gh7896.phpt new file mode 100644 index 0000000000000..2ad2958d1cd9a --- /dev/null +++ b/tests/basic/gh7896.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-7896 (Environment vars may be mangled on Windows) +--SKIPIF-- + +--ENV-- +FÖÖ=GüИter传 +--FILE-- + +--EXPECT-- +string(11) "GüИter传" +string(11) "GüИter传" +string(11) "GüИter传" From 2c4b9e995a5de31af8fb928351bd632fe0ac5ce6 Mon Sep 17 00:00:00 2001 From: Tony Su Date: Tue, 18 Jan 2022 18:41:50 +0800 Subject: [PATCH 088/227] [JIT] Print out more meaningful warning message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [JIT] Print out more meaningful warning message When the setting value is out of range for jit_hot_loop, jit_hot_func, jit_hot_return, and jit_hot_side_exit, current PHP only prints out warning message like: Warning: Invalid "opcache.jit_hot_loop" setting. Should be between 0 and 256 in Unknown on line 0 With this small patch, PHP can print out more meaningful information, and tell user default value will be used and correct value range, like Warning: Invalid "opcache.jit_hot_loop" setting; using default value instead. Should be between 0 and 255 in Unknown on line 0 This patch has been verified on my local machine. Signed-off-by: Su, Tao Co-authored-by: Michael Voříšek Co-authored-by: Christoph M. Becker Closes GH-7955. --- ext/opcache/zend_accelerator_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index f785303c936a7..b09eb9ff41ad9 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -182,7 +182,7 @@ static ZEND_INI_MH(OnUpdateCounter) *p = val; return SUCCESS; } - zend_error(E_WARNING, "Invalid \"%s\" setting. Should be between 0 and 256", ZSTR_VAL(entry->name)); + zend_error(E_WARNING, "Invalid \"%s\" setting; using default value instead. Should be between 0 and 255", ZSTR_VAL(entry->name)); return FAILURE; } From 03816fba46d5db687d27d7cfbd471411b76cf9ee Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 18 Jan 2022 12:01:13 +0100 Subject: [PATCH 089/227] Fix GH-7902: mb_send_mail may delimit headers with LF only Email headers are supposed to be separated with CRLF. Period. We introduce a `CRLF` macro for better comprehensibility right away. Closes GH-7907. --- NEWS | 3 +++ ext/mbstring/mbstring.c | 14 +++++++++----- ext/mbstring/tests/gh7902.phpt | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 ext/mbstring/tests/gh7902.phpt diff --git a/NEWS b/NEWS index 4b5d96f48e5ee..f4f0013fe00e3 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ PHP NEWS - FPM: . Fixed memory leak on invalid port. (David Carlier) +- MBString: + . Fixed bug GH-7902 (mb_send_mail may delimit headers with LF only). (cmb) + - Sockets: . Fixed ext/sockets build on Haiku. (David Carlier) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index a5284264f3d34..48f22a682a196 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3270,6 +3270,8 @@ PHP_FUNCTION(mb_decode_numericentity) continue; \ } +#define CRLF "\r\n" + static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t str_len) { const char *ps; @@ -3601,7 +3603,7 @@ PHP_FUNCTION(mb_send_mail) || orig_str.encoding->no_encoding == mbfl_no_encoding_pass) { orig_str.encoding = mbfl_identify_encoding(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection)); } - pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, "\n", sizeof("Subject: [PHP-jp nnnnnnnn]")); + pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, CRLF, sizeof("Subject: [PHP-jp nnnnnnnn]" CRLF) - 1); if (pstr != NULL) { subject_buf = subject = (char *)pstr->val; } @@ -3640,14 +3642,14 @@ PHP_FUNCTION(mb_send_mail) n = ZSTR_LEN(str_headers); mbfl_memory_device_strncat(&device, p, n); if (n > 0 && p[n - 1] != '\n') { - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } zend_string_release_ex(str_headers, 0); } if (!zend_hash_str_exists(&ht_headers, "MIME-VERSION", sizeof("MIME-VERSION") - 1)) { mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER1, sizeof(PHP_MBSTR_MAIL_MIME_HEADER1) - 1); - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } if (!suppressed_hdrs.cnt_type) { @@ -3658,7 +3660,7 @@ PHP_FUNCTION(mb_send_mail) mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER3, sizeof(PHP_MBSTR_MAIL_MIME_HEADER3) - 1); mbfl_memory_device_strcat(&device, p); } - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } if (!suppressed_hdrs.cnt_trans_enc) { mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER4, sizeof(PHP_MBSTR_MAIL_MIME_HEADER4) - 1); @@ -3667,9 +3669,10 @@ PHP_FUNCTION(mb_send_mail) p = "7bit"; } mbfl_memory_device_strcat(&device, p); - mbfl_memory_device_strncat(&device, "\n", 1); + mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1); } + mbfl_memory_device_unput(&device); mbfl_memory_device_unput(&device); mbfl_memory_device_output('\0', &device); str_headers = zend_string_init((char *)device.buffer, strlen((char *)device.buffer), 0); @@ -3707,6 +3710,7 @@ PHP_FUNCTION(mb_send_mail) } #undef SKIP_LONG_HEADER_SEP_MBSTRING +#undef CRLF #undef MAIL_ASCIIZ_CHECK_MBSTRING #undef PHP_MBSTR_MAIL_MIME_HEADER1 #undef PHP_MBSTR_MAIL_MIME_HEADER2 diff --git a/ext/mbstring/tests/gh7902.phpt b/ext/mbstring/tests/gh7902.phpt new file mode 100644 index 0000000000000..d9a0fced7913d --- /dev/null +++ b/ext/mbstring/tests/gh7902.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-7902 (mb_send_mail may delimit headers with LF only) +--SKIPIF-- + +--INI-- +sendmail_path={MAIL:{PWD}/gh7902.eml} +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(0) From cdfc4d3596d9f983b7395ee11641cbf37b77b46e Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 17 Jan 2022 10:23:15 +0100 Subject: [PATCH 090/227] Fix GH-7883 don't close not open file handle don't create a stream if file is not open --- NEWS | 1 + Zend/zend_stream.c | 5 ++++- main/php_ini.c | 7 ++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 39c1d484f3f93..a35589a51b036 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ PHP NEWS . Fixed bug #81430 (Attribute instantiation leaves dangling pointer). (beberlei) . Fixed bug GH-7896 (Environment vars may be mangled on Windows). (cmb) + . Fixed bug GH-7883 (Segfault when INI file is not readable). (Remi) - FFI: . Fixed bug GH-7867 (FFI::cast() from pointer to array is broken). (cmb, diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index aadc62558e601..ae2c734b09b4e 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -214,7 +214,10 @@ static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */ { switch (fh->type) { case ZEND_HANDLE_FP: - fclose(fh->handle.fp); + if (fh->handle.fp) { + fclose(fh->handle.fp); + fh->handle.fp = NULL; + } break; case ZEND_HANDLE_STREAM: if (fh->handle.stream.closer && fh->handle.stream.handle) { diff --git a/main/php_ini.c b/main/php_ini.c index fd6f366488212..136942896da4d 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -686,8 +686,9 @@ int php_init_config(void) if (VCWD_STAT(ini_file, &sb) == 0) { if (S_ISREG(sb.st_mode)) { zend_file_handle fh; - zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file); - if (fh.handle.fp) { + FILE *file = VCWD_FOPEN(ini_file, "r"); + if (file) { + zend_stream_init_fp(&fh, file, ini_file); if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash) == SUCCESS) { /* Here, add it to the list of ini files read */ l = (int)strlen(ini_file); @@ -695,8 +696,8 @@ int php_init_config(void) p = estrndup(ini_file, l); zend_llist_add_element(&scanned_ini_list, &p); } + zend_destroy_file_handle(&fh); } - zend_destroy_file_handle(&fh); } } free(namelist[i]); From 20d8561ed4986c3ca1e514b7bcb2dda8b6fbe0ee Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Tue, 18 Jan 2022 14:04:42 +0000 Subject: [PATCH 091/227] fuzzer support for FreeBSD, getting opcache location Closes GH-7926. --- sapi/fuzzer/fuzzer-execute-common.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sapi/fuzzer/fuzzer-execute-common.h b/sapi/fuzzer/fuzzer-execute-common.h index 3189d514c02e3..3ecd27d3fd991 100644 --- a/sapi/fuzzer/fuzzer-execute-common.h +++ b/sapi/fuzzer/fuzzer-execute-common.h @@ -16,6 +16,10 @@ #include
+#if defined(__FreeBSD__) +# include +#endif + #include "fuzzer.h" #include "fuzzer-sapi.h" #include "zend_exceptions.h" @@ -140,7 +144,13 @@ ZEND_ATTRIBUTE_UNUSED char *get_opcache_path(void) { /* Try relative to binary location. */ char path[MAXPATHLEN]; +#if defined(__FreeBSD__) + size_t pathlen = sizeof(path); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + if (sysctl(mib, 4, path, &pathlen, NULL, 0) < 0) { +#else if (readlink("/proc/self/exe", path, sizeof(path)) < 0) { +#endif ZEND_ASSERT(0 && "Failed to get binary path"); return NULL; } From 6af65eac8d972705d7ecc1218191b2e54cfd2b21 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 18 Jan 2022 18:09:44 -0600 Subject: [PATCH 092/227] Fix news entry for 8.1.2 --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a35589a51b036..b0a9b6433bc5a 100644 --- a/NEWS +++ b/NEWS @@ -26,7 +26,7 @@ PHP NEWS . Fixed bug GH-7875 (mails are sent even if failure to log throws exception). (cmb) -06 Jan 2022, PHP 8.1.2RC1 +20 Jan 2022, PHP 8.1.2 - Core: . Fixed bug #81216 (Nullsafe operator leaks dynamic property name). (Dmitry) From aff3709adabe2c83ceb3afbe1f485e3f1a434968 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 19 Jan 2022 20:10:23 +0100 Subject: [PATCH 093/227] [ci skip] Extend my maintainership of com_dotnet and gd --- EXTENSIONS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EXTENSIONS b/EXTENSIONS index bdc1b6d3a39ea..25cf9fbd6a981 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -250,7 +250,7 @@ STATUS: Working ------------------------------------------------------------------------------- EXTENSION: com_dotnet PRIMARY MAINTAINER: Wez Furlong (2003 - 2005) - Christoph M. Becker (2018 - 2020) + Christoph M. Becker (2018 - 2022) MAINTENANCE: Maintained STATUS: Windows SINCE: 5.0 @@ -313,7 +313,7 @@ STATUS: Working ------------------------------------------------------------------------------- EXTENSION: gd PRIMARY MAINTAINER: Pierre-Alain Joye (2002 - 2016) - Christoph M. Becker (2015 - 2020) + Christoph M. Becker (2015 - 2022) MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- From 5fc0db989ea6fdc4a37ed60216cdba751da6fde6 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Wed, 19 Jan 2022 17:14:08 +0000 Subject: [PATCH 094/227] Strip MariaDB 10 prefix Closes GH-7972 --- NEWS | 3 +++ ext/mysqli/tests/gh7932.phpt | 20 ++++++++++++++++++++ ext/mysqlnd/mysqlnd_connection.c | 8 -------- ext/mysqlnd/mysqlnd_wireprotocol.c | 7 +++++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 ext/mysqli/tests/gh7932.phpt diff --git a/NEWS b/NEWS index f4f0013fe00e3..285d6265ee955 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,9 @@ PHP NEWS - MBString: . Fixed bug GH-7902 (mb_send_mail may delimit headers with LF only). (cmb) +- MySQLnd: + . Fixed bug GH-7972 (MariaDB version prefix 5.5.5- is not stripped). (Kamil Tekiela) + - Sockets: . Fixed ext/sockets build on Haiku. (David Carlier) diff --git a/ext/mysqli/tests/gh7932.phpt b/ext/mysqli/tests/gh7932.phpt new file mode 100644 index 0000000000000..6a1303bfc9ce0 --- /dev/null +++ b/ext/mysqli/tests/gh7932.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-7972 (MariaDB version prefix not always stripped) +--SKIPIF-- + +--FILE-- +server_info, '5.5.5-')) { + print("Expecting stripped prefix. Found: " . $mysqli->server_info . "\n"); +} +?> +--EXPECT-- diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index 799e9b67a19ca..bfd68681717ef 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1436,14 +1436,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_server_version)(const MYSQLND_CONN_DATA * return 0; } -#define MARIA_DB_VERSION_HACK_PREFIX "5.5.5-" - - if ((conn->server_capabilities & CLIENT_PLUGIN_AUTH) - && !strncmp(p, MARIA_DB_VERSION_HACK_PREFIX, sizeof(MARIA_DB_VERSION_HACK_PREFIX)-1)) - { - p += sizeof(MARIA_DB_VERSION_HACK_PREFIX)-1; - } - major = ZEND_STRTOL(p, &p, 10); p += 1; /* consume the dot */ minor = ZEND_STRTOL(p, &p, 10); diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index b83de494c2f7d..6a3cafd39d8b7 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -41,6 +41,8 @@ const char mysqlnd_read_body_name[] = "mysqlnd_read_body"; #define ERROR_MARKER 0xFF #define EODATA_MARKER 0xFE +#define MARIADB_RPL_VERSION_HACK "5.5.5-" + /* {{{ mysqlnd_command_to_text */ const char * const mysqlnd_command_to_text[COM_END] = { @@ -369,6 +371,11 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet) DBG_RETURN(PASS); } + /* MariaDB always sends 5.5.5 before version string: 5.5.5 was never released, + so just ignore it */ + if (!strncmp((char *) p, MARIADB_RPL_VERSION_HACK, sizeof(MARIADB_RPL_VERSION_HACK) - 1)) + p+= sizeof(MARIADB_RPL_VERSION_HACK) - 1; + packet->server_version = estrdup((char *)p); p+= strlen(packet->server_version) + 1; /* eat the '\0' */ BAIL_IF_NO_MORE_DATA; From 82b883034c8a25a95e85f3858b8d6539f9d991e8 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 20 Jan 2022 11:17:18 +0000 Subject: [PATCH 095/227] Fix coding style from previous commit --- ext/mysqlnd/mysqlnd_wireprotocol.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 6a3cafd39d8b7..20349e51419c4 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -373,8 +373,9 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet) /* MariaDB always sends 5.5.5 before version string: 5.5.5 was never released, so just ignore it */ - if (!strncmp((char *) p, MARIADB_RPL_VERSION_HACK, sizeof(MARIADB_RPL_VERSION_HACK) - 1)) - p+= sizeof(MARIADB_RPL_VERSION_HACK) - 1; + if (!strncmp((char *) p, MARIADB_RPL_VERSION_HACK, sizeof(MARIADB_RPL_VERSION_HACK) - 1)) { + p += sizeof(MARIADB_RPL_VERSION_HACK) - 1; + } packet->server_version = estrdup((char *)p); p+= strlen(packet->server_version) + 1; /* eat the '\0' */ From de4afc0fa75f133e154885d4dadd049e78d9723c Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 21 Jan 2022 12:05:53 +0100 Subject: [PATCH 096/227] [ci skip] Fix NEWS The fix for GH-7842 was too late for 8.1.2RC1, so will be in 8.1.3 only. --- NEWS | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 9bfcc8e67dca3..3687daf93e235 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ PHP NEWS - FPM: . Fixed memory leak on invalid port. (David Carlier) + . Fixed bug GH-7842 (Invalid OpenMetrics response format returned by FPM + status page. (Stefano Arlandini) - MBString: . Fixed bug GH-7902 (mb_send_mail may delimit headers with LF only). (cmb) @@ -48,10 +50,6 @@ PHP NEWS - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) -- FPM: - . Fixed bug GH-7842 (Invalid OpenMetrics response format returned by FPM - status page. (Stefano Arlandini) - - Hash: . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). (cmb) From d2ec5bec295540ce45c84704849459b929a74879 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 21 Jan 2022 17:42:41 +0100 Subject: [PATCH 097/227] Make gh7875.phpt more resilient Apparently, on Cirrus CI FreeBSD chmodding a file to 0444 doesn't make it readonly. So in this case, we skip the test. [1] --- ext/standard/tests/mail/gh7875.phpt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ext/standard/tests/mail/gh7875.phpt b/ext/standard/tests/mail/gh7875.phpt index f19fe5f3194f5..0947dcb3538f1 100644 --- a/ext/standard/tests/mail/gh7875.phpt +++ b/ext/standard/tests/mail/gh7875.phpt @@ -1,5 +1,16 @@ --TEST-- GH-7875 (mails are sent even if failure to log throws exception) +--SKIPIF-- + --INI-- sendmail_path={MAIL:{PWD}/gh7875.mail.out} mail.log={PWD}/gh7875.mail.log From 07aaa34cd418c44f7bc653fafbf49f07fc71b2bf Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 21 Jan 2022 13:39:30 +0000 Subject: [PATCH 098/227] Fix GH-7978: sockets extension compilation errors We fix the `ucred` detection when custom `CFLAGS` are in use. Closes GH-7981. --- NEWS | 1 + ext/sockets/config.m4 | 3 +++ 2 files changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 285d6265ee955..d32c3fb2f11e8 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ PHP NEWS - Sockets: . Fixed ext/sockets build on Haiku. (David Carlier) + . Fixed bug GH-7978 (sockets extension compilation errors). (David Carlier) - Standard: . Fixed bug GH-7875 (mails are sent even if failure to log throws exception). diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4 index d4f92082c3b2d..aafedcb99ddd3 100644 --- a/ext/sockets/config.m4 +++ b/ext/sockets/config.m4 @@ -67,6 +67,9 @@ if test "$PHP_SOCKETS" != "no"; then AC_CACHE_CHECK([if ancillary credentials uses ucred],[ac_cv_ucred], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include ]], [[struct ucred u = {.gid = 0};]])], [ac_cv_ucred=yes], [ac_cv_ucred=no]) From b27d2fffbc551cebc3696718028bd22ebbc93dde Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sat, 22 Jan 2022 12:34:50 -0500 Subject: [PATCH 099/227] Update php-parser to 4.13.2 in build/gen_stub.php (#7989) v4.13.2 fixes a deprecation notice in php 8.2 for namespacedName --- build/gen_stub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index b2213409b0b89..94eab3be1ef0d 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -3287,7 +3287,7 @@ function initPhpParser() { } $isInitialized = true; - $version = "4.13.0"; + $version = "4.13.2"; $phpParserDir = __DIR__ . "/PHP-Parser-$version"; if (!is_dir($phpParserDir)) { installPhpParser($version, $phpParserDir); From 464e725bb5a61e425e1e05015e0db8ca4bf2f3a9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Jan 2022 11:04:51 +0300 Subject: [PATCH 100/227] Fix typo (wrong string length) Fixes oss-fuzz #44110 --- Zend/zend_operators.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index acda841979eb5..423ed918da3f3 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1926,7 +1926,7 @@ ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend int ret; if (case_insensitive) { - ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)); + ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); } else { ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); } @@ -1972,7 +1972,7 @@ ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* zend_string *tmp_str1, *tmp_str2; zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); - int ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)); + int ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); zend_tmp_string_release(tmp_str1); zend_tmp_string_release(tmp_str2); From 965dafe3e15667daf0c5837dd92ee2ebcf4899ed Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Jan 2022 12:17:46 +0300 Subject: [PATCH 101/227] Fix too aggressive DCE that leads to memory leak Fixes oss-fuzz #43738 --- ext/opcache/Optimizer/sccp.c | 28 +++++++++++++++++++--------- ext/opcache/tests/opt/sccp_037.phpt | 13 +++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 ext/opcache/tests/opt/sccp_037.phpt diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 64cfa676965d4..8163929b3911f 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -2275,21 +2275,31 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, value); } return 0; - } else { - zend_ssa_remove_result_def(ssa, ssa_op); - if (opline->opcode == ZEND_DO_ICALL) { - removed_ops = remove_call(ctx, opline, ssa_op); - } else if (opline->opcode == ZEND_TYPE_CHECK - && (opline->op1_type & (IS_VAR|IS_TMP_VAR)) - && (!value_known(&ctx->values[ssa_op->op1_use]) - || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use]) - || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) { + } else if ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) + && (!value_known(&ctx->values[ssa_op->op2_use]) + || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op2_use]) + || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op2_use]))) { + return 0; + } else if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) + && (!value_known(&ctx->values[ssa_op->op1_use]) + || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use]) + || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) { + if (opline->opcode == ZEND_TYPE_CHECK + || opline->opcode == ZEND_BOOL) { + zend_ssa_remove_result_def(ssa, ssa_op); /* For TYPE_CHECK we may compute the result value without knowing the * operand, based on type inference information. Make sure the operand is * freed and leave further cleanup to DCE. */ opline->opcode = ZEND_FREE; opline->result_type = IS_UNUSED; removed_ops++; + } else { + return 0; + } + } else { + zend_ssa_remove_result_def(ssa, ssa_op); + if (opline->opcode == ZEND_DO_ICALL) { + removed_ops = remove_call(ctx, opline, ssa_op); } else { zend_ssa_remove_instr(ssa, opline, ssa_op); removed_ops++; diff --git a/ext/opcache/tests/opt/sccp_037.phpt b/ext/opcache/tests/opt/sccp_037.phpt new file mode 100644 index 0000000000000..130db36052b39 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_037.phpt @@ -0,0 +1,13 @@ +--TEST-- +SCCP 037: Memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECT-- +DONE From f1ae13509f23a639bd47b4035e6bf74c68cef752 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Jan 2022 12:38:38 +0300 Subject: [PATCH 102/227] Fix memory leak Fixes oss-fuzz #43988 --- Zend/tests/dynamic_prop_deprecation_002.phpt | 13 ++++++++++++ Zend/zend_object_handlers.c | 21 +++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 Zend/tests/dynamic_prop_deprecation_002.phpt diff --git a/Zend/tests/dynamic_prop_deprecation_002.phpt b/Zend/tests/dynamic_prop_deprecation_002.phpt new file mode 100644 index 0000000000000..2ab7452fedb67 --- /dev/null +++ b/Zend/tests/dynamic_prop_deprecation_002.phpt @@ -0,0 +1,13 @@ +--TEST-- +Dynamic properties deprecation 002 (memory leak) +--FILE-- +y]; +?> +--EXPECT-- +Err: Creation of dynamic property class@anonymous::$y is deprecated \ No newline at end of file diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index e75ff8318cb48..721abe46998b8 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -277,10 +277,16 @@ static ZEND_COLD zend_never_inline void zend_forbidden_dynamic_property( ZSTR_VAL(ce->name), ZSTR_VAL(member)); } -static ZEND_COLD zend_never_inline void zend_deprecated_dynamic_property( - zend_class_entry *ce, zend_string *member) { +static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property( + zend_object *obj, zend_string *member) { + GC_ADDREF(obj); zend_error(E_DEPRECATED, "Creation of dynamic property %s::$%s is deprecated", - ZSTR_VAL(ce->name), ZSTR_VAL(member)); + ZSTR_VAL(obj->ce->name), ZSTR_VAL(member)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + return 0; + } + return 1; } static ZEND_COLD zend_never_inline void zend_readonly_property_modification_scope_error( @@ -880,7 +886,10 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva goto exit; } if (UNEXPECTED(!(zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES))) { - zend_deprecated_dynamic_property(zobj->ce, name); + if (UNEXPECTED(!zend_deprecated_dynamic_property(zobj, name))) { + variable_ptr = &EG(error_zval); + goto exit; + } } Z_TRY_ADDREF_P(value); @@ -1063,7 +1072,9 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam return &EG(error_zval); } if (UNEXPECTED(!(zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES))) { - zend_deprecated_dynamic_property(zobj->ce, name); + if (UNEXPECTED(!zend_deprecated_dynamic_property(zobj, name))) { + return &EG(error_zval); + } } if (UNEXPECTED(!zobj->properties)) { rebuild_object_properties(zobj); From f711c9603db70ad7be8dace35b4297860a0f6e11 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Jan 2022 13:08:11 +0300 Subject: [PATCH 103/227] Fix incorrect register allocation Fixes oss-fuzz #44006 --- ext/opcache/jit/zend_jit.c | 8 ++++++-- ext/opcache/jit/zend_jit_trace.c | 8 ++++++-- ext/opcache/tests/jit/add_013.phpt | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/jit/add_013.phpt diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index fdffcbc1034c7..fa7953e20f3f2 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -1394,13 +1394,17 @@ static int zend_jit_compute_liveness(const zend_op_array *op_array, zend_ssa *ss if (ssa->ops[line].op1_use >= 0 && intervals[ssa->ops[line].op1_use] && ssa->ops[line].op1_use_chain < 0 && - !ssa->vars[ssa->ops[line].op1_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op1_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op1_use].type & MAY_BE_ANY)) { zend_jit_add_hint(intervals, i, ssa->ops[line].op1_use); } else if (opline->opcode != ZEND_SUB && ssa->ops[line].op2_use >= 0 && intervals[ssa->ops[line].op2_use] && ssa->ops[line].op2_use_chain < 0 && - !ssa->vars[ssa->ops[line].op2_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op2_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op2_use].type & MAY_BE_ANY)) { zend_jit_add_hint(intervals, i, ssa->ops[line].op2_use); } } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index b871304aea812..f4fe85f336740 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2945,7 +2945,9 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace if (ssa->ops[line].op1_use >= 0 && intervals[ssa->ops[line].op1_use] && ssa->ops[line].op1_use_chain < 0 && - !ssa->vars[ssa->ops[line].op1_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op1_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op1_use].type & MAY_BE_ANY)) { zend_ssa_phi *phi = ssa->vars[ssa->ops[line].op1_use].definition_phi; if (phi && @@ -2958,7 +2960,9 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace ssa->ops[line].op2_use >= 0 && intervals[ssa->ops[line].op2_use] && ssa->ops[line].op2_use_chain < 0 && - !ssa->vars[ssa->ops[line].op2_use].phi_use_chain) { + !ssa->vars[ssa->ops[line].op2_use].phi_use_chain && + (ssa->var_info[i].type & MAY_BE_ANY) == + (ssa->var_info[ssa->ops[line].op2_use].type & MAY_BE_ANY)) { zend_ssa_phi *phi = ssa->vars[ssa->ops[line].op2_use].definition_phi; if (phi && diff --git a/ext/opcache/tests/jit/add_013.phpt b/ext/opcache/tests/jit/add_013.phpt new file mode 100644 index 0000000000000..e2baa69566af3 --- /dev/null +++ b/ext/opcache/tests/jit/add_013.phpt @@ -0,0 +1,20 @@ +--TEST-- +JIT ADD: 013 register allocation (incorrect hinting) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + 4) break; + } +} +?> +DONE +--EXPECT-- +DONE \ No newline at end of file From 54c952f11fbc3e877ddb729b78e9814eb3f79157 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Jan 2022 16:27:55 +0300 Subject: [PATCH 104/227] JIT: Fix incorrect type store elimination Fixes oss-fuzz #43737 --- ext/opcache/jit/zend_jit_trace.c | 6 ++++-- ext/opcache/tests/jit/assign_050.phpt | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_050.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index f4fe85f336740..840a5610f924f 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4624,14 +4624,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par break; } op2_addr = OP2_REG_ADDR(); + op2_info = OP2_INFO(); if (ra && ssa_op->op2_def >= 0 - && !ssa->vars[ssa_op->op2_def].no_val) { + && (!ssa->vars[ssa_op->op2_def].no_val + || (zend_jit_trace_type_to_info(STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var))) & MAY_BE_ANY) != + (op2_info & MAY_BE_ANY))) { op2_def_addr = OP2_DEF_REG_ADDR(); } else { op2_def_addr = op2_addr; } - op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); op1_info = OP1_INFO(); if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG diff --git a/ext/opcache/tests/jit/assign_050.phpt b/ext/opcache/tests/jit/assign_050.phpt new file mode 100644 index 0000000000000..21fcf9ef794aa --- /dev/null +++ b/ext/opcache/tests/jit/assign_050.phpt @@ -0,0 +1,23 @@ +--TEST-- +JIT ASSIGN: incorrect type store elimination +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +DONE +--EXPECT-- +DONE From 22688c7822f46a39e2f59c0dbc09c72d57cfc5bf Mon Sep 17 00:00:00 2001 From: "Su, Tao" Date: Sat, 29 Jan 2022 00:12:32 -0800 Subject: [PATCH 105/227] [ci skip] [Zend] Update README.md with new Zend VM executors Closes GH-8008 As a new learner to PHP Zend VM, the first place I can find information is this README.md. Unfortunately, it has not included the latest Zend VM kind and code generation script. With code reading and trail-and-error experiments, I found a few updates that might be helpful to new learners. ChangeLog: 1) Add HYBRID threading model 2) Remove --without-old-executor option and description 3) ZE2 --> ZE3 (Since PHP 7) 4) Change default VM kind from CALL to HYBRID Signed-off-by: Su, Tao --- Zend/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Zend/README.md b/Zend/README.md index cf1f15463d2f9..d164da4736e94 100644 --- a/Zend/README.md +++ b/Zend/README.md @@ -119,21 +119,21 @@ ZEND_VM_HELPER_EX(, , , ) } ``` -Executor's code is generated by PHP script zend_vm_gen.php it uses +The executors code is generated by the PHP script `zend_vm_gen.php`. It uses `zend_vm_def.h` and `zend_vm_execute.skl` as input and produces `zend_vm_opcodes.h` and `zend_vm_execute.h`. The first file is a list of opcode definitions. It is included from `zend_compile.h`. The second one is an executor code itself. It is included from `zend_execute.c`. -`zend_vm_gen.php` can produce different kind of executors. You can select -different opcode threading model using `--with-vm-kind=CALL|SWITCH|GOTO`. You -can disable opcode specialization using `--without-specializer`. You can include -or exclude old executor together with specialized one using -`--without-old-executor`. At last you can debug executor using original -`zend_vm_def.h` or generated file `zend_vm_execute.h`. Debugging with original -file requires `--with-lines` option. By default ZE2 uses the following command -to generate executor: +`zend_vm_gen.php` can produce different kind of executors. You can select a +different opcode threading model using `--with-vm-kind=CALL|SWITCH|GOTO|HYBRID`. +You can disable opcode specialization using `--without-specializer`. +At last you can debug the executor using the original `zend_vm_def.h` or the +generated `zend_vm_execute.h` file. Debugging with the original file requires +the `--with-lines` option. By default ZE3 (since PHP 7) uses the following +command to generate the executor: ```bash -php zend_vm_gen.php --with-vm-kind=CALL +# Default VM kind is HYBRID +php zend_vm_gen.php --with-vm-kind=HYBRID ``` From 70f712ce04920f27f4bbba7f716d3439f31096ce Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 25 Jan 2022 18:12:30 +0100 Subject: [PATCH 106/227] [ci skip] Close stale PRs with GitHub actions Closes GH-7999 --- .github/workflows/close-stale-prs.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/close-stale-prs.yml diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml new file mode 100644 index 0000000000000..d4a88c209aa21 --- /dev/null +++ b/.github/workflows/close-stale-prs.yml @@ -0,0 +1,20 @@ +name: Close stale PRs + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v4 + with: + days-before-close: 7 + days-before-stale: 60 + # Temporary, avoid closing PRs until this action merged + debug-only: true + # Hack to skip issues, unfortunately there's no option to disable issues + only-issue-labels: inexistent-label + only-pr-labels: Waiting on Author + stale-pr-message: There has not been any recent activity in this PR. It will automatically be closed in 7 days if no further action is taken. From 2f5295692fde289f99aa9701528dcde4c78b780f Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 29 Dec 2021 12:51:18 +0100 Subject: [PATCH 107/227] Optimize stripos/stristr Closes GH-7847 Closes GH-7852 Previously stripos/stristr would lowercase both the haystack and the needle to reuse strpos. The approach in this PR is similar to strpos. memchr is highly optimized so we're using it to search for the first character of the needle in the haystack. If we find it we compare the remaining characters of the needle manually. The new implementation seems to perform about half as well as strpos (as two memchr calls are necessary to find the next candidate). --- NEWS | 2 ++ UPGRADING.INTERNALS | 3 +++ Zend/zend_operators.h | 61 +++++++++++++++++++++++++++++++++++++++++++ ext/libxml/libxml.c | 5 ++-- ext/phar/phar.c | 7 +---- ext/phar/tar.c | 8 ++---- ext/phar/zip.c | 7 +---- ext/standard/string.c | 31 +++++----------------- main/php.h | 1 + 9 files changed, 79 insertions(+), 46 deletions(-) diff --git a/NEWS b/NEWS index 0a53434c36a9f..09da40c962e28 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ PHP NEWS . net_get_interfaces() also reports wireless network interfaces on Windows. (Yurun) . Finished AVIF support in getimagesize(). (Yannis Guyon) + . Fixed bug GH-7847 (stripos with large haystack has bad performance). + (ilutov) - Zip: . add ZipArchive::clearError() method diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 7175f0b54b4db..cec9356406556 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -17,6 +17,9 @@ PHP 8.2 INTERNALS UPGRADE NOTES zend_binary_str(n)casecmp() as one would expect. Call the appropriate wrapped function directly instead. * Removed the (ZEND_)WRONG_PARAM_COUNT_WITH_RETVAL() macros. +* php_stristr() no longer lowercases the haystack and needle as a side effect. + Call zend_str_tolower() yourself if necessary. You no longer need to copy + the haystack and needle before passing them to php_stristr(). ======================== 2. Build system changes diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index eb88eedb79da1..265b84409009a 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -919,6 +919,67 @@ static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */ } /* }}} */ +static zend_always_inline bool zend_strnieq(const char *ptr1, const char *ptr2, size_t num) +{ + const char *end = ptr1 + num; + while (ptr1 < end) { + if (zend_tolower_ascii(*ptr1++) != zend_tolower_ascii(*ptr2++)) { + return 0; + } + } + return 1; +} + +static zend_always_inline const char * +zend_memnistr(const char *haystack, const char *needle, size_t needle_len, const char *end) +{ + ZEND_ASSERT(end >= haystack); + + if (UNEXPECTED(needle_len == 0)) { + return haystack; + } + + if (UNEXPECTED(needle_len > (end - haystack))) { + return NULL; + } + + const char first_lower = zend_tolower_ascii(*needle); + const char first_upper = zend_toupper_ascii(*needle); + const char *p_lower = (const char *)memchr(haystack, first_lower, end - haystack); + const char *p_upper = NULL; + if (first_lower != first_upper) { + // If the needle length is 1 we don't need to look beyond p_lower as it is a guaranteed match + size_t upper_search_length = end - (needle_len == 1 && p_lower != NULL ? p_lower : haystack); + p_upper = (const char *)memchr(haystack, first_upper, upper_search_length); + } + const char *p = !p_upper || (p_lower && p_lower < p_upper) ? p_lower : p_upper; + + if (needle_len == 1) { + return p; + } + + const char needle_end_lower = zend_tolower_ascii(needle[needle_len - 1]); + const char needle_end_upper = zend_toupper_ascii(needle[needle_len - 1]); + end -= needle_len; + + while (p && p <= end) { + if (needle_end_lower == p[needle_len - 1] || needle_end_upper == p[needle_len - 1]) { + if (zend_strnieq(needle + 1, p + 1, needle_len - 2)) { + return p; + } + } + if (p_lower == p) { + p_lower = (const char *)memchr(p_lower + 1, first_lower, end - p_lower); + } + if (p_upper == p) { + p_upper = (const char *)memchr(p_upper + 1, first_upper, end - p_upper); + } + p = !p_upper || (p_lower && p_lower < p_upper) ? p_lower : p_upper; + } + + return NULL; +} + END_EXTERN_C() diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 449bf3248313e..99d5696ebcf31 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -378,9 +378,9 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) const char buf[] = "Content-Type:"; if (Z_TYPE_P(header) == IS_STRING && !zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) { - char *needle = estrdup("charset="); + char needle[] = "charset="; char *haystack = estrndup(Z_STRVAL_P(header), Z_STRLEN_P(header)); - char *encoding = php_stristr(haystack, needle, Z_STRLEN_P(header), sizeof("charset=")-1); + char *encoding = php_stristr(haystack, needle, Z_STRLEN_P(header), strlen(needle)); if (encoding) { char *end; @@ -408,7 +408,6 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) } } efree(haystack); - efree(needle); break; /* found content-type */ } } ZEND_HASH_FOREACH_END(); diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 91310c21e4967..6d5790e3089c4 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2531,7 +2531,6 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv { char halt_stub[] = "__HALT_COMPILER();"; zend_string *newstub; - char *tmp; phar_entry_info *entry, *newentry; size_t halt_offset; int restore_alias_len, global_flags = 0, closeoldfile; @@ -2635,9 +2634,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv } else { free_user_stub = 0; } - tmp = estrndup(user_stub, len); - if ((pos = php_stristr(tmp, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { - efree(tmp); + if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { if (closeoldfile) { php_stream_close(oldfile); } @@ -2650,8 +2647,6 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv } return EOF; } - pos = user_stub + (pos - tmp); - efree(tmp); len = pos - user_stub + 18; if ((size_t)len != php_stream_write(newfile, user_stub, len) || 5 != php_stream_write(newfile, " ?>\r\n", 5)) { diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 07b784a0b9df2..3b2e4c2ca76aa 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -967,7 +967,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int int closeoldfile, free_user_stub; size_t signature_length; struct _phar_pass_tar_info pass; - char *buf, *signature, *tmp, sigbuf[8]; + char *buf, *signature, sigbuf[8]; char halt_stub[] = "__HALT_COMPILER();"; entry.flags = PHAR_ENT_PERM_DEF_FILE; @@ -1063,9 +1063,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int free_user_stub = 0; } - tmp = estrndup(user_stub, len); - if ((pos = php_stristr(tmp, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { - efree(tmp); + if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) { if (error) { spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", phar->fname); } @@ -1074,8 +1072,6 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int } return EOF; } - pos = user_stub + (pos - tmp); - efree(tmp); len = pos - user_stub + 18; entry.fp = php_stream_fopen_tmpfile(); diff --git a/ext/phar/zip.c b/ext/phar/zip.c index c5e38cabf7b87..bfa23e9768b32 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -1202,7 +1202,6 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int char *pos; static const char newstub[] = "fname); } @@ -1316,8 +1313,6 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int } return EOF; } - pos = user_stub + (pos - tmp); - efree(tmp); len = pos - user_stub + 18; entry.fp = php_stream_fopen_tmpfile(); diff --git a/ext/standard/string.c b/ext/standard/string.c index 7c2dce4595b0f..36e8c1a737e77 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1687,9 +1687,7 @@ PHP_FUNCTION(pathinfo) case insensitive strstr */ PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len) { - zend_str_tolower(s, s_len); - zend_str_tolower(t, t_len); - return (char*)php_memnstr(s, t, t_len, s + s_len); + return (char*)php_memnistr(s, t, t_len, s + s_len); } /* }}} */ @@ -1735,8 +1733,6 @@ PHP_FUNCTION(stristr) zend_string *haystack, *needle; const char *found = NULL; size_t found_offset; - char *haystack_dup; - char *orig_needle; bool part = 0; ZEND_PARSE_PARAMETERS_START(2, 3) @@ -1746,13 +1742,10 @@ PHP_FUNCTION(stristr) Z_PARAM_BOOL(part) ZEND_PARSE_PARAMETERS_END(); - haystack_dup = estrndup(ZSTR_VAL(haystack), ZSTR_LEN(haystack)); - orig_needle = estrndup(ZSTR_VAL(needle), ZSTR_LEN(needle)); - found = php_stristr(haystack_dup, orig_needle, ZSTR_LEN(haystack), ZSTR_LEN(needle)); - efree(orig_needle); + found = php_stristr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(haystack), ZSTR_LEN(needle)); if (found) { - found_offset = found - haystack_dup; + found_offset = found - ZSTR_VAL(haystack); if (part) { RETVAL_STRINGL(ZSTR_VAL(haystack), found_offset); } else { @@ -1761,8 +1754,6 @@ PHP_FUNCTION(stristr) } else { RETVAL_FALSE; } - - efree(haystack_dup); } /* }}} */ @@ -1890,7 +1881,6 @@ PHP_FUNCTION(stripos) const char *found = NULL; zend_string *haystack, *needle; zend_long offset = 0; - zend_string *needle_dup = NULL, *haystack_dup; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(haystack) @@ -1907,23 +1897,14 @@ PHP_FUNCTION(stripos) RETURN_THROWS(); } - if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) { - RETURN_FALSE; - } - - haystack_dup = zend_string_tolower(haystack); - needle_dup = zend_string_tolower(needle); - found = (char*)php_memnstr(ZSTR_VAL(haystack_dup) + offset, - ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack)); + found = (char*)php_memnistr(ZSTR_VAL(haystack) + offset, + ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack)); if (found) { - RETVAL_LONG(found - ZSTR_VAL(haystack_dup)); + RETVAL_LONG(found - ZSTR_VAL(haystack)); } else { RETVAL_FALSE; } - - zend_string_release_ex(haystack_dup, 0); - zend_string_release_ex(needle_dup, 0); } /* }}} */ diff --git a/main/php.h b/main/php.h index 91ecbb21dc726..e8fcea5b6f607 100644 --- a/main/php.h +++ b/main/php.h @@ -344,6 +344,7 @@ END_EXTERN_C() #define phpin zendin #define php_memnstr zend_memnstr +#define php_memnistr zend_memnistr /* functions */ BEGIN_EXTERN_C() From a60a9b4a89b4fa40f8980a0a35a7088860cb8a4d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Feb 2022 16:24:22 +0300 Subject: [PATCH 108/227] Fix memory leak Fixes oss-fuzz #44222 --- Zend/tests/nullsafe_operator/040.phpt | 19 +++ Zend/zend_vm_def.h | 53 +++--- Zend/zend_vm_execute.h | 232 ++++++++++++++++++-------- Zend/zend_vm_handlers.h | 6 +- Zend/zend_vm_opcodes.c | 2 +- 5 files changed, 217 insertions(+), 95 deletions(-) create mode 100644 Zend/tests/nullsafe_operator/040.phpt diff --git a/Zend/tests/nullsafe_operator/040.phpt b/Zend/tests/nullsafe_operator/040.phpt new file mode 100644 index 0000000000000..1bfdaf753df85 --- /dev/null +++ b/Zend/tests/nullsafe_operator/040.phpt @@ -0,0 +1,19 @@ +--TEST-- +Memory leak in JMP_NULL +--FILE-- +null); +} + +$foo2 = &returns_ref2(); +$foo2 = 'foo'; +var_dump($foo); +?> +--EXPECT-- +string(3) "foo" diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index fca5af71da717..e0687a23fd082 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7422,39 +7422,44 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMPVARCV, JMP_ADDR) +ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE - zval *val; + zval *val, *result; val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - if (OP1_TYPE != IS_CONST) { - ZVAL_DEREF(val); - } - - if (Z_TYPE_INFO_P(val) > IS_NULL) { - ZEND_VM_NEXT_OPCODE(); - } else { - zval *result = EX_VAR(opline->result.var); - if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + FREE_OP1(); + break; } } - } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } ZEND_VM_HOT_HANDLER(31, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index f569ff6ba8ff9..922ed92e560f2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5084,36 +5084,41 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; + zval *val, *result; val = RT_CONSTANT(opline, opline->op1); - if (IS_CONST != IS_CONST) { - ZVAL_DEREF(val); - } - if (Z_TYPE_INFO_P(val) > IS_NULL) { - ZEND_VM_NEXT_OPCODE(); - } else { - zval *result = EX_VAR(opline->result.var); + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { - if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + break; } } - } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -11855,41 +11860,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR ZEND_VM_TAIL_CALL(zend_bw_not_helper_SPEC(op1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - - val = EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST) { - ZVAL_DEREF(val); - } - - if (Z_TYPE_INFO_P(val) > IS_NULL) { - ZEND_VM_NEXT_OPCODE(); - } else { - zval *result = EX_VAR(opline->result.var); - - if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } - - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } -} - static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -19137,6 +19107,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND ZEND_VM_NEXT_OPCODE(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val, *result; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22034,6 +22044,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND ZEND_VM_NEXT_OPCODE(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val, *result; + + val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -38421,6 +38471,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_ ZEND_VM_NEXT_OPCODE(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val, *result; + + val = EX_VAR(opline->op1.var); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -53574,10 +53664,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL, (void*)&&ZEND_JMP_NULL_SPEC_CONST_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, + (void*)&&ZEND_JMP_NULL_SPEC_TMP_LABEL, + (void*)&&ZEND_JMP_NULL_SPEC_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, + (void*)&&ZEND_JMP_NULL_SPEC_CV_LABEL, (void*)&&ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_JMP_FORWARD_SPEC_LABEL, @@ -55732,10 +55822,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_BW_NOT_SPEC_TMPVARCV) ZEND_BW_NOT_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMP_NULL_SPEC_TMPVARCV): - VM_TRACE(ZEND_JMP_NULL_SPEC_TMPVARCV) - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV): VM_TRACE(ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56637,6 +56723,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_COALESCE_SPEC_TMP) ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMP_NULL_SPEC_TMP): + VM_TRACE(ZEND_JMP_NULL_SPEC_TMP) + ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_TMP): VM_TRACE(ZEND_QM_ASSIGN_SPEC_TMP) ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56942,6 +57032,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_COALESCE_SPEC_VAR) ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMP_NULL_SPEC_VAR): + VM_TRACE(ZEND_JMP_NULL_SPEC_VAR) + ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_VAR): VM_TRACE(ZEND_QM_ASSIGN_SPEC_VAR) ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -58067,6 +58161,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_COALESCE_SPEC_CV) ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMP_NULL_SPEC_CV): + VM_TRACE(ZEND_JMP_NULL_SPEC_CV) + ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_CV): VM_TRACE(ZEND_QM_ASSIGN_SPEC_CV) ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -61597,10 +61695,10 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER, ZEND_JMP_NULL_SPEC_CONST_HANDLER, - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, + ZEND_JMP_NULL_SPEC_TMP_HANDLER, + ZEND_JMP_NULL_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, + ZEND_JMP_NULL_SPEC_CV_HANDLER, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_JMP_FORWARD_SPEC_HANDLER, diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index a2e85dde9b16b..ceab588d10503 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1348,9 +1348,9 @@ _(2538, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ _(2540, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ _(2541, ZEND_JMP_NULL_SPEC_CONST) \ - _(2542, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2543, ZEND_JMP_NULL_SPEC_TMPVARCV) \ - _(2545, ZEND_JMP_NULL_SPEC_TMPVARCV) \ + _(2542, ZEND_JMP_NULL_SPEC_TMP) \ + _(2543, ZEND_JMP_NULL_SPEC_VAR) \ + _(2545, ZEND_JMP_NULL_SPEC_CV) \ _(2546, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ _(2547, ZEND_RECV_NOTYPE_SPEC) \ _(2548, ZEND_JMP_FORWARD_SPEC) \ diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 56a31aa19a095..0afcc8ecc8b5e 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -424,7 +424,7 @@ static uint32_t zend_vm_opcodes_flags[200] = { 0x0300030b, 0x00000301, 0x0000010b, - 0x0000200b, + 0x00002003, 0x00000101, }; From 718478377b886c0630ea5b291679a24409b1ea8e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Feb 2022 17:22:18 +0300 Subject: [PATCH 109/227] Prevent array modification if it's captured by user error handler during index conversion Fixes oss-fuzz #44235 --- Zend/tests/array_offset_002.phpt | 18 ++++++ Zend/zend_execute.c | 93 ++++++++++++++++++++++++++++-- ext/opcache/jit/zend_jit_helpers.c | 30 ++++++---- 3 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 Zend/tests/array_offset_002.phpt diff --git a/Zend/tests/array_offset_002.phpt b/Zend/tests/array_offset_002.phpt new file mode 100644 index 0000000000000..ad684c3b6e486 --- /dev/null +++ b/Zend/tests/array_offset_002.phpt @@ -0,0 +1,18 @@ +--TEST-- +Capturing array in user error handler during index conversion +--FILE-- + +--EXPECT-- +Err: Implicit conversion from float 1.0E+20 to int loses precision +array(0) { +} diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a245db9835379..ccd10d85c4f95 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2147,8 +2147,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht GC_ADDREF(ht); } zend_undefined_offset(lval); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } return NULL; } if (EG(exception)) { @@ -2169,8 +2171,10 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, /* Key may be released while throwing the undefined index warning. */ zend_string_addref(offset); zend_undefined_index(offset); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } retval = NULL; } else if (EG(exception)) { retval = NULL; @@ -2319,6 +2323,80 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval } } +static zend_never_inline zend_uchar slow_index_convert_w(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC) +{ + switch (Z_TYPE_P(dim)) { + case IS_UNDEF: { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + ZVAL_UNDEFINED_OP2(); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } + ZEND_FALLTHROUGH; + } + case IS_NULL: + value->str = ZSTR_EMPTY_ALLOC(); + return IS_STRING; + case IS_DOUBLE: + value->lval = zend_dval_to_lval(Z_DVAL_P(dim)); + if (!zend_is_long_compatible(Z_DVAL_P(dim), value->lval)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } + } + return IS_LONG; + case IS_RESOURCE: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + zend_use_resource_as_offset(dim); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } + value->lval = Z_RES_HANDLE_P(dim); + return IS_LONG; + case IS_FALSE: + value->lval = 0; + return IS_LONG; + case IS_TRUE: + value->lval = 1; + return IS_LONG; + default: + zend_illegal_offset(); + return IS_NULL; + } +} + static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type EXECUTE_DATA_DC) { zval *retval = NULL; @@ -2380,8 +2458,13 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht goto try_again; } else { zend_value val; - zend_uchar t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC); + zend_uchar t; + if (type != BP_VAR_W && type != BP_VAR_RW) { + t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC); + } else { + t = slow_index_convert_w(ht, dim, &val EXECUTE_DATA_CC); + } if (t == IS_STRING) { offset_key = val.str; goto str_index; diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index a36cccb40145c..5a9251d8650f2 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -365,8 +365,10 @@ static int ZEND_FASTCALL zend_jit_undefined_op_helper_write(HashTable *ht, uint3 GC_ADDREF(ht); } zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(cv)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } return 0; } return EG(exception) == NULL; @@ -808,8 +810,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di execute_data = EG(current_execute_data); opline = EX(opline); zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -836,8 +840,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di execute_data = EG(current_execute_data); opline = EX(opline); zend_use_resource_as_offset(dim); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -933,8 +939,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim execute_data = EG(current_execute_data); opline = EX(opline); zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -961,8 +969,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim execute_data = EG(current_execute_data); opline = EX(opline); zend_use_resource_as_offset(dim); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); From 478448d27161ce6fb23ee4fb92add46bd93482f0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Feb 2022 22:00:39 +0300 Subject: [PATCH 110/227] JIT: Fix register alloction (missed store) Fixes oss-fuzz #44242 --- ext/opcache/jit/zend_jit_trace.c | 7 +++---- ext/opcache/jit/zend_jit_x86.dasc | 12 +++++++++++ ext/opcache/tests/jit/reg_alloc_007.phpt | 26 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/jit/reg_alloc_007.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 840a5610f924f..8d75d04d47a2e 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3826,7 +3826,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ssa->var_info[i].type &= ~MAY_BE_GUARD; op_type = concrete_type(ssa->var_info[i].type); - if (!zend_jit_type_guard(&dasm_state, opline, i, op_type)) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), op_type)) { goto jit_failure; } SET_STACK_TYPE(stack, i, op_type, 1); @@ -3859,7 +3859,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ZEND_ASSERT(ival->reg != ZREG_NONE); if (info & MAY_BE_GUARD) { - if (!zend_jit_type_guard(&dasm_state, opline, phi->var, concrete_type(info))) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(phi->var), concrete_type(info))) { goto jit_failure; } info &= ~MAY_BE_GUARD; @@ -5986,8 +5986,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par || opline->opcode == ZEND_COALESCE || opline->opcode == ZEND_JMP_NULL || opline->opcode == ZEND_FE_RESET_R) { - if (!ra[ssa_op->op1_use] - || ra[ssa_op->op1_use]->reg != ra[ssa_op->op1_def]->reg) { + if (!ra[ssa_op->op1_use]) { flags |= ZREG_LOAD; } } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index e9068c39e5e4a..e15047ef5d36a 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3922,6 +3922,18 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + if (!Z_LOAD(src) && !Z_STORE(src) && Z_STORE(dst)) { + zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + + if (!zend_jit_spill_store(Dst, dst, var_addr, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } + } } else if (Z_MODE(dst) == IS_MEM_ZVAL) { if (!Z_LOAD(src) && !Z_STORE(src)) { if (!zend_jit_spill_store(Dst, src, dst, info, diff --git a/ext/opcache/tests/jit/reg_alloc_007.phpt b/ext/opcache/tests/jit/reg_alloc_007.phpt new file mode 100644 index 0000000000000..dab019f01cae6 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_007.phpt @@ -0,0 +1,26 @@ +--TEST-- +Register Alloction 007: Missing store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $a in %sreg_alloc_007.php on line 4 + +Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %sreg_alloc_007.php:6 +Stack trace: +#0 %sreg_alloc_007.php(9): test() +#1 {main} + thrown in %sreg_alloc_007.php on line 6 From 8a46311dbdacd9972c269cb9fccb42afd1eecfeb Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Wed, 2 Feb 2022 23:44:02 +0000 Subject: [PATCH 111/227] Bump for 8.0.17-dev --- NEWS | 5 ++++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index d32c3fb2f11e8..3d6d992ae1b16 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 2022, PHP 8.0.16 +?? ??? 2022, PHP 8.0.17 + + +17 Feb 2022, PHP 8.0.16 - Core: . Fixed bug #81430 (Attribute instantiation leaves dangling pointer). diff --git a/Zend/zend.h b/Zend/zend.h index 862d708727055..b1222625d552f 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.0.15-dev" +#define ZEND_VERSION "4.0.17-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 3e5ebce3126be..8f83ad06c07f6 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.0.15-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.0.17-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index cc8245315270f..d01736081da01 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 0 -#define PHP_RELEASE_VERSION 15 +#define PHP_RELEASE_VERSION 17 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.0.15-dev" -#define PHP_VERSION_ID 80015 +#define PHP_VERSION "8.0.17-dev" +#define PHP_VERSION_ID 80017 From 8db7fd8a2ac0bb406863d1ca9415f7236aa2f210 Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Thu, 3 Feb 2022 02:21:29 +0100 Subject: [PATCH 112/227] Bump for 8.1.4-dev --- NEWS | 4 +++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 5fe565cb881f3..c6d1a7c277307 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.3 +?? ??? ????, PHP 8.1.4 + +03 Feb 2022, PHP 8.1.3 - Core: . Fixed bug #81430 (Attribute instantiation leaves dangling pointer). diff --git a/Zend/zend.h b/Zend/zend.h index 071901d4c5725..67afd49421fd9 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.3-dev" +#define ZEND_VERSION "4.1.4-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 4c111b8a9b3dd..57e01def67e0e 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.3-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.4-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index e0e76bd6aaca1..fd5b1b0854a9b 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 -#define PHP_RELEASE_VERSION 3 +#define PHP_RELEASE_VERSION 4 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.3-dev" -#define PHP_VERSION_ID 80103 +#define PHP_VERSION "8.1.4-dev" +#define PHP_VERSION_ID 80104 From 8c7521d3ae957b53304b7fb7b2054417cc2e8a32 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 3 Feb 2022 10:42:30 +0100 Subject: [PATCH 113/227] [Close stale PRs] Skip RFCs and "Waiting on Review" Pull requests with the "Waiting on Author" label should still not be closed if they have the RFC label as closing them requires manual action. Also avoid closing "Waiting on Review". --- .github/workflows/close-stale-prs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index d4a88c209aa21..e5e8abdd9d625 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -12,6 +12,7 @@ jobs: with: days-before-close: 7 days-before-stale: 60 + exempt-pr-labels: RFC,Waiting on Review # Temporary, avoid closing PRs until this action merged debug-only: true # Hack to skip issues, unfortunately there's no option to disable issues From 9bd468da6341d38f9b006b5ca407f79bb5d91393 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 20 Jan 2022 16:55:57 +0100 Subject: [PATCH 114/227] Fix GH-7953: ob_clean() only does not set Content-Encoding If an output handler has not yet been started, calling `ob_clean()` causes it to start. If that happens, we must not forget to set the `Content-Encoding` and `Vary` headers. Closes GH-7960. --- NEWS | 5 +++++ ext/iconv/iconv.c | 2 +- ext/iconv/tests/gh7953.phpt | 21 +++++++++++++++++++++ ext/zlib/tests/gh7953.phpt | 21 +++++++++++++++++++++ ext/zlib/zlib.c | 2 +- 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 ext/iconv/tests/gh7953.phpt create mode 100644 ext/zlib/tests/gh7953.phpt diff --git a/NEWS b/NEWS index 3d6d992ae1b16..3b25cf62d3f27 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.17 +- Iconv: + . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) + +- Zlib: + . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) 17 Feb 2022, PHP 8.0.16 diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 90c209cbcbf00..d0693c08f2062 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -311,7 +311,7 @@ static int php_iconv_output_handler(void **nothing, php_output_context *output_c mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE; } - if (mimetype != NULL && !(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) { + if (mimetype != NULL && (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN) || (output_context->op & PHP_OUTPUT_HANDLER_START))) { size_t len; char *p = strstr(get_output_encoding(), "//"); diff --git a/ext/iconv/tests/gh7953.phpt b/ext/iconv/tests/gh7953.phpt new file mode 100644 index 0000000000000..bfc249fb9f21e --- /dev/null +++ b/ext/iconv/tests/gh7953.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-7953 (ob_clean() only may not set Content-* header) +--SKIPIF-- + +--INI-- +input_encoding=UTF-8 +output_encoding=ISO-8859-1 +--CGI-- +--FILE-- + +--EXPECTF-- +%a +--EXPECTHEADERS-- +Content-Type: text/html; charset=ISO-8859-1 diff --git a/ext/zlib/tests/gh7953.phpt b/ext/zlib/tests/gh7953.phpt new file mode 100644 index 0000000000000..d5d9011c03281 --- /dev/null +++ b/ext/zlib/tests/gh7953.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-7953 (ob_clean() only may not set Content-* header) +--SKIPIF-- + +--CGI-- +--ENV-- +HTTP_ACCEPT_ENCODING=gzip +--FILE-- + +--EXPECTF-- +%a +--EXPECTHEADERS-- +Content-Encoding: gzip +Vary: Accept-Encoding diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 75bd273526eb6..f7cf0d5dac76a 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -281,7 +281,7 @@ static int php_zlib_output_handler(void **handler_context, php_output_context *o return FAILURE; } - if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) { + if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN) || (output_context->op & PHP_OUTPUT_HANDLER_START)) { int flags; if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags)) { From 706398fa9fb081c6385c66ac8af1fe952c80f17d Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 4 Feb 2022 18:39:05 +0100 Subject: [PATCH 115/227] [ci skip] [Close stale PRs] Enable GitHub action --- .github/workflows/close-stale-prs.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index e5e8abdd9d625..5aa178eed2c2c 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -13,8 +13,6 @@ jobs: days-before-close: 7 days-before-stale: 60 exempt-pr-labels: RFC,Waiting on Review - # Temporary, avoid closing PRs until this action merged - debug-only: true # Hack to skip issues, unfortunately there's no option to disable issues only-issue-labels: inexistent-label only-pr-labels: Waiting on Author From 0199b222583855f2b42b9b15d545bc4b8b8d87f0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 5 Feb 2022 20:13:32 +0100 Subject: [PATCH 116/227] ext/opcache: check mkstemp() return value right after the call (#8031) Don't call fchmod(-1), which is not only wrong, but also clobbers errno and sets it to EBADF, breaking the following errno access for the log message. --- ext/opcache/zend_shared_alloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 53c7b61ff3f36..ad6b69b34613e 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -83,11 +83,12 @@ void zend_shared_alloc_create_lock(char *lockfile_path) snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX); lock_file = mkstemp(lockfile_name); - fchmod(lock_file, 0666); - if (lock_file == -1) { zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Unable to create lock file: %s (%d)", strerror(errno), errno); } + + fchmod(lock_file, 0666); + val = fcntl(lock_file, F_GETFD, 0); val |= FD_CLOEXEC; fcntl(lock_file, F_SETFD, val); From 7b90ebeb3f954123915f6d62fb7b2cd3fdf3c6ec Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sat, 5 Feb 2022 14:18:37 -0500 Subject: [PATCH 117/227] Fix `-Werror=sign-compare` warning in `zend_memnistr` (#8042) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `error: comparison of integer expressions of different signedness: ‘size_t’ {aka ‘long unsigned int’} and ‘long int’ [-Werror=sign-compare]` This is asserting `end >= haystack` as a precondition for callers (in debug builds) and existing callers are correct. An alternate option is to cast the left side to `int64_t`, but that may be slightly inefficient for 32-bit builds. --- Zend/zend_operators.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 265b84409009a..346706d22beae 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -939,7 +939,7 @@ zend_memnistr(const char *haystack, const char *needle, size_t needle_len, const return haystack; } - if (UNEXPECTED(needle_len > (end - haystack))) { + if (UNEXPECTED(needle_len > (size_t)(end - haystack))) { return NULL; } @@ -947,7 +947,7 @@ zend_memnistr(const char *haystack, const char *needle, size_t needle_len, const const char first_upper = zend_toupper_ascii(*needle); const char *p_lower = (const char *)memchr(haystack, first_lower, end - haystack); const char *p_upper = NULL; - if (first_lower != first_upper) { + if (first_lower != first_upper) { // If the needle length is 1 we don't need to look beyond p_lower as it is a guaranteed match size_t upper_search_length = end - (needle_len == 1 && p_lower != NULL ? p_lower : haystack); p_upper = (const char *)memchr(haystack, first_upper, upper_search_length); From ca0afc3c8e16952e1d3f553de7271762d52e2761 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Feb 2022 12:48:44 +0300 Subject: [PATCH 118/227] Improve speed of dominators and loop identification algorithms --- Zend/Optimizer/zend_cfg.c | 83 +++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index 8b83ccad67726..cc946c1b9ef3a 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -672,6 +672,11 @@ ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, ze int blocks_count = cfg->blocks_count; int j, k, changed; + if (cfg->blocks_count == 1) { + blocks[0].level = 0; + return; + } + ALLOCA_FLAG(use_heap) int *postnum = do_alloca(sizeof(int) * cfg->blocks_count, use_heap); memset(postnum, -1, sizeof(int) * cfg->blocks_count); @@ -692,16 +697,14 @@ ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, ze for (k = 0; k < blocks[j].predecessors_count; k++) { int pred = cfg->predecessors[blocks[j].predecessor_offset + k]; - if (idom < 0) { - if (blocks[pred].idom >= 0) - idom = pred; - continue; - } - if (blocks[pred].idom >= 0) { - while (idom != pred) { - while (postnum[pred] < postnum[idom]) pred = blocks[pred].idom; - while (postnum[idom] < postnum[pred]) idom = blocks[idom].idom; + if (idom < 0) { + idom = pred; + } else { + while (idom != pred) { + while (postnum[pred] < postnum[idom]) pred = blocks[pred].idom; + while (postnum[idom] < postnum[pred]) idom = blocks[idom].idom; + } } } } @@ -765,19 +768,6 @@ static bool dominates(zend_basic_block *blocks, int a, int b) /* {{{ */ } /* }}} */ -typedef struct { - int id; - int level; -} block_info; -static int compare_block_level(const block_info *a, const block_info *b) { - return b->level - a->level; -} -static void swap_blocks(block_info *a, block_info *b) { - block_info tmp = *a; - *a = *b; - *b = tmp; -} - ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { int i, j, k, n; @@ -786,17 +776,22 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c int *entry_times, *exit_times; zend_worklist work; int flag = ZEND_FUNC_NO_LOOPS; - block_info *sorted_blocks; + int *sorted_blocks; ALLOCA_FLAG(list_use_heap) ALLOCA_FLAG(tree_use_heap) - ALLOCA_FLAG(sorted_blocks_use_heap) + + if (cfg->blocks_count == 1) { + cfg->flags |= flag; + return; + } ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap); /* We don't materialize the DJ spanning tree explicitly, as we are only interested in ancestor * queries. These are implemented by checking entry/exit times of the DFS search. */ - entry_times = do_alloca(2 * sizeof(int) * cfg->blocks_count, tree_use_heap); + entry_times = do_alloca(3 * sizeof(int) * cfg->blocks_count, tree_use_heap); exit_times = entry_times + cfg->blocks_count; + sorted_blocks = exit_times + cfg->blocks_count; memset(entry_times, -1, 2 * sizeof(int) * cfg->blocks_count); zend_worklist_push(&work, 0); @@ -826,27 +821,35 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c zend_worklist_pop(&work); } - /* Sort blocks by decreasing level, which is the order in which we want to process them */ - sorted_blocks = do_alloca(sizeof(block_info) * cfg->blocks_count, sorted_blocks_use_heap); - for (i = 0; i < cfg->blocks_count; i++) { - sorted_blocks[i].id = i; - sorted_blocks[i].level = blocks[i].level; + /* Sort blocks by level, which is the opposite order in which we want to process them */ + sorted_blocks[0] = 0; + j = 0; + n = 1; + while (j != n) { + i = j; + j = n; + for (; i < j; i++) { + int child; + for (child = blocks[sorted_blocks[i]].children; child >= 0; child = blocks[child].next_child) { + sorted_blocks[n++] = child; + } + } } - zend_sort(sorted_blocks, cfg->blocks_count, sizeof(block_info), - (compare_func_t) compare_block_level, (swap_func_t) swap_blocks); - /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ - Graphs". */ + /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ Graphs". */ + while (n > 0) { + i = sorted_blocks[--n]; - for (n = 0; n < cfg->blocks_count; n++) { - i = sorted_blocks[n].id; + if (blocks[i].predecessors_count < 2) { + /* loop header has at least two input edges */ + continue; + } - zend_bitset_clear(work.visited, zend_bitset_len(cfg->blocks_count)); for (j = 0; j < blocks[i].predecessors_count; j++) { int pred = cfg->predecessors[blocks[i].predecessor_offset + j]; /* A join edge is one for which the predecessor does not - immediately dominate the successor. */ + immediately dominate the successor. */ if (blocks[i].idom == pred) { continue; } @@ -856,6 +859,9 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c if (dominates(blocks, i, pred)) { blocks[i].flags |= ZEND_BB_LOOP_HEADER; flag &= ~ZEND_FUNC_NO_LOOPS; + if (!zend_worklist_len(&work)) { + zend_bitset_clear(work.visited, zend_bitset_len(cfg->blocks_count)); + } zend_worklist_push(&work, pred); } else { /* Otherwise it's a cross-join edge. See if it's a branch @@ -885,7 +891,6 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c } } - free_alloca(sorted_blocks, sorted_blocks_use_heap); free_alloca(entry_times, tree_use_heap); ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap); From bea542a9536013390b40b7c32ddf94676e56001b Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 6 Feb 2022 17:18:46 +0000 Subject: [PATCH 119/227] Haiku fix ZTS build, disabling tls model Closes GH-8047. --- NEWS | 3 +++ TSRM/TSRM.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3b25cf62d3f27..9502c2a38eabb 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.17 +- Core: + . Fixed Haiku ZTS build. (David Carlier) + - Iconv: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 188ed29f0bc5e..81343f3477409 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -147,7 +147,7 @@ TSRM_API const char *tsrm_api_name(void); # define __has_attribute(x) 0 #endif -#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) +#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__) # define TSRM_TLS_MODEL_ATTR #elif __PIC__ # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec"))) From 86c196ba7f73f4bb90530a80631a0cc737a6c684 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 3 Feb 2022 14:26:57 +0100 Subject: [PATCH 120/227] Fix GH-7980: Unexpected result for iconv_mime_decode We need to reset the shift state right after conversion, to cater to potenially following plain encodings. Also, there is no need to reset the shift for plain encodings, because these are not state-dependent. Closes GH-8025. --- NEWS | 1 + ext/iconv/iconv.c | 10 +++------- ext/iconv/tests/gh7980.phpt | 13 +++++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 ext/iconv/tests/gh7980.phpt diff --git a/NEWS b/NEWS index 9502c2a38eabb..a273da6f91927 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PHP NEWS - Iconv: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) + . Fixed bug GH-7980 (Unexpected result for iconv_mime_decode). (cmb) - Zlib: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index d0693c08f2062..7a66c965e3cbf 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1576,6 +1576,9 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st } err = _php_iconv_appendl(pretval, ZSTR_VAL(decoded_text), ZSTR_LEN(decoded_text), cd); + if (err == PHP_ICONV_ERR_SUCCESS) { + err = _php_iconv_appendl(pretval, NULL, 0, cd); + } zend_string_release_ex(decoded_text, 0); if (err != PHP_ICONV_ERR_SUCCESS) { @@ -1716,13 +1719,6 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st *next_pos = p1; } - if (cd != (iconv_t)(-1)) { - _php_iconv_appendl(pretval, NULL, 0, cd); - } - if (cd_pl != (iconv_t)(-1)) { - _php_iconv_appendl(pretval, NULL, 0, cd_pl); - } - smart_str_0(pretval); out: if (cd != (iconv_t)(-1)) { diff --git a/ext/iconv/tests/gh7980.phpt b/ext/iconv/tests/gh7980.phpt new file mode 100644 index 0000000000000..a2c875a03d9cc --- /dev/null +++ b/ext/iconv/tests/gh7980.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug GH-7980 (Unexpected result for iconv_mime_decode) +--SKIPIF-- + +--FILE-- +'; +var_dump(iconv_mime_decode($subject, ICONV_MIME_DECODE_STRICT, 'UTF-8')); +?> +--EXPECT-- +string(57) "DSI Chargé de Formation Jean Dupont " From 2d579a1495be77227aedd9fc8e7a85635ed6da3f Mon Sep 17 00:00:00 2001 From: Tony Su Date: Tue, 8 Feb 2022 17:38:33 +0800 Subject: [PATCH 121/227] [ci skip] Update README.md on ZE description Expand ZE to Zend Engine and remove Zend Engine version. per Christoph M. Becker's comment for PR-8008. Signed-off-by: Su, Tao Closes GH-8057. --- Zend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/README.md b/Zend/README.md index d164da4736e94..26f3613c34bb3 100644 --- a/Zend/README.md +++ b/Zend/README.md @@ -130,7 +130,7 @@ different opcode threading model using `--with-vm-kind=CALL|SWITCH|GOTO|HYBRID`. You can disable opcode specialization using `--without-specializer`. At last you can debug the executor using the original `zend_vm_def.h` or the generated `zend_vm_execute.h` file. Debugging with the original file requires -the `--with-lines` option. By default ZE3 (since PHP 7) uses the following +the `--with-lines` option. By default, Zend Engine uses the following command to generate the executor: ```bash From 1d48da6da581c4d1c55f8b6f78cc73bad0136929 Mon Sep 17 00:00:00 2001 From: Brett <6075681+developerbmw@users.noreply.github.com> Date: Tue, 8 Feb 2022 14:37:52 +1300 Subject: [PATCH 122/227] Fixed libpng warning when loading interlaced images We enable interlace transform when reading png. Closes GH-8002. --- NEWS | 3 +++ ext/gd/libgd/gd_png.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/NEWS b/NEWS index a273da6f91927..64bb448e262ef 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ PHP NEWS - Core: . Fixed Haiku ZTS build. (David Carlier) +- GD: + . Fixed libpng warning when loading interlaced images. (Brett) + - Iconv: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) . Fixed bug GH-7980 (Unexpected result for iconv_mime_decode). (cmb) diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index 952d65240db17..c7de330b929c4 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -336,6 +336,11 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) break; } + /* enable the interlace transform if supported */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + (void)png_set_interlace_handling(png_ptr); +#endif + png_read_update_info(png_ptr, info_ptr); /* allocate space for the PNG image data */ From c035298eb2cf309c486c0652ae5706e961e1fd1f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 8 Feb 2022 15:45:40 +0300 Subject: [PATCH 123/227] Free cached chunks when the requested memory limit is above real usage --- Zend/zend_alloc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 5738c030a5822..6e0ce4b651dc2 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2660,10 +2660,23 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) ZEND_API zend_result zend_set_memory_limit_ex(size_t memory_limit) { #if ZEND_MM_LIMIT + zend_mm_heap *heap = AG(mm_heap); + if (memory_limit < ZEND_MM_CHUNK_SIZE) { memory_limit = ZEND_MM_CHUNK_SIZE; } - if (UNEXPECTED(memory_limit < AG(mm_heap)->real_size)) { + if (UNEXPECTED(memory_limit < heap->real_size)) { + if (memory_limit >= heap->real_size - heap->cached_chunks_count * ZEND_MM_CHUNK_SIZE) { + /* free some cached chunks to fit into new memory limit */ + do { + zend_mm_chunk *p = heap->cached_chunks; + heap->cached_chunks = p->next; + zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE); + heap->cached_chunks_count--; + heap->real_size -= ZEND_MM_CHUNK_SIZE; + } while (memory_limit < heap->real_size); + return SUCCESS; + } return FAILURE; } AG(mm_heap)->limit = memory_limit; From 3b463749f544a7b538264ee2a9647e4bca92f9b0 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 8 Feb 2022 09:36:37 +0100 Subject: [PATCH 124/227] Fix GH-8059 use $PHP_EXECUTABLE when $PHP not set --- build/Makefile.global | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/Makefile.global b/build/Makefile.global index 6941bab6ad412..f93a874ce1b57 100644 --- a/build/Makefile.global +++ b/build/Makefile.global @@ -148,6 +148,9 @@ prof-use: if test ! -z "$(PHP)"; then \ echo Parse $< to generate $@;\ $(PHP) $(top_srcdir)/build/gen_stub.php $<; \ + elif test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \ + echo Parse $< to generate $@;\ + $(PHP_EXECUTABLE) $(top_srcdir)/build/gen_stub.php $<; \ fi; \ fi; From c03e111e6a39024677b2cc5d30a9baf2fe84dbc5 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 8 Feb 2022 13:54:35 +0100 Subject: [PATCH 125/227] [ci skip] news --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index f4ed66db02e27..c1df994e029d3 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ PHP NEWS - Core: . Fixed Haiku ZTS build. (David Carlier) + . Fixed bug GH-8059 arginfo not regenerated for extension. (Remi) - GD: . Fixed libpng warning when loading interlaced images. (Brett) From 29fe06fa5919bb0f239677d29f3856d64537eeec Mon Sep 17 00:00:00 2001 From: Till Backhaus Date: Mon, 19 Mar 2018 13:06:04 +0100 Subject: [PATCH 126/227] Fix bug #76109: Implement fpm_scoreboard_copy fpm_scoreboard_copy locks the scoreboard while copying the scoreboard and all proc scoreboards. proc scoreboards are locked one by one while copying each struct. The old implementation (inside fpm_handle_status_request) only briefly locked the scoreboard while copying the scorebard. Closes GH-7931 Co-authored-by: Jakub Zelenka --- NEWS | 4 ++ sapi/fpm/fpm/fpm_scoreboard.c | 57 +++++++++++++++++ sapi/fpm/fpm/fpm_scoreboard.h | 6 ++ sapi/fpm/fpm/fpm_status.c | 112 ++++++++++++++++------------------ 4 files changed, 118 insertions(+), 61 deletions(-) diff --git a/NEWS b/NEWS index 64bb448e262ef..3e1d12d0fc9b0 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ PHP NEWS - GD: . Fixed libpng warning when loading interlaced images. (Brett) +- FPM: + . Fixed bug #76109 (Unsafe access to fpm scoreboard). + (Till Backhaus, Jakub Zelenka) + - Iconv: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) . Fixed bug GH-7980 (Unexpected result for iconv_mime_decode). (cmb) diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 5380d184901bf..ec28af49d7c4b 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -226,6 +226,63 @@ void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard) { scoreboard->lock = 0; } +struct fpm_scoreboard_s *fpm_scoreboard_copy(struct fpm_scoreboard_s *scoreboard, int copy_procs) +{ + struct fpm_scoreboard_s *scoreboard_copy; + struct fpm_scoreboard_proc_s *scoreboard_proc_p; + size_t scoreboard_size, scoreboard_nprocs_size; + int i; + void *mem; + + if (!scoreboard) { + scoreboard = fpm_scoreboard_get(); + } + + if (copy_procs) { + scoreboard_size = sizeof(struct fpm_scoreboard_s); + scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs; + + mem = malloc(scoreboard_size + scoreboard_nprocs_size); + } else { + mem = malloc(sizeof(struct fpm_scoreboard_s)); + } + + if (!mem) { + zlog(ZLOG_ERROR, "scoreboard: failed to allocate memory for copy"); + return NULL; + } + + scoreboard_copy = mem; + + scoreboard = fpm_scoreboard_acquire(scoreboard, FPM_SCOREBOARD_LOCK_NOHANG); + if (!scoreboard) { + free(mem); + zlog(ZLOG_ERROR, "scoreboard: failed to lock (already locked)"); + return NULL; + } + + *scoreboard_copy = *scoreboard; + + if (copy_procs) { + mem += scoreboard_size; + + for (i = 0; i < scoreboard->nprocs; i++, mem += sizeof(struct fpm_scoreboard_proc_s)) { + scoreboard_proc_p = fpm_scoreboard_proc_acquire(scoreboard, i, FPM_SCOREBOARD_LOCK_HANG); + scoreboard_copy->procs[i] = *scoreboard_proc_p; + fpm_scoreboard_proc_release(scoreboard_proc_p); + } + } + + fpm_scoreboard_release(scoreboard); + + return scoreboard_copy; +} + +void fpm_scoreboard_free_copy(struct fpm_scoreboard_s *scoreboard) +{ + free(scoreboard); +} + struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang) /* {{{ */ { struct fpm_scoreboard_proc_s *proc; diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index 363bdd260547c..e22d6d933a00a 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -15,6 +15,9 @@ #define FPM_SCOREBOARD_ACTION_SET 0 #define FPM_SCOREBOARD_ACTION_INC 1 +#define FPM_SCOREBOARD_LOCK_HANG 0 +#define FPM_SCOREBOARD_LOCK_NOHANG 1 + struct fpm_scoreboard_proc_s { union { atomic_t lock; @@ -87,6 +90,9 @@ void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid); void fpm_scoreboard_proc_free(struct fpm_child_s *child); int fpm_scoreboard_proc_alloc(struct fpm_child_s *child); +struct fpm_scoreboard_s *fpm_scoreboard_copy(struct fpm_scoreboard_s *scoreboard, int copy_procs); +void fpm_scoreboard_free_copy(struct fpm_scoreboard_s *scoreboard); + #ifdef HAVE_TIMES float fpm_scoreboard_get_tick(); #endif diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index 0d74f551b7970..b77c7fb700aa0 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -136,8 +136,8 @@ int fpm_status_export_to_zval(zval *status) int fpm_status_handle_request(void) /* {{{ */ { - struct fpm_scoreboard_s scoreboard, *scoreboard_p; - struct fpm_scoreboard_proc_s proc; + struct fpm_scoreboard_s *scoreboard_p; + struct fpm_scoreboard_proc_s *proc; char *buffer, *time_format, time_buffer[64]; time_t now_epoch; int full, encode; @@ -170,9 +170,16 @@ int fpm_status_handle_request(void) /* {{{ */ if (fpm_status_uri && !strcmp(fpm_status_uri, SG(request_info).request_uri)) { fpm_request_executing(); + /* full status ? */ + _GET_str = zend_string_init(ZEND_STRL("_GET"), 0); + full = (fpm_php_get_string_from_table(_GET_str, "full") != NULL); + short_syntax = short_post = NULL; + full_separator = full_pre = full_syntax = full_post = NULL; + encode = 0; + scoreboard_p = fpm_scoreboard_get(); - if (scoreboard_p->shared) { - scoreboard_p = scoreboard_p->shared; + if (scoreboard_p) { + scoreboard_p = fpm_scoreboard_copy(scoreboard_p->shared ? scoreboard_p->shared : scoreboard_p, full); } if (!scoreboard_p) { zlog(ZLOG_ERROR, "status: unable to find or access status shared memory"); @@ -184,21 +191,9 @@ int fpm_status_handle_request(void) /* {{{ */ return 1; } - if (!fpm_spinlock(&scoreboard_p->lock, 1)) { - zlog(ZLOG_NOTICE, "[pool %s] status: scoreboard already in used.", scoreboard_p->pool); - SG(sapi_headers).http_response_code = 503; - sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); - sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); - sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); - PUTS("Server busy. Please try again later."); - return 1; - } - /* copy the scoreboard not to bother other processes */ - scoreboard = *scoreboard_p; - fpm_unlock(scoreboard_p->lock); - - if (scoreboard.idle < 0 || scoreboard.active < 0) { - zlog(ZLOG_ERROR, "[pool %s] invalid status values", scoreboard.pool); + if (scoreboard_p->idle < 0 || scoreboard_p->active < 0) { + fpm_scoreboard_free_copy(scoreboard_p); + zlog(ZLOG_ERROR, "[pool %s] invalid status values", scoreboard_p->pool); SG(sapi_headers).http_response_code = 500; sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); @@ -214,16 +209,10 @@ int fpm_status_handle_request(void) /* {{{ */ /* handle HEAD */ if (SG(request_info).headers_only) { + fpm_scoreboard_free_copy(scoreboard_p); return 1; } - /* full status ? */ - _GET_str = zend_string_init("_GET", sizeof("_GET")-1, 0); - full = (fpm_php_get_string_from_table(_GET_str, "full") != NULL); - short_syntax = short_post = NULL; - full_separator = full_pre = full_syntax = full_post = NULL; - encode = 0; - /* HTML */ if (fpm_php_get_string_from_table(_GET_str, "html")) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1); @@ -429,23 +418,23 @@ int fpm_status_handle_request(void) /* {{{ */ } } - strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&scoreboard.start_epoch)); + strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&scoreboard_p->start_epoch)); now_epoch = time(NULL); spprintf(&buffer, 0, short_syntax, - scoreboard.pool, - PM2STR(scoreboard.pm), + scoreboard_p->pool, + PM2STR(scoreboard_p->pm), time_buffer, - (unsigned long) (now_epoch - scoreboard.start_epoch), - scoreboard.requests, - scoreboard.lq, - scoreboard.lq_max, - scoreboard.lq_len, - scoreboard.idle, - scoreboard.active, - scoreboard.idle + scoreboard.active, - scoreboard.active_max, - scoreboard.max_children_reached, - scoreboard.slow_rq); + (unsigned long) (now_epoch - scoreboard_p->start_epoch), + scoreboard_p->requests, + scoreboard_p->lq, + scoreboard_p->lq_max, + scoreboard_p->lq_len, + scoreboard_p->idle, + scoreboard_p->active, + scoreboard_p->idle + scoreboard_p->active, + scoreboard_p->active_max, + scoreboard_p->max_children_reached, + scoreboard_p->slow_rq); PUTS(buffer); efree(buffer); @@ -475,7 +464,7 @@ int fpm_status_handle_request(void) /* {{{ */ if (!scoreboard_p->procs[i].used) { continue; } - proc = scoreboard_p->procs[i]; + proc = &scoreboard_p->procs[i]; if (first) { first = 0; @@ -487,44 +476,44 @@ int fpm_status_handle_request(void) /* {{{ */ query_string = NULL; tmp_query_string = NULL; - if (proc.query_string[0] != '\0') { + if (proc->query_string[0] != '\0') { if (!encode) { - query_string = proc.query_string; + query_string = proc->query_string; } else { - tmp_query_string = php_escape_html_entities_ex((const unsigned char *) proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, /* double_encode */ 1, /* quiet */ 0); + tmp_query_string = php_escape_html_entities_ex((const unsigned char *) proc->query_string, strlen(proc->query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, /* double_encode */ 1, /* quiet */ 0); query_string = ZSTR_VAL(tmp_query_string); } } /* prevent NaN */ - if (proc.cpu_duration.tv_sec == 0 && proc.cpu_duration.tv_usec == 0) { + if (proc->cpu_duration.tv_sec == 0 && proc->cpu_duration.tv_usec == 0) { cpu = 0.; } else { - cpu = (proc.last_request_cpu.tms_utime + proc.last_request_cpu.tms_stime + proc.last_request_cpu.tms_cutime + proc.last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.; + cpu = (proc->last_request_cpu.tms_utime + proc->last_request_cpu.tms_stime + proc->last_request_cpu.tms_cutime + proc->last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (proc->cpu_duration.tv_sec + proc->cpu_duration.tv_usec / 1000000.) * 100.; } - if (proc.request_stage == FPM_REQUEST_ACCEPTING) { - duration = proc.duration; + if (proc->request_stage == FPM_REQUEST_ACCEPTING) { + duration = proc->duration; } else { - timersub(&now, &proc.accepted, &duration); + timersub(&now, &proc->accepted, &duration); } - strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&proc.start_epoch)); + strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&proc->start_epoch)); spprintf(&buffer, 0, full_syntax, - (int) proc.pid, - fpm_request_get_stage_name(proc.request_stage), + (int) proc->pid, + fpm_request_get_stage_name(proc->request_stage), time_buffer, - (unsigned long) (now_epoch - proc.start_epoch), - proc.requests, + (unsigned long) (now_epoch - proc->start_epoch), + proc->requests, duration.tv_sec * 1000000UL + duration.tv_usec, - proc.request_method[0] != '\0' ? proc.request_method : "-", - proc.request_uri[0] != '\0' ? proc.request_uri : "-", + proc->request_method[0] != '\0' ? proc->request_method : "-", + proc->request_uri[0] != '\0' ? proc->request_uri : "-", query_string ? "?" : "", query_string ? query_string : "", - proc.content_length, - proc.auth_user[0] != '\0' ? proc.auth_user : "-", - proc.script_filename[0] != '\0' ? proc.script_filename : "-", - proc.request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0., - proc.request_stage == FPM_REQUEST_ACCEPTING ? proc.memory : 0); + proc->content_length, + proc->auth_user[0] != '\0' ? proc->auth_user : "-", + proc->script_filename[0] != '\0' ? proc->script_filename : "-", + proc->request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0., + proc->request_stage == FPM_REQUEST_ACCEPTING ? proc->memory : 0); PUTS(buffer); efree(buffer); @@ -538,6 +527,7 @@ int fpm_status_handle_request(void) /* {{{ */ } } + fpm_scoreboard_free_copy(scoreboard_p); return 1; } From 82bb169a083bb592291d8e6bd5e2198c00eac07b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 11:08:19 +0300 Subject: [PATCH 127/227] Tracing JIT: Fixed incorrect deoptimization info Fixes oss-fuzz #44294 --- ext/opcache/tests/jit/reg_alloc_008.phpt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ext/opcache/tests/jit/reg_alloc_008.phpt diff --git a/ext/opcache/tests/jit/reg_alloc_008.phpt b/ext/opcache/tests/jit/reg_alloc_008.phpt new file mode 100644 index 0000000000000..f71578ab4307c --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_008.phpt @@ -0,0 +1,17 @@ +--TEST-- +Register Alloction 008: Incorrect deoptimization code +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $y in %sreg_alloc_008.php on line 4 From d0f965d078c449d4c6579a69cd7d2d3c0a9250f0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 11:10:22 +0300 Subject: [PATCH 128/227] Tracing JIT: Fixed incorrect deoptimization info --- ext/opcache/jit/zend_jit_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 8d75d04d47a2e..223792e2eae92 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3864,7 +3864,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } info &= ~MAY_BE_GUARD; ssa->var_info[phi->ssa_var].type = info; - SET_STACK_TYPE(stack, i, concrete_type(info), 1); + SET_STACK_TYPE(stack, phi->var, concrete_type(info), 1); } SET_STACK_REG_EX(stack, phi->var, ival->reg, ZREG_LOAD); if (!zend_jit_load_var(&dasm_state, ssa->var_info[phi->ssa_var].type, ssa->vars[phi->ssa_var].var, ival->reg)) { From 0d6b173532d481fdb90d54685bef72d455352b6a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 12:05:57 +0300 Subject: [PATCH 129/227] JIT: Fix missed type store Fizes oss-fuzz #44376 --- ext/opcache/jit/zend_jit.c | 3 +++ ext/opcache/tests/jit/reg_alloc_009.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 ext/opcache/tests/jit/reg_alloc_009.phpt diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index fa7953e20f3f2..bec0146afecbf 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2732,6 +2732,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op op2_def_addr = op2_addr; } op1_info = OP1_INFO(); + if (ra && ssa->vars[ssa_op->op1_use].no_val) { + op1_info |= MAY_BE_UNDEF; // requres type assignment + } if (opline->result_type == IS_UNUSED) { res_addr = 0; res_info = -1; diff --git a/ext/opcache/tests/jit/reg_alloc_009.phpt b/ext/opcache/tests/jit/reg_alloc_009.phpt new file mode 100644 index 0000000000000..dfcbfc086f85f --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_009.phpt @@ -0,0 +1,24 @@ +--TEST-- +Register Alloction 009: Missing type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +> - $j++; + } +} +test(); +?> +--EXPECTF-- +Warning: Undefined variable $j in %sreg_alloc_009.php on line 4 + +Fatal error: Uncaught ArithmeticError: Bit shift by negative number in %sreg_alloc_009.php:4 +Stack trace: +#0 %sreg_alloc_009.php(7): test() +#1 {main} + thrown in %sreg_alloc_009.php on line 4 From 7434909dc652feca55da7e29db81d1f4cd09b9ad Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 13:03:36 +0300 Subject: [PATCH 130/227] Fix type inference Fixes oss-fuzz #44407 --- ext/opcache/Optimizer/zend_inference.c | 3 +++ ext/opcache/tests/jit/assign_dim_012.phpt | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_012.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index d3a483b889756..db8112d29445b 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2625,6 +2625,9 @@ static zend_always_inline int _zend_update_type_info( if (t1 & MAY_BE_STRING) { tmp |= MAY_BE_STRING | MAY_BE_NULL; } + if (t1 & MAY_BE_OBJECT) { + tmp |= (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF); + } if (t1 & (MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL|MAY_BE_UNDEF)) { tmp |= (OP1_DATA_INFO() & (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF)); diff --git a/ext/opcache/tests/jit/assign_dim_012.phpt b/ext/opcache/tests/jit/assign_dim_012.phpt new file mode 100644 index 0000000000000..0753d93618213 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_012.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT ASSIGN_DIM: 012 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +DONE From 912608d89bbf9ea1c564052855b8d484aad10319 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 13:44:49 +0300 Subject: [PATCH 131/227] JIT: Fixed register clobbering during overflow handling Fixes oss-fuzz #44535 --- ext/opcache/jit/zend_jit_x86.dasc | 12 +++++------ ext/opcache/tests/jit/assign_dim_op_007.phpt | 21 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_dim_op_007.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index e15047ef5d36a..462ba36168485 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -4457,11 +4457,11 @@ static int zend_jit_math_long_long(dasm_State **Dst, (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1))) { if (opcode == ZEND_ADD) { |.if X64 - | mov64 rax, 0x43e0000000000000 + | mov64 Ra(tmp_reg), 0x43e0000000000000 if (Z_MODE(res_addr) == IS_REG) { - | movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax + | movd xmm(Z_REG(res_addr)-ZREG_XMM0), Ra(tmp_reg) } else { - | SET_ZVAL_LVAL res_addr, rax + | SET_ZVAL_LVAL res_addr, Ra(tmp_reg) } |.else | SET_ZVAL_LVAL res_addr, 0 @@ -4470,11 +4470,11 @@ static int zend_jit_math_long_long(dasm_State **Dst, break; } else if (opcode == ZEND_SUB) { |.if X64 - | mov64 rax, 0xc3e0000000000000 + | mov64 Ra(tmp_reg), 0xc3e0000000000000 if (Z_MODE(res_addr) == IS_REG) { - | movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax + | movd xmm(Z_REG(res_addr)-ZREG_XMM0), Ra(tmp_reg) } else { - | SET_ZVAL_LVAL res_addr, rax + | SET_ZVAL_LVAL res_addr, Ra(tmp_reg) } |.else | SET_ZVAL_LVAL res_addr, 0x00200000 diff --git a/ext/opcache/tests/jit/assign_dim_op_007.phpt b/ext/opcache/tests/jit/assign_dim_op_007.phpt new file mode 100644 index 0000000000000..e8708a1255131 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_op_007.phpt @@ -0,0 +1,21 @@ +--TEST-- +JIT ASSIGN_DIM_OP: overflow +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +member = 9223372036854775807; + $this->member += 1; + } +} +new test(); +?> +DONE +--EXPECT-- +DONE From 73fed0f0285f0b225f10884d19eb26d3cfbd5084 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 15:16:08 +0300 Subject: [PATCH 132/227] Fix emory leak Fixes oss-fuzz #44408 --- Zend/tests/closure_063.phpt | 12 ++++++++++++ Zend/zend_closures.c | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/closure_063.phpt diff --git a/Zend/tests/closure_063.phpt b/Zend/tests/closure_063.phpt new file mode 100644 index 0000000000000..b53f370eb4bfc --- /dev/null +++ b/Zend/tests/closure_063.phpt @@ -0,0 +1,12 @@ +--TEST-- +Closure::bindTo leaks with "fake" closure +--FILE-- +bindTo(new stdClass); +?> +DONE +--EXPECT-- +DONE \ No newline at end of file diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index a5ae8cde359e2..b5c0b47553248 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -770,7 +770,8 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) { - zend_create_closure_ex(res, func, scope, called_scope, this_ptr, /* is_fake */ false); + zend_create_closure_ex(res, func, scope, called_scope, this_ptr, + /* is_fake */ (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0); } ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) /* {{{ */ From 52ae6417ca3e62eff796bf3e3b5662fe6a9ee085 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 15:33:31 +0300 Subject: [PATCH 133/227] Fixed GH-8044 (var_export/debug_zval_dump HT_ASSERT_RC1 debug failure for SplFixedArray) --- ext/spl/spl_fixedarray.c | 6 ++++++ ext/spl/tests/fixedarray_022.phpt | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 ext/spl/tests/fixedarray_022.phpt diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 693d3296acaec..ec53935ac9d2e 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -207,6 +207,12 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) if (!spl_fixedarray_empty(&intern->array)) { zend_long j = zend_hash_num_elements(ht); + if (GC_REFCOUNT(ht) > 1) { + intern->std.properties = zend_array_dup(ht); + if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { + GC_DELREF(ht); + } + } for (zend_long i = 0; i < intern->array.size; i++) { zend_hash_index_update(ht, i, &intern->array.elements[i]); Z_TRY_ADDREF(intern->array.elements[i]); diff --git a/ext/spl/tests/fixedarray_022.phpt b/ext/spl/tests/fixedarray_022.phpt new file mode 100644 index 0000000000000..c1cff1a926582 --- /dev/null +++ b/ext/spl/tests/fixedarray_022.phpt @@ -0,0 +1,20 @@ +--TEST-- +SPL: FixedArray: Bug GH-8044 (var_export/debug_zval_dump HT_ASSERT_RC1 debug failure for SplFixedArray) +--FILE-- + +--EXPECTF-- +Warning: var_export does not handle circular references in %s on line 5 +SplFixedArray::__set_state(array( + 0 => NULL, +)) +object(SplFixedArray)#2 (1) refcount(4){ + [0]=> + *RECURSION* +} From c77bbcd4642a982fd9fdaf32dbe444d925c7883f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Feb 2022 16:46:12 +0300 Subject: [PATCH 134/227] Fixed GH-8041 (php 8.2.0-dev crashes with assertion for cloning/get_object_vars on non-empty SplFixedArray) --- ext/spl/spl_fixedarray.c | 4 ++++ ext/spl/tests/fixedarray_023.phpt | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 ext/spl/tests/fixedarray_023.phpt diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 8901c95694f53..7bfc8413fb2ba 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -223,6 +223,10 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) zend_hash_index_del(ht, i); } } + if (HT_IS_PACKED(ht)) { + /* Engine doesn't expet packed array */ + zend_hash_packed_to_hash(ht); + } } return ht; diff --git a/ext/spl/tests/fixedarray_023.phpt b/ext/spl/tests/fixedarray_023.phpt new file mode 100644 index 0000000000000..e0e2606c90a8a --- /dev/null +++ b/ext/spl/tests/fixedarray_023.phpt @@ -0,0 +1,11 @@ +--TEST-- +SPL: FixedArray: Bug GH-8041 (php 8.2.0-dev crashes with assertion for cloning/get_object_vars on non-empty SplFixedArray) +--FILE-- + +DONE +--EXPECT-- +DONE From dce5e561a63fc970de722636ad8c09e9b079e8ae Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 31 Jan 2022 15:43:24 +0100 Subject: [PATCH 135/227] Fix #81708: UAF due to php_filter_float() failing for ints We must only release the zval, if we actually assign a new zval. --- ext/filter/logical_filters.c | 2 +- ext/filter/tests/bug81708.phpt | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 ext/filter/tests/bug81708.phpt diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index fa6ae65ac5868..e5e87c01568a4 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -435,10 +435,10 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ switch (is_numeric_string(num, p - num, &lval, &dval, 0)) { case IS_LONG: - zval_ptr_dtor(value); if ((min_range_set && (lval < min_range)) || (max_range_set && (lval > max_range))) { goto error; } + zval_ptr_dtor(value); ZVAL_DOUBLE(value, (double)lval); break; case IS_DOUBLE: diff --git a/ext/filter/tests/bug81708.phpt b/ext/filter/tests/bug81708.phpt new file mode 100644 index 0000000000000..d0036af136824 --- /dev/null +++ b/ext/filter/tests/bug81708.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #81708 (UAF due to php_filter_float() failing for ints) +--SKIPIF-- + +--INI-- +opcache.enable_cli=0 +--FILE-- + ['min_range' => -1, 'max_range' => 1]] +); +var_dump($input); +?> +--EXPECT-- +string(3) "+11" From 82f1bf1b6bc3a43aba62214870e6d0931e93a6d9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 31 Jan 2022 15:43:24 +0100 Subject: [PATCH 136/227] Fix #81708: UAF due to php_filter_float() failing for ints We must only release the zval, if we actually assign a new zval. --- ext/filter/logical_filters.c | 2 +- ext/filter/tests/bug81708.phpt | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 ext/filter/tests/bug81708.phpt diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 1bf7c00d13c68..95f7a99e34b14 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -436,10 +436,10 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ switch (is_numeric_string(num, p - num, &lval, &dval, 0)) { case IS_LONG: - zval_ptr_dtor(value); if ((min_range_set && (lval < min_range)) || (max_range_set && (lval > max_range))) { goto error; } + zval_ptr_dtor(value); ZVAL_DOUBLE(value, (double)lval); break; case IS_DOUBLE: diff --git a/ext/filter/tests/bug81708.phpt b/ext/filter/tests/bug81708.phpt new file mode 100644 index 0000000000000..d0036af136824 --- /dev/null +++ b/ext/filter/tests/bug81708.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #81708 (UAF due to php_filter_float() failing for ints) +--SKIPIF-- + +--INI-- +opcache.enable_cli=0 +--FILE-- + ['min_range' => -1, 'max_range' => 1]] +); +var_dump($input); +?> +--EXPECT-- +string(3) "+11" From 93a8d5cd1721ccb5c7ae78e227d36b580e03efc1 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Tue, 8 Feb 2022 12:08:26 +0000 Subject: [PATCH 137/227] Fix bug GH-8058 - mysqlnd segfault when prepare fails Closes GH-8061 --- NEWS | 3 + ext/mysqli/tests/gh8058.phpt | 39 ++++++++++++ .../tests/mysqli_stmt_affected_rows.phpt | 11 +--- ext/mysqlnd/mysqlnd_ps.c | 60 +++++-------------- 4 files changed, 59 insertions(+), 54 deletions(-) create mode 100644 ext/mysqli/tests/gh8058.phpt diff --git a/NEWS b/NEWS index 3e1d12d0fc9b0..91fce7ad7342a 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) . Fixed bug GH-7980 (Unexpected result for iconv_mime_decode). (cmb) +- MySQLnd: + . Fixed bug GH-8058 (NULL pointer dereference in mysqlnd package). (Kamil Tekiela) + - Zlib: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) diff --git a/ext/mysqli/tests/gh8058.phpt b/ext/mysqli/tests/gh8058.phpt new file mode 100644 index 0000000000000..8f47e372e73e3 --- /dev/null +++ b/ext/mysqli/tests/gh8058.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-8058 (NULL pointer dereference in mysqlnd package (#81706)) +--SKIPIF-- + +--FILE-- +prepare("select 1,2,3"); +$stmt->bind_result($a,$a,$a); +$stmt->prepare(""); +$stmt->prepare("select ".str_repeat("'A',", 0x1201)."1"); +unset($stmt); // trigger dtor + +// There should be no memory leak +$stmt = $mysqli->prepare("select 1,2,3"); +$stmt->bind_result($a,$a,$a); +$stmt->prepare(""); +$stmt->prepare("select 1"); +unset($stmt); // trigger dtor + +mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); +$stmt = $mysqli->prepare("select 1,2,3"); +try { + // We expect an exception to be thrown + $stmt->prepare(""); +} catch (mysqli_sql_exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECT-- +string(15) "Query was empty" diff --git a/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt b/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt index de4f73bc18ce6..ed682b7cca54b 100644 --- a/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt +++ b/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt @@ -196,18 +196,13 @@ require_once('skipifconnectfailure.inc'); /* stmt_affected_rows is not really meant for SELECT! */ if (mysqli_stmt_prepare($stmt, 'SELECT unknown_column FROM this_table_does_not_exist') || mysqli_stmt_execute($stmt)) - printf("[041] The invalid SELECT statement is issued on purpose\n"); + printf("[041] Expecting SELECT statement to fail on purpose\n"); if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) printf("[042] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); - if ($IS_MYSQLND) { - if (false !== ($tmp = mysqli_stmt_store_result($stmt))) - printf("[043] Expecting boolean/false, got %s\%s\n", gettype($tmp), $tmp); - } else { - if (true !== ($tmp = mysqli_stmt_store_result($stmt))) - printf("[043] Libmysql does not care if the previous statement was bogus, expecting boolean/true, got %s\%s\n", gettype($tmp), $tmp); - } + if (true !== ($tmp = mysqli_stmt_store_result($stmt))) + printf("[043] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); if (0 !== ($tmp = mysqli_stmt_num_rows($stmt))) printf("[044] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index f3dee49d88f33..1eac55a03fc89 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -391,12 +391,10 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s) /* {{{ mysqlnd_stmt::prepare */ static enum_func_status -MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const query, const size_t query_len) +MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * s, const char * const query, const size_t query_len) { MYSQLND_STMT_DATA * stmt = s? s->data : NULL; MYSQLND_CONN_DATA * conn = stmt? stmt->conn : NULL; - MYSQLND_STMT * s_to_prepare = s; - MYSQLND_STMT_DATA * stmt_to_prepare = stmt; DBG_ENTER("mysqlnd_stmt::prepare"); if (!stmt || !conn) { @@ -412,25 +410,15 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const SET_EMPTY_ERROR(conn->error_info); if (stmt->state > MYSQLND_STMT_INITTED) { - /* See if we have to clean the wire */ - if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) { - /* Do implicit use_result and then flush the result */ - stmt->default_rset_handler = s->m->use_result; - stmt->default_rset_handler(s); - } - /* No 'else' here please :) */ - if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE && stmt->result) { - stmt->result->m.skip_result(stmt->result); - } /* - Create a new test statement, which we will prepare, but if anything - fails, we will scrap it. + Create a new prepared statement and destroy the previous one. */ - s_to_prepare = conn->m->stmt_init(conn); - if (!s_to_prepare) { + s->m->dtor(s, TRUE); + s = conn->m->stmt_init(conn); + if (!s) { goto fail; } - stmt_to_prepare = s_to_prepare->data; + stmt = s->data; } { @@ -444,13 +432,13 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const } } - if (FAIL == mysqlnd_stmt_read_prepare_response(s_to_prepare)) { + if (FAIL == mysqlnd_stmt_read_prepare_response(s)) { goto fail; } - if (stmt_to_prepare->param_count) { - if (FAIL == mysqlnd_stmt_skip_metadata(s_to_prepare) || - FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare)) + if (stmt->param_count) { + if (FAIL == mysqlnd_stmt_skip_metadata(s) || + FAIL == mysqlnd_stmt_prepare_read_eof(s)) { goto fail; } @@ -461,51 +449,31 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const Beware that SHOW statements bypass the PS framework and thus they send no metadata at prepare. */ - if (stmt_to_prepare->field_count) { - MYSQLND_RES * result = conn->m->result_init(stmt_to_prepare->field_count); + if (stmt->field_count) { + MYSQLND_RES * result = conn->m->result_init(stmt->field_count); if (!result) { SET_OOM_ERROR(conn->error_info); goto fail; } /* Allocate the result now as it is needed for the reading of metadata */ - stmt_to_prepare->result = result; + stmt->result = result; result->conn = conn->m->get_reference(conn); result->type = MYSQLND_RES_PS_BUF; if (FAIL == result->m.read_result_metadata(result, conn) || - FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare)) + FAIL == mysqlnd_stmt_prepare_read_eof(s)) { goto fail; } } - if (stmt_to_prepare != stmt) { - /* swap */ - size_t real_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *); - char * tmp_swap = mnd_malloc(real_size); - memcpy(tmp_swap, s, real_size); - memcpy(s, s_to_prepare, real_size); - memcpy(s_to_prepare, tmp_swap, real_size); - mnd_free(tmp_swap); - { - MYSQLND_STMT_DATA * tmp_swap_data = stmt_to_prepare; - stmt_to_prepare = stmt; - stmt = tmp_swap_data; - } - s_to_prepare->m->dtor(s_to_prepare, TRUE); - } stmt->state = MYSQLND_STMT_PREPARED; DBG_INF("PASS"); DBG_RETURN(PASS); fail: - if (stmt_to_prepare != stmt && s_to_prepare) { - s_to_prepare->m->dtor(s_to_prepare, TRUE); - } - stmt->state = MYSQLND_STMT_INITTED; - DBG_INF("FAIL"); DBG_RETURN(FAIL); } From d13ceb74fa48a12ff29ca3d291d568a0f198249b Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Mon, 14 Feb 2022 16:23:06 +0000 Subject: [PATCH 138/227] Add fix to NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index b4d1e4b0378ec..076b2cd2abf92 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.4.28 +- Filter: + . Fix #81708: UAF due to php_filter_float() failing for ints + 16 Dec 2021, PHP 7.4.27 From 0fab520ded1babcdf5c54fb4b4d2642de2c7cbfe Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Mon, 14 Feb 2022 17:58:26 -0500 Subject: [PATCH 139/227] Fix zend_register_internal_class_ex alias generation (#8091) This wouldn't work for creating aliases in a namespace. It would create the class alias "MyNS_ClassName" instead of "MyNS\\ClassName" --- build/gen_stub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 486ff679499fc..348cc9e82d277 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1748,7 +1748,7 @@ function (Name $item) { } if ($this->alias) { - $code .= "\tzend_register_class_alias(\"" . str_replace("\\", "_", $this->alias) . "\", class_entry);\n"; + $code .= "\tzend_register_class_alias(\"" . str_replace("\\", "\\\\", $this->alias) . "\", class_entry);\n"; } foreach ($this->enumCaseInfos as $enumCase) { From 325bcf9f1d0d7c879f441cbbe9a8a28e30f4ea86 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Tue, 15 Feb 2022 13:27:37 +0000 Subject: [PATCH 140/227] Prepare for 7.4.29 --- NEWS | 5 ++++- configure.ac | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 076b2cd2abf92..fa117f5185fa4 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 7.4.28 +?? ??? ????, PHP 7.4.29 + + +17 Feb 2022, PHP 7.4.28 - Filter: . Fix #81708: UAF due to php_filter_float() failing for ints diff --git a/configure.ac b/configure.ac index 7155ff432f400..6f829c0e7820a 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[7.4.27-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[7.4.29-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER From e98a7a68b7b8b5b7974134f8046777bd72f141e4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 15 Feb 2022 10:15:28 +0100 Subject: [PATCH 141/227] Fix bugtracker URL The php-src bugtracker is now on Github. Closes GH-8102. --- sapi/fpm/fpm/fpm_children.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c index a24e06fc483be..0aab23043a943 100644 --- a/sapi/fpm/fpm/fpm_children.c +++ b/sapi/fpm/fpm/fpm_children.c @@ -299,7 +299,7 @@ void fpm_children_bury() /* {{{ */ } } } else { - zlog(ZLOG_ALERT, "oops, unknown child (%d) exited %s. Please open a bug report (https://bugs.php.net).", pid, buf); + zlog(ZLOG_ALERT, "oops, unknown child (%d) exited %s. Please open a bug report (https://github.com/php/php-src/issues).", pid, buf); } } } From bfe9531dc1b8ad235108d4f310f57df0c75d6bb7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 16 Feb 2022 19:01:44 +0100 Subject: [PATCH 142/227] Initialize int_codepoint in parse_code_point_param() This is being passed to convert_cp(), and passing an uninitialized value to a function is undefined behavior. Clang 14 makes use of noundef facts aggressively and miscompiles this code if not initialized. --- ext/intl/uchar/uchar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/intl/uchar/uchar.c b/ext/intl/uchar/uchar.c index 0f44b454b4499..58f9615de7050 100644 --- a/ext/intl/uchar/uchar.c +++ b/ext/intl/uchar/uchar.c @@ -38,7 +38,7 @@ static inline int convert_cp(UChar32* pcp, zend_string *string_codepoint, zend_l static zend_never_inline int parse_code_point_param(INTERNAL_FUNCTION_PARAMETERS, UChar32 *cp) { zend_string *string_codepoint; - zend_long int_codepoint; + zend_long int_codepoint = 0; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); From f06ac9a486ada028d85cda8a73bdd709eb7b0d95 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 20 Jan 2022 11:30:35 +0100 Subject: [PATCH 143/227] Fix GH-7939: Cannot unserialize IntlTimeZone objects As it is now, `IntlTimeZone`, `IntlCalendar` and `IntlDateFormatter` and some other intl class instances can be serialized, but the representation is meaningless, and unserialization yields uninitialized/ unusable objects. To prevent users from noticing this too late, we deny serialization of such objects in the first place. Closes GH-7945. --- NEWS | 1 + UPGRADING | 8 ++++++++ ext/intl/breakiterator/breakiterator.stub.php | 3 +++ ext/intl/breakiterator/breakiterator_arginfo.h | 5 ++++- ext/intl/breakiterator/breakiterator_iterators.stub.php | 1 + ext/intl/breakiterator/breakiterator_iterators_arginfo.h | 3 ++- ext/intl/calendar/calendar.stub.php | 2 ++ ext/intl/calendar/calendar_arginfo.h | 4 +++- ext/intl/collator/collator.stub.php | 1 + ext/intl/collator/collator_arginfo.h | 3 ++- ext/intl/common/common.stub.php | 1 + ext/intl/common/common_arginfo.h | 3 ++- ext/intl/converter/converter.stub.php | 1 + ext/intl/converter/converter_arginfo.h | 3 ++- ext/intl/dateformat/dateformat.stub.php | 1 + ext/intl/dateformat/dateformat_arginfo.h | 3 ++- ext/intl/dateformat/datepatterngenerator.stub.php | 1 + ext/intl/dateformat/datepatterngenerator_arginfo.h | 3 ++- ext/intl/msgformat/msgformat.stub.php | 1 + ext/intl/msgformat/msgformat_arginfo.h | 3 ++- ext/intl/resourcebundle/resourcebundle.stub.php | 1 + ext/intl/resourcebundle/resourcebundle_arginfo.h | 3 ++- ext/intl/spoofchecker/spoofchecker.stub.php | 1 + ext/intl/spoofchecker/spoofchecker_arginfo.h | 3 ++- ext/intl/timezone/timezone.stub.php | 1 + ext/intl/timezone/timezone_arginfo.h | 3 ++- ext/intl/transliterator/transliterator.stub.php | 1 + ext/intl/transliterator/transliterator_arginfo.h | 3 ++- 28 files changed, 54 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 09da40c962e28..00ba31fd248e2 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ PHP NEWS - Intl: . Update all grandfathered language tags with preferred values + . Fixed GH-7939 (Cannot unserialize IntlTimeZone objects). (cmb) - OCI8: . Added oci8.prefetch_lob_size directive to tune LOB query performance diff --git a/UPGRADING b/UPGRADING index 4d918a85bfc17..efc6f36df0eef 100644 --- a/UPGRADING +++ b/UPGRADING @@ -126,6 +126,14 @@ PHP 8.2 UPGRADE NOTES 9. Other Changes to Extensions ======================================== +- Intl: + . IntlBreakIterator, IntlRuleBasedBreakIterator, IntlCodePointBreakIterator, + IntlPartsIterator, IntlCalendar, IntlCalendar, Collator, IntlIterator, + UConverter, IntlDateFormatter, IntlDatePatternGenerator, MessageFormatter, + ResourceBundle, Spoofchecker, IntlTimeZone and Transliterator instances are + no longer serializable. Previously, they could be serialized, but + unserialization yielded unusable objects or failed. + - OCI8: . The minimum Oracle Client library version required is now 11.2. diff --git a/ext/intl/breakiterator/breakiterator.stub.php b/ext/intl/breakiterator/breakiterator.stub.php index c78e48da62700..951b4ffc1bdfd 100644 --- a/ext/intl/breakiterator/breakiterator.stub.php +++ b/ext/intl/breakiterator/breakiterator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlBreakIterator implements IteratorAggregate { /** @tentative-return-type */ @@ -69,6 +70,7 @@ public function setText(string $text): ?bool {} // TODO return false instead of public function getIterator(): Iterator {} } +/** @not-serializable */ class IntlRuleBasedBreakIterator extends IntlBreakIterator { public function __construct(string $rules, bool $compiled = false) {} @@ -86,6 +88,7 @@ public function getRuleStatus(): int {} public function getRuleStatusVec(): array|false {} } +/** @not-serializable */ class IntlCodePointBreakIterator extends IntlBreakIterator { /** @tentative-return-type */ diff --git a/ext/intl/breakiterator/breakiterator_arginfo.h b/ext/intl/breakiterator/breakiterator_arginfo.h index 04f834a087eb0..ffb5017ab4263 100644 --- a/ext/intl/breakiterator/breakiterator_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1979da7ee2fa55b27f1c91bb4e0ddc37e8505b08 */ + * Stub hash: 724e0c36ee113b67906cc9a8cea23781f0a961bf */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlBreakIterator_createCharacterInstance, 0, 0, IntlBreakIterator, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") @@ -161,6 +161,7 @@ static zend_class_entry *register_class_IntlBreakIterator(zend_class_entry *clas INIT_CLASS_ENTRY(ce, "IntlBreakIterator", class_IntlBreakIterator_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; zend_class_implements(class_entry, 1, class_entry_IteratorAggregate); return class_entry; @@ -172,6 +173,7 @@ static zend_class_entry *register_class_IntlRuleBasedBreakIterator(zend_class_en INIT_CLASS_ENTRY(ce, "IntlRuleBasedBreakIterator", class_IntlRuleBasedBreakIterator_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlBreakIterator); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } @@ -182,6 +184,7 @@ static zend_class_entry *register_class_IntlCodePointBreakIterator(zend_class_en INIT_CLASS_ENTRY(ce, "IntlCodePointBreakIterator", class_IntlCodePointBreakIterator_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlBreakIterator); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/breakiterator/breakiterator_iterators.stub.php b/ext/intl/breakiterator/breakiterator_iterators.stub.php index 7e7603fe6fd54..9d2fa9442819f 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.stub.php +++ b/ext/intl/breakiterator/breakiterator_iterators.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlPartsIterator extends IntlIterator { /** @tentative-return-type */ diff --git a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h index ee5e1279b5d2a..8db11d23739e0 100644 --- a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 267199a0a3532b5acf1d700f14329cdb2f2db0e1 */ + * Stub hash: f72f108e37541ac042bb25249ef226211c344189 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlPartsIterator_getBreakIterator, 0, 0, IntlBreakIterator, 0) ZEND_END_ARG_INFO() @@ -24,6 +24,7 @@ static zend_class_entry *register_class_IntlPartsIterator(zend_class_entry *clas INIT_CLASS_ENTRY(ce, "IntlPartsIterator", class_IntlPartsIterator_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlIterator); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/calendar/calendar.stub.php b/ext/intl/calendar/calendar.stub.php index 709d0e3667c7f..85c2c8a05e52c 100644 --- a/ext/intl/calendar/calendar.stub.php +++ b/ext/intl/calendar/calendar.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlCalendar { private function __construct() {} @@ -281,6 +282,7 @@ public function setTimeZone($timezone): bool {} public function toDateTime(): DateTime|false {} } +/** @not-serializable */ class IntlGregorianCalendar extends IntlCalendar { /** diff --git a/ext/intl/calendar/calendar_arginfo.h b/ext/intl/calendar/calendar_arginfo.h index 7be45231f9c90..7b22161f30f5d 100644 --- a/ext/intl/calendar/calendar_arginfo.h +++ b/ext/intl/calendar/calendar_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7be0e49d2b898587c4bbefaaf613932ae4786c52 */ + * Stub hash: 0096dc9e60e2256054d23344e024df1d6527a5fa */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlCalendar___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -291,6 +291,7 @@ static zend_class_entry *register_class_IntlCalendar(void) INIT_CLASS_ENTRY(ce, "IntlCalendar", class_IntlCalendar_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } @@ -301,6 +302,7 @@ static zend_class_entry *register_class_IntlGregorianCalendar(zend_class_entry * INIT_CLASS_ENTRY(ce, "IntlGregorianCalendar", class_IntlGregorianCalendar_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_IntlCalendar); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/collator/collator.stub.php b/ext/intl/collator/collator.stub.php index e0c8487af79ff..bd201ee28be61 100644 --- a/ext/intl/collator/collator.stub.php +++ b/ext/intl/collator/collator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class Collator { public function __construct(string $locale) {} diff --git a/ext/intl/collator/collator_arginfo.h b/ext/intl/collator/collator_arginfo.h index f13e1197dd8eb..c693ad925088b 100644 --- a/ext/intl/collator/collator_arginfo.h +++ b/ext/intl/collator/collator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4baf9586ab91f37facc865cf1b3aa6a87e5d732d */ + * Stub hash: c2e08f16cdc3d64e82fc277b4a59250d4b19c84e */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Collator___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -96,6 +96,7 @@ static zend_class_entry *register_class_Collator(void) INIT_CLASS_ENTRY(ce, "Collator", class_Collator_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/common/common.stub.php b/ext/intl/common/common.stub.php index 0e87db6f51920..acadedd39934c 100644 --- a/ext/intl/common/common.stub.php +++ b/ext/intl/common/common.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlIterator implements Iterator { /** @tentative-return-type */ diff --git a/ext/intl/common/common_arginfo.h b/ext/intl/common/common_arginfo.h index 79d63aa5f4fdd..cbf422bf0d4c6 100644 --- a/ext/intl/common/common_arginfo.h +++ b/ext/intl/common/common_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c4698dbe96a069a63265052e9a105f074e3dda0a */ + * Stub hash: 976f2d1417928226d6c04ff444c4feda152d91df */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlIterator_current, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() @@ -37,6 +37,7 @@ static zend_class_entry *register_class_IntlIterator(zend_class_entry *class_ent INIT_CLASS_ENTRY(ce, "IntlIterator", class_IntlIterator_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; zend_class_implements(class_entry, 1, class_entry_Iterator); return class_entry; diff --git a/ext/intl/converter/converter.stub.php b/ext/intl/converter/converter.stub.php index 9e07341778b20..19a8bbef9512f 100644 --- a/ext/intl/converter/converter.stub.php +++ b/ext/intl/converter/converter.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class UConverter { public function __construct(?string $destination_encoding = null, ?string $source_encoding = null) {} diff --git a/ext/intl/converter/converter_arginfo.h b/ext/intl/converter/converter_arginfo.h index fa88dd2ab630e..cae2a68d4be07 100644 --- a/ext/intl/converter/converter_arginfo.h +++ b/ext/intl/converter/converter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2a6d8499e1a2d414130e366783a1c084f47a3293 */ + * Stub hash: 0ab2d741996611bbfcfb07462bc184a02f353585 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_UConverter___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, destination_encoding, IS_STRING, 1, "null") @@ -125,6 +125,7 @@ static zend_class_entry *register_class_UConverter(void) INIT_CLASS_ENTRY(ce, "UConverter", class_UConverter_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/dateformat/dateformat.stub.php b/ext/intl/dateformat/dateformat.stub.php index 11c0d05dc41e6..0ea15225f5a25 100644 --- a/ext/intl/dateformat/dateformat.stub.php +++ b/ext/intl/dateformat/dateformat.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlDateFormatter { /** diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index ccad07cd60a9d..9cb936f530992 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 82f90e7b0528b2b3515c086763dba4de0f92dfa7 */ + * Stub hash: c7c0d08433ab9dbf59777072550895d85294aad4 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) @@ -141,6 +141,7 @@ static zend_class_entry *register_class_IntlDateFormatter(void) INIT_CLASS_ENTRY(ce, "IntlDateFormatter", class_IntlDateFormatter_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/dateformat/datepatterngenerator.stub.php b/ext/intl/dateformat/datepatterngenerator.stub.php index c0190fb4e9859..a9ce7c1463120 100644 --- a/ext/intl/dateformat/datepatterngenerator.stub.php +++ b/ext/intl/dateformat/datepatterngenerator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlDatePatternGenerator { public function __construct(?string $locale = null) {} diff --git a/ext/intl/dateformat/datepatterngenerator_arginfo.h b/ext/intl/dateformat/datepatterngenerator_arginfo.h index 63e8df7a5429c..f72e24cd1e7aa 100644 --- a/ext/intl/dateformat/datepatterngenerator_arginfo.h +++ b/ext/intl/dateformat/datepatterngenerator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 74026c524046787844da9f8132029735243176c6 */ + * Stub hash: 4456b13f7ed59847bbf129cd45b0d1f63ce70108 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDatePatternGenerator___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") @@ -32,6 +32,7 @@ static zend_class_entry *register_class_IntlDatePatternGenerator(void) INIT_CLASS_ENTRY(ce, "IntlDatePatternGenerator", class_IntlDatePatternGenerator_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/msgformat/msgformat.stub.php b/ext/intl/msgformat/msgformat.stub.php index c85a9b92b3a32..20afbd2b42cd4 100644 --- a/ext/intl/msgformat/msgformat.stub.php +++ b/ext/intl/msgformat/msgformat.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class MessageFormatter { public function __construct(string $locale, string $pattern) {} diff --git a/ext/intl/msgformat/msgformat_arginfo.h b/ext/intl/msgformat/msgformat_arginfo.h index 8f0456f6cbb05..4e7146048640d 100644 --- a/ext/intl/msgformat/msgformat_arginfo.h +++ b/ext/intl/msgformat/msgformat_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 44bc7b87c0b6c674bf94764b3f036006e3933713 */ + * Stub hash: d595f5c582996ebb96ab39df8cb56c4cf6c8dfcf */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MessageFormatter___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -81,6 +81,7 @@ static zend_class_entry *register_class_MessageFormatter(void) INIT_CLASS_ENTRY(ce, "MessageFormatter", class_MessageFormatter_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/resourcebundle/resourcebundle.stub.php b/ext/intl/resourcebundle/resourcebundle.stub.php index 4247fca318a4e..47df7a19b3a9f 100644 --- a/ext/intl/resourcebundle/resourcebundle.stub.php +++ b/ext/intl/resourcebundle/resourcebundle.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class ResourceBundle implements IteratorAggregate, Countable { public function __construct(?string $locale, ?string $bundle, bool $fallback = true) {} diff --git a/ext/intl/resourcebundle/resourcebundle_arginfo.h b/ext/intl/resourcebundle/resourcebundle_arginfo.h index 0564b026dc39b..6a478edd430b2 100644 --- a/ext/intl/resourcebundle/resourcebundle_arginfo.h +++ b/ext/intl/resourcebundle/resourcebundle_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d27fa5a4dc092b94e48fc876070f440c247fa6c2 */ + * Stub hash: 7816536650d8513ef6998233096b0bf6a29d7af4 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ResourceBundle___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) @@ -62,6 +62,7 @@ static zend_class_entry *register_class_ResourceBundle(zend_class_entry *class_e INIT_CLASS_ENTRY(ce, "ResourceBundle", class_ResourceBundle_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; zend_class_implements(class_entry, 2, class_entry_IteratorAggregate, class_entry_Countable); return class_entry; diff --git a/ext/intl/spoofchecker/spoofchecker.stub.php b/ext/intl/spoofchecker/spoofchecker.stub.php index 0ff7cc6da7c4a..dc414949b0ab8 100644 --- a/ext/intl/spoofchecker/spoofchecker.stub.php +++ b/ext/intl/spoofchecker/spoofchecker.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class Spoofchecker { public function __construct() {} diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h index 281ea7f3ed330..c030015d49c86 100644 --- a/ext/intl/spoofchecker/spoofchecker_arginfo.h +++ b/ext/intl/spoofchecker/spoofchecker_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d915fb3698e0bde4af2a1175fff882cae1f55668 */ + * Stub hash: f1c86958a39aa8f89ee468a0753f6a5b232c3e1f */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Spoofchecker___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -58,6 +58,7 @@ static zend_class_entry *register_class_Spoofchecker(void) INIT_CLASS_ENTRY(ce, "Spoofchecker", class_Spoofchecker_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/timezone/timezone.stub.php b/ext/intl/timezone/timezone.stub.php index cc4f6084fd535..55592a386cc0f 100644 --- a/ext/intl/timezone/timezone.stub.php +++ b/ext/intl/timezone/timezone.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class IntlTimeZone { private function __construct() {} diff --git a/ext/intl/timezone/timezone_arginfo.h b/ext/intl/timezone/timezone_arginfo.h index c8a77dcb07829..d0d1e94d2f84f 100644 --- a/ext/intl/timezone/timezone_arginfo.h +++ b/ext/intl/timezone/timezone_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3f945431687a2f45b0ec8c3a6435ef68008c75ad */ + * Stub hash: 2ec7a46ca205dfeb9ef0dc3c8e8d78bce1cf43be */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlTimeZone___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -169,6 +169,7 @@ static zend_class_entry *register_class_IntlTimeZone(void) INIT_CLASS_ENTRY(ce, "IntlTimeZone", class_IntlTimeZone_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } diff --git a/ext/intl/transliterator/transliterator.stub.php b/ext/intl/transliterator/transliterator.stub.php index 6d52263e0646f..81c4070352825 100644 --- a/ext/intl/transliterator/transliterator.stub.php +++ b/ext/intl/transliterator/transliterator.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +/** @not-serializable */ class Transliterator { public string $id; diff --git a/ext/intl/transliterator/transliterator_arginfo.h b/ext/intl/transliterator/transliterator_arginfo.h index c80be4f5b3460..03aa3b1f0ee9c 100644 --- a/ext/intl/transliterator/transliterator_arginfo.h +++ b/ext/intl/transliterator/transliterator_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8a6aaab7dd89a014726bd1fdf1f40f7b6fa98ea5 */ + * Stub hash: 8ef1f285c6138fbc58c1e4cef04d4ac09dfc3fef */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Transliterator___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -61,6 +61,7 @@ static zend_class_entry *register_class_Transliterator(void) INIT_CLASS_ENTRY(ce, "Transliterator", class_Transliterator_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); From 8f5480e7ebbb94c46baa4ca8c7d4826f9ae614af Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 17 Feb 2022 19:16:15 +0300 Subject: [PATCH 144/227] Release lock and protect SHM before replaying warnings --- ext/opcache/ZendAccelerator.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 6883979e7d131..c195ad7d2cbcc 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2195,6 +2195,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) zend_hash_index_del(EG(zend_constants), new_const_num); } } + persistent_script->dynamic_members.last_used = ZCG(request_time); + SHM_PROTECT(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } else { #if !ZEND_WIN32 @@ -2231,16 +2234,16 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) } } } + + persistent_script->dynamic_members.last_used = ZCG(request_time); + SHM_PROTECT(); + HANDLE_UNBLOCK_INTERRUPTIONS(); + replay_warnings(persistent_script); zend_file_handle_dtor(file_handle); from_shared_memory = 1; } - persistent_script->dynamic_members.last_used = ZCG(request_time); - - SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); - /* Fetch jit auto globals used in the script before execution */ if (persistent_script->ping_auto_globals_mask) { zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask); From 7e8257fbd29193e2087cb90ea74afa3ec4cd7c64 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Feb 2022 11:35:43 +0300 Subject: [PATCH 145/227] Disable ASSIGN optimization for values inferred for fatal errors. --- Zend/Optimizer/dfa_pass.c | 2 ++ ext/opcache/tests/jit/assign_051.phpt | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_051.phpt diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index d0b52fbfcd1bb..5f7d027a73bf6 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -1356,6 +1356,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx if (src_var >= 0 && !(ssa->var_info[src_var].type & MAY_BE_REF) + && (ssa->var_info[src_var].type & (MAY_BE_UNDEF|MAY_BE_ANY)) && ssa->vars[src_var].definition >= 0 && ssa->ops[ssa->vars[src_var].definition].result_def == src_var && ssa->ops[ssa->vars[src_var].definition].result_use < 0 @@ -1513,6 +1514,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) && src_var >= 0 && !(ssa->var_info[src_var].type & MAY_BE_REF) + && (ssa->var_info[src_var].type & (MAY_BE_UNDEF|MAY_BE_ANY)) && ssa->vars[src_var].definition >= 0 && ssa->ops[ssa->vars[src_var].definition].result_def == src_var && ssa->ops[ssa->vars[src_var].definition].result_use < 0 diff --git a/ext/opcache/tests/jit/assign_051.phpt b/ext/opcache/tests/jit/assign_051.phpt new file mode 100644 index 0000000000000..88264161d4af5 --- /dev/null +++ b/ext/opcache/tests/jit/assign_051.phpt @@ -0,0 +1,23 @@ +--TEST-- +JIT ASSIGN: incorrect assignment optimization +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "y" in %sassign_051.php:3 +Stack trace: +#0 %sassign_051.php(7): foo(0) +#1 {main} + thrown in %sassign_051.php on line 3 From 84a638a346f918e1ed6afc23f8ea1b7b7b90df1b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Feb 2022 12:20:40 +0300 Subject: [PATCH 146/227] Fix memory leak Fixes oss-fuzz #44685 --- .../resume_running_generator_error_002.phpt | 17 +++++++++++++++++ Zend/zend_generators.c | 1 + 2 files changed, 18 insertions(+) create mode 100644 Zend/tests/generators/errors/resume_running_generator_error_002.phpt diff --git a/Zend/tests/generators/errors/resume_running_generator_error_002.phpt b/Zend/tests/generators/errors/resume_running_generator_error_002.phpt new file mode 100644 index 0000000000000..e71e32a886dcc --- /dev/null +++ b/Zend/tests/generators/errors/resume_running_generator_error_002.phpt @@ -0,0 +1,17 @@ +--TEST-- +Memory leak when resume an already running generator +--FILE-- +send($g); +} +$gen = gen(); +try { + $gen->send($gen); +} catch (Throwable $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Cannot resume an already running generator diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 68c1865c0002e..2e6e22effab9d 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -924,6 +924,7 @@ ZEND_METHOD(Generator, send) root = zend_generator_get_current(generator); /* Put sent value in the target VAR slot, if it is used */ if (root->send_target) { + zval_ptr_dtor(root->send_target); ZVAL_COPY(root->send_target, value); } From 3198b8787bdbe08a893faf1164c48b9bd0f86562 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Feb 2022 17:15:07 +0300 Subject: [PATCH 147/227] JIT: Fix register allocation Fixes oss-fuzz #44689 --- ext/opcache/jit/zend_jit.c | 8 ++++++-- ext/opcache/tests/jit/reg_alloc_010.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/reg_alloc_010.phpt diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index bec0146afecbf..920020fb2d01b 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -145,8 +145,8 @@ static zend_bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ } while (phi); } - next_use = zend_ssa_next_use(ssa->ops, var, use); - if (next_use < 0) { + if (ssa->cfg.blocks[ssa->cfg.map[use]].loop_header > 0 + || (ssa->cfg.blocks[ssa->cfg.map[use]].flags & ZEND_BB_LOOP_HEADER)) { int b = ssa->cfg.map[use]; int prev_use = ssa->vars[var].use_chain; @@ -158,6 +158,10 @@ static zend_bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ } prev_use = zend_ssa_next_use(ssa->ops, var, prev_use); } + } + + next_use = zend_ssa_next_use(ssa->ops, var, use); + if (next_use < 0) { return 1; } else if (zend_ssa_is_no_val_use(op_array->opcodes + next_use, ssa->ops + next_use, var)) { return 1; diff --git a/ext/opcache/tests/jit/reg_alloc_010.phpt b/ext/opcache/tests/jit/reg_alloc_010.phpt new file mode 100644 index 0000000000000..d14b107295346 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_010.phpt @@ -0,0 +1,24 @@ +--TEST-- +Register Alloction 010: Missed store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $cnt in %sreg_alloc_010.php on line 3 + +Warning: Undefined variable $cnt in %sreg_alloc_010.php on line 3 +DONE \ No newline at end of file From 2753b454f3cff026f9220b57c1f87b025608b9d0 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 18 Feb 2022 13:43:19 +0100 Subject: [PATCH 148/227] [ci skip] Don't run GitHub actions on forks Closes GH-8111 Closes GH-8119 --- .github/workflows/close-needs-feedback.yml | 1 + .github/workflows/close-stale-prs.yml | 1 + .github/workflows/remove-needs-feedback.yml | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/close-needs-feedback.yml b/.github/workflows/close-needs-feedback.yml index 5af9133a44198..7197598f38c49 100644 --- a/.github/workflows/close-needs-feedback.yml +++ b/.github/workflows/close-needs-feedback.yml @@ -6,6 +6,7 @@ on: jobs: build: + if: github.repository_owner == 'php' runs-on: ubuntu-latest steps: - name: Close old issues that need feedback diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index 5aa178eed2c2c..e5fbacff5d152 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -6,6 +6,7 @@ on: jobs: stale: + if: github.repository_owner == 'php' runs-on: ubuntu-latest steps: - uses: actions/stale@v4 diff --git a/.github/workflows/remove-needs-feedback.yml b/.github/workflows/remove-needs-feedback.yml index 8f6dfc47f1664..fded33b442081 100644 --- a/.github/workflows/remove-needs-feedback.yml +++ b/.github/workflows/remove-needs-feedback.yml @@ -7,7 +7,7 @@ on: jobs: build: - if: "contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login" + if: "github.repository_owner == 'php' && contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login" runs-on: ubuntu-latest steps: - uses: actions-ecosystem/action-remove-labels@v1 From 19063a84f0e815b3efb65d8e5349247ecb291e17 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 17 Feb 2022 14:48:18 +0100 Subject: [PATCH 149/227] Fix null static_variable_ptr for uncalled fake closures Closes GH-8083 Closes GH-8109 --- NEWS | 2 ++ Zend/tests/gh8083.phpt | 22 ++++++++++++++++++++++ Zend/zend_closures.c | 7 +++++++ 3 files changed, 31 insertions(+) create mode 100644 Zend/tests/gh8083.phpt diff --git a/NEWS b/NEWS index d57dd9c37e884..cea996c4ebdf6 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed Haiku ZTS build. (David Carlier) . Fixed bug GH-8059 arginfo not regenerated for extension. (Remi) + . Fixed bug GH-8083 Segfault when dumping uncalled fake closure with static + variables. (ilutov) - GD: . Fixed libpng warning when loading interlaced images. (Brett) diff --git a/Zend/tests/gh8083.phpt b/Zend/tests/gh8083.phpt new file mode 100644 index 0000000000000..a98de47cbf375 --- /dev/null +++ b/Zend/tests/gh8083.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-8083 (var_dump() on closure with static variable segfaults) +--FILE-- + +--EXPECT-- +object(Closure)#1 (1) { + ["static"]=> + array(1) { + ["i"]=> + NULL + } +} diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index b5c0b47553248..0dab5537a3752 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -697,6 +697,13 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en } ZEND_MAP_PTR_INIT(closure->func.op_array.static_variables_ptr, &closure->func.op_array.static_variables); + } else if (func->op_array.static_variables) { + HashTable *ht = ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr); + + if (!ht) { + ht = zend_array_dup(func->op_array.static_variables); + ZEND_MAP_PTR_SET(closure->func.op_array.static_variables_ptr, ht); + } } /* Runtime cache is scope-dependent, so we cannot reuse it if the scope changed */ From fb70460d8e7593e32abdaaf8ae8849345d49c8fd Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 18 Feb 2022 13:21:22 +0100 Subject: [PATCH 150/227] Fix GH-7958: Nested CallbackFilterIterator is leaking memory We implement `zend_object_iterator_funcs.get_gc` for user iterators to avoid the memory leak. Closes GH-8107. --- NEWS | 1 + Zend/tests/gh7958.phpt | 43 ++++++++++++++++++++++++++++++++++++++++++ Zend/zend_interfaces.c | 10 +++++++++- Zend/zend_interfaces.h | 1 + 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/gh7958.phpt diff --git a/NEWS b/NEWS index cea996c4ebdf6..e25f3378ee165 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PHP NEWS . Fixed bug GH-8059 arginfo not regenerated for extension. (Remi) . Fixed bug GH-8083 Segfault when dumping uncalled fake closure with static variables. (ilutov) + . Fixed bug GH-7958 (Nested CallbackFilterIterator is leaking memory). (cmb) - GD: . Fixed libpng warning when loading interlaced images. (Brett) diff --git a/Zend/tests/gh7958.phpt b/Zend/tests/gh7958.phpt new file mode 100644 index 0000000000000..d9f3b8940a4a4 --- /dev/null +++ b/Zend/tests/gh7958.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-7958 (Nested CallbackFilterIterator is leaking memory) +--FILE-- +iterator = new ArrayIterator($data); + echo '-- c ' . spl_object_id($this) . "\n"; + } + + public function __destruct() + { + echo '-- d ' . spl_object_id($this) . "\n"; + } + + public function filter() + { + $this->iterator = new \CallbackFilterIterator($this->iterator, fn() => true); + $this->iterator->rewind(); + } +} + +$action = new Action(['a', 'b']); +$action->filter(); +$action->filter(); +print_r(iterator_to_array($action->iterator)); +$action = null; +gc_collect_cycles(); +echo "==DONE==\n"; +?> +--EXPECT-- +-- c 1 +Array +( + [0] => a + [1] => b +) +-- d 1 +==DONE== diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 54a2d61c38c29..b032d1d4e0b4c 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -182,6 +182,14 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter) } /* }}} */ +ZEND_API HashTable *zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n) +{ + zend_user_iterator *iter = (zend_user_iterator*)_iter; + *table = &iter->it.data; + *n = 1; + return NULL; +} + static const zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = { zend_user_it_dtor, zend_user_it_valid, @@ -190,7 +198,7 @@ static const zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = zend_user_it_move_forward, zend_user_it_rewind, zend_user_it_invalidate_current, - NULL, /* get_gc */ + zend_user_it_get_gc, }; /* {{{ zend_user_it_get_iterator */ diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h index 2799e2c438154..a8351ee9a7823 100644 --- a/Zend/zend_interfaces.h +++ b/Zend/zend_interfaces.h @@ -55,6 +55,7 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter); ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter); ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter); +ZEND_API HashTable *zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n); ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *iterator); ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref); From dfd2a80b69d469d879d60c12c1d9d9ca49cb3f76 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Thu, 17 Feb 2022 14:40:56 -0400 Subject: [PATCH 151/227] Fix #80909: crash with persistent connections in PDO_ODBC When we have a complex connection string (more than a DSN), PHP appends a UID and PWD if none are present and a username and password are called, so SQLDriverConnect works as expected. However, it seems spprintf doesn't allocate with persistence if required. As a result, it'll be considering leaking and crash PHP on free when a persistent connection is used. Closes GH-8110. --- NEWS | 4 ++++ ext/pdo_odbc/odbc_driver.c | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 00ba31fd248e2..ab565d58ae5bd 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,10 @@ PHP NEWS . Support for building against Oracle Client libraries 10.1 and 10.2 has been dropped. Oracle Client libraries 11.2 or newer are now required. +- PDO_ODBC: + . Fixed bug #80909 (crash with persistent connections in PDO_ODBC). (Calvin + Buckley) + - Standard: . net_get_interfaces() also reports wireless network interfaces on Windows. (Yurun) diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 4f59913937af2..840b7aeb8be3e 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -487,8 +487,16 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ /* Force UID and PWD to be set in the DSN */ if (dbh->username && *dbh->username && !strstr(dbh->data_source, "uid") && !strstr(dbh->data_source, "UID")) { - char *dsn; - spprintf(&dsn, 0, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password); + /* XXX: Do we check if password is null? */ + size_t new_dsn_size = strlen(dbh->data_source) + + strlen(dbh->username) + strlen(dbh->password) + + strlen(";UID=;PWD=") + 1; + char *dsn = pemalloc(new_dsn_size, dbh->is_persistent); + if (dsn == NULL) { + /* XXX: Do we inform the caller? */ + goto fail; + } + snprintf(dsn, new_dsn_size, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password); pefree((char*)dbh->data_source, dbh->is_persistent); dbh->data_source = dsn; } From ef80dcb80b9fd742f43844ec07588fc25896c507 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 21 Feb 2022 16:27:53 +0100 Subject: [PATCH 152/227] Fix GH-8074: Wrong type inference of range() result If either the first or second operand of `range()` may be a string, we must not exclude the possibility that the result may be an array of longs. Closes GH-8131. --- NEWS | 3 +++ ext/opcache/Optimizer/zend_func_info.c | 2 +- ext/opcache/tests/opt/gh8074.phpt | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/gh8074.phpt diff --git a/NEWS b/NEWS index 91fce7ad7342a..022cd11a62495 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,9 @@ PHP NEWS - MySQLnd: . Fixed bug GH-8058 (NULL pointer dereference in mysqlnd package). (Kamil Tekiela) +- OPcache: + . Fixed bug GH-8074 (Wrong type inference of range() result). (cmb) + - Zlib: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 84c9d20966cae..143717176b8d5 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -78,7 +78,7 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa || (t3 & (MAY_BE_DOUBLE|MAY_BE_STRING))) { tmp |= MAY_BE_ARRAY_OF_DOUBLE; } - if ((t1 & (MAY_BE_ANY-(MAY_BE_STRING|MAY_BE_DOUBLE))) && (t2 & (MAY_BE_ANY-(MAY_BE_STRING|MAY_BE_DOUBLE)))) { + if ((t1 & (MAY_BE_ANY-MAY_BE_DOUBLE)) && (t2 & (MAY_BE_ANY-MAY_BE_DOUBLE))) { if ((t3 & MAY_BE_ANY) != MAY_BE_DOUBLE) { tmp |= MAY_BE_ARRAY_OF_LONG; } diff --git a/ext/opcache/tests/opt/gh8074.phpt b/ext/opcache/tests/opt/gh8074.phpt new file mode 100644 index 0000000000000..86ec3449c476c --- /dev/null +++ b/ext/opcache/tests/opt/gh8074.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-8074 (Wrong type inference of range() result) +--FILE-- + +--EXPECT-- +int(2) +int(3) From 8a8533d263d981b9c24de7f0e54adb8441da72e0 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Tue, 22 Feb 2022 22:11:49 +0200 Subject: [PATCH 153/227] mb_check_encoding($str, '7bit') rejects strings with bytes over 0x7F This was the old behavior of mb_check_encoding() before 3e7acf901d, but yours truly broke it. If only we had more thorough tests at that time, this might not have slipped through the cracks. Thanks to divinity76 for the report. --- ext/mbstring/libmbfl/filters/mbfilter_7bit.c | 2 +- ext/mbstring/tests/other_encodings.phpt | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_7bit.c b/ext/mbstring/libmbfl/filters/mbfilter_7bit.c index dbf8993128472..a3a90c96f7a4a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_7bit.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_7bit.c @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_7bit_8bit = { int mbfl_filt_conv_7bit_any(int c, mbfl_convert_filter *filter) { - return (*filter->output_function)(c, filter->data); + return (*filter->output_function)(c < 0x80 ? c : MBFL_BAD_INPUT, filter->data); } diff --git a/ext/mbstring/tests/other_encodings.phpt b/ext/mbstring/tests/other_encodings.phpt index 321eccb247b6f..0cdaad43d8826 100644 --- a/ext/mbstring/tests/other_encodings.phpt +++ b/ext/mbstring/tests/other_encodings.phpt @@ -14,10 +14,11 @@ mb_substitute_character(0x25); var_dump(mb_convert_encoding("ABC", "7bit", "ASCII")); var_dump(mb_convert_encoding("\x80", "7bit", "ASCII")); var_dump(mb_convert_encoding("ABC", "8bit", "7bit")); +var_dump(mb_check_encoding(chr(255), '7bit')); echo "7bit done\n"; // "8bit" -var_dump(mb_convert_encoding("\x01\x00", "8bit", "UTF-16BE")); // codepoints over 0xFF are illegal or '8-bit' +var_dump(mb_convert_encoding("\x01\x00", "8bit", "UTF-16BE")); // codepoints over 0xFF are illegal for '8-bit' echo "8bit done\n"; // UCS-2 @@ -41,6 +42,7 @@ echo "UCS-4 done\n"; string(3) "ABC" string(1) "%" string(3) "ABC" +bool(false) 7bit done string(1) "%" 8bit done From 41461cf812d65f6b933ca01e12fcc0d29c713276 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 9 Feb 2022 19:01:05 +0100 Subject: [PATCH 154/227] Migrate CI to GitHub actions --- .github/actions/apt-x64/action.yml | 68 ++++++++ .github/actions/brew/action.yml | 34 ++++ .github/actions/configure-macos/action.yml | 71 ++++++++ .github/actions/configure-x64/action.yml | 81 +++++++++ .github/actions/install-linux/action.yml | 14 ++ .github/actions/mssql/action.yml | 14 ++ .github/actions/setup-x64/action.yml | 30 ++++ .github/actions/test-linux/action.yml | 27 +++ .github/actions/test-macos/action.yml | 20 +++ .github/scripts/setup-slapd.sh | 185 +++++++++++++++++++++ .github/workflows/push.yml | 82 +++++++++ azure-pipelines.yml | 21 +-- 12 files changed, 631 insertions(+), 16 deletions(-) create mode 100644 .github/actions/apt-x64/action.yml create mode 100644 .github/actions/brew/action.yml create mode 100644 .github/actions/configure-macos/action.yml create mode 100644 .github/actions/configure-x64/action.yml create mode 100644 .github/actions/install-linux/action.yml create mode 100644 .github/actions/mssql/action.yml create mode 100644 .github/actions/setup-x64/action.yml create mode 100644 .github/actions/test-linux/action.yml create mode 100644 .github/actions/test-macos/action.yml create mode 100755 .github/scripts/setup-slapd.sh create mode 100644 .github/workflows/push.yml diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml new file mode 100644 index 0000000000000..c21a34534aea8 --- /dev/null +++ b/.github/actions/apt-x64/action.yml @@ -0,0 +1,68 @@ +name: apt +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo apt-get update + sudo apt-get install \ + bison \ + re2c \ + locales \ + ldap-utils \ + openssl \ + slapd \ + language-pack-de \ + libgmp-dev \ + libicu-dev \ + libtidy-dev \ + libenchant-dev \ + libaspell-dev \ + libpspell-dev \ + libsasl2-dev \ + libxpm-dev \ + libzip-dev \ + libsqlite3-dev \ + libwebp-dev \ + libonig-dev \ + libkrb5-dev \ + libgssapi-krb5-2 \ + libcurl4-openssl-dev \ + libxml2-dev \ + libxslt1-dev \ + libpq-dev \ + libreadline-dev \ + libldap2-dev \ + libsodium-dev \ + libargon2-0-dev \ + libmm-dev \ + libsnmp-dev \ + postgresql \ + postgresql-contrib \ + snmpd \ + snmp-mibs-downloader \ + freetds-dev \ + unixodbc-dev \ + llvm \ + libc-client-dev \ + dovecot-core \ + dovecot-pop3d \ + dovecot-imapd \ + sendmail \ + firebird-dev \ + liblmdb-dev \ + libtokyocabinet-dev \ + libdb-dev \ + libqdbm-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev + mkdir /opt/oracle + wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip + unzip instantclient-basiclite-linuxx64.zip + wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-sdk-linuxx64.zip + unzip instantclient-sdk-linuxx64.zip + mv instantclient_*_* /opt/oracle/instantclient + # Interferes with libldap2 headers. + rm /opt/oracle/instantclient/sdk/include/ldap.h diff --git a/.github/actions/brew/action.yml b/.github/actions/brew/action.yml new file mode 100644 index 0000000000000..36b76392048d4 --- /dev/null +++ b/.github/actions/brew/action.yml @@ -0,0 +1,34 @@ +name: brew +runs: + using: composite + steps: + - shell: bash + run: | + set -x + brew install \ + pkg-config \ + autoconf \ + bison \ + re2c + brew install \ + openssl@1.1 \ + krb5 \ + bzip2 \ + enchant \ + libffi \ + libpng \ + webp \ + freetype \ + intltool \ + icu4c \ + libiconv \ + zlib \ + t1lib \ + gd \ + libzip \ + gmp \ + tidyp \ + libxml2 \ + libxslt \ + postgresql + brew link icu4c gettext --force diff --git a/.github/actions/configure-macos/action.yml b/.github/actions/configure-macos/action.yml new file mode 100644 index 0000000000000..852d8f62b68e1 --- /dev/null +++ b/.github/actions/configure-macos/action.yml @@ -0,0 +1,71 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export PATH="/usr/local/opt/bison/bin:$PATH" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/openssl@1.1/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/krb5/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxml2/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxslt/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/zlib/lib/pkgconfig" + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/icu4c/lib/pkgconfig" + ./buildconf --force + ./configure \ + --enable-option-checking=fatal \ + --prefix=/usr/local \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + --with-pgsql=/usr/local/opt/libpq \ + --with-pdo-pgsql=/usr/local/opt/libpq \ + --with-pdo-sqlite \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + --with-tidy=/usr/local/opt/tidyp \ + --with-libxml \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline=/usr/local/opt/readline \ + --enable-mbstring \ + --with-curl \ + --with-gettext=/usr/local/opt/gettext \ + --enable-sockets \ + --with-bz2=/usr/local/opt/bzip2 \ + --with-openssl \ + --with-gmp=/usr/local/opt/gmp \ + --with-iconv=/usr/local/opt/libiconv \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --with-pspell=/usr/local/opt/aspell \ + --with-kerberos \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + --enable-intl \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --enable-werror \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/configure-x64/action.yml b/.github/actions/configure-x64/action.yml new file mode 100644 index 0000000000000..73ce6322d25af --- /dev/null +++ b/.github/actions/configure-x64/action.yml @@ -0,0 +1,81 @@ +name: ./configure +inputs: + configurationParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + ./buildconf --force + ./configure \ + --enable-option-checking=fatal \ + --prefix=/usr \ + --enable-phpdbg \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + --with-pgsql \ + --with-pdo-pgsql \ + --with-pdo-sqlite \ + --enable-intl \ + --without-pear \ + --enable-gd \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --with-xpm \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --with-zlib-dir=/usr \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + --with-tidy \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --with-readline \ + --enable-mbstring \ + --with-curl \ + --with-gettext \ + --enable-sockets \ + --with-bz2 \ + --with-openssl \ + --with-gmp \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --with-pspell=/usr \ + --with-enchant=/usr \ + --with-kerberos \ + --enable-sysvmsg \ + --with-ffi \ + --enable-zend-test \ + --with-ldap \ + --with-ldap-sasl \ + --with-password-argon2 \ + --with-mhash \ + --with-sodium \ + --enable-dba \ + --with-cdb \ + --enable-flatfile \ + --enable-inifile \ + --with-tcadb \ + --with-lmdb \ + --with-qdbm \ + --with-snmp \ + --with-unixODBC \ + --with-imap \ + --with-kerberos \ + --with-imap-ssl \ + --with-pdo-odbc=unixODBC,/usr \ + --with-pdo-oci=shared,instantclient,/opt/oracle/instantclient \ + --with-oci8=shared,instantclient,/opt/oracle/instantclient \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.configurationParameters }} diff --git a/.github/actions/install-linux/action.yml b/.github/actions/install-linux/action.yml new file mode 100644 index 0000000000000..6db48f0ec3e1d --- /dev/null +++ b/.github/actions/install-linux/action.yml @@ -0,0 +1,14 @@ +name: Install +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo make install + sudo mkdir /etc/php.d + sudo chmod 777 /etc/php.d + echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini + echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini + echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini + echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini diff --git a/.github/actions/mssql/action.yml b/.github/actions/mssql/action.yml new file mode 100644 index 0000000000000..894380644c1ea --- /dev/null +++ b/.github/actions/mssql/action.yml @@ -0,0 +1,14 @@ +name: Create mssql container +runs: + using: composite + steps: + - shell: bash + run: | + set -x + docker run \ + -e "ACCEPT_EULA=Y" \ + -e "SA_PASSWORD=" \ + -p 1433:1433 \ + --name sql1 \ + -h sql1 \ + -d mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04 diff --git a/.github/actions/setup-x64/action.yml b/.github/actions/setup-x64/action.yml new file mode 100644 index 0000000000000..6cec51d4c8079 --- /dev/null +++ b/.github/actions/setup-x64/action.yml @@ -0,0 +1,30 @@ +name: Setup +runs: + using: composite + steps: + - shell: bash + run: | + set -x + + sudo service mysql start + sudo service postgresql start + sudo service slapd start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + # Ensure local_infile tests can run. + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';" + sudo -u postgres psql -c "CREATE DATABASE test;" + docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U SA -P "" -Q "create login pdo_test with password='password', check_policy=off; create user pdo_test for login pdo_test; grant alter, control to pdo_test;" + sudo locale-gen de_DE + + ./.github/scripts/setup-slapd.sh + + sudo cp ext/snmp/tests/snmpd.conf /etc/snmp + sudo cp ext/snmp/tests/bigtest /etc/snmp + sudo service snmpd restart + + sudo groupadd -g 5000 vmail + sudo useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail + sudo cp ext/imap/tests/setup/dovecot.conf /etc/dovecot/dovecot.conf + sudo cp ext/imap/tests/setup/dovecotpass /etc/dovecot/dovecotpass + sudo service dovecot restart diff --git a/.github/actions/test-linux/action.yml b/.github/actions/test-linux/action.yml new file mode 100644 index 0000000000000..c7dab609820dd --- /dev/null +++ b/.github/actions/test-linux/action.yml @@ -0,0 +1,27 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export MYSQL_TEST_USER=root + export MYSQL_TEST_PASSWD=root + export PDO_MYSQL_TEST_DSN="mysql:host=localhost;dbname=test" + export PDO_MYSQL_TEST_USER=root + export PDO_MYSQL_TEST_PASS=root + export PDO_DBLIB_TEST_DSN="dblib:host=127.0.0.1;dbname=master;version=7.0" + export PDO_DBLIB_TEST_USER="pdo_test" + export PDO_DBLIB_TEST_PASS="password" + export SKIP_IO_CAPTURE_TESTS=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -j$(/usr/bin/nproc) \ + -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 diff --git a/.github/actions/test-macos/action.yml b/.github/actions/test-macos/action.yml new file mode 100644 index 0000000000000..99ac49b268c76 --- /dev/null +++ b/.github/actions/test-macos/action.yml @@ -0,0 +1,20 @@ +name: Test +inputs: + runTestsParameters: + default: '' + required: false +runs: + using: composite + steps: + - shell: bash + run: | + set -x + export SKIP_IO_CAPTURE_TESTS=1 + export CI_NO_IPV6=1 + sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + -j$(sysctl -n hw.ncpu) \ + -g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 diff --git a/.github/scripts/setup-slapd.sh b/.github/scripts/setup-slapd.sh new file mode 100755 index 0000000000000..7ea3cb33b3d0e --- /dev/null +++ b/.github/scripts/setup-slapd.sh @@ -0,0 +1,185 @@ +#!/bin/sh +set -ev + +# Create TLS certificate +sudo mkdir -p /etc/ldap/ssl + +alt_names() { + ( + ( + (hostname && hostname -a && hostname -A && hostname -f) | + xargs -n 1 | + sort -u | + sed -e 's/\(\S\+\)/DNS:\1/g' + ) && ( + (hostname -i && hostname -I && echo "127.0.0.1 ::1") | + xargs -n 1 | + sort -u | + sed -e 's/\(\S\+\)/IP:\1/g' + ) + ) | paste -d, -s +} + +sudo openssl req -newkey rsa:4096 -x509 -nodes -days 3650 \ + -out /etc/ldap/ssl/server.crt -keyout /etc/ldap/ssl/server.key \ + -subj "/C=US/ST=Arizona/L=Localhost/O=localhost/CN=localhost" \ + -addext "subjectAltName = `alt_names`" + +sudo chown -R openldap:openldap /etc/ldap/ssl + +# Display the TLS certificate (should be world readable) +openssl x509 -noout -text -in /etc/ldap/ssl/server.crt + +# Point to the certificate generated +if ! grep -q 'TLS_CACERT \/etc\/ldap\/ssl\/server.crt' /etc/ldap/ldap.conf; then + sudo sed -e 's|^\s*TLS_CACERT|# TLS_CACERT|' -i /etc/ldap/ldap.conf + echo 'TLS_CACERT /etc/ldap/ssl/server.crt' | sudo tee -a /etc/ldap/ldap.conf +fi + +# Configure LDAP protocols to serve. +sudo sed -e 's|^\s*SLAPD_SERVICES\s*=.*$|SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"|' -i /etc/default/slapd + +# Configure LDAP database. +DBDN=`sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(&(olcRootDN=*)(olcSuffix=*))' dn | grep -i '^dn:' | sed -e 's/^dn:\s*//'`; + +sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif + +sudo service slapd restart + +sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF +dn: $DBDN +changetype: modify +replace: olcSuffix +olcSuffix: dc=my-domain,dc=com +- +replace: olcRootDN +olcRootDN: cn=Manager,dc=my-domain,dc=com +- +replace: olcRootPW +olcRootPW: secret + +dn: cn=config +changetype: modify +add: olcTLSCACertificateFile +olcTLSCACertificateFile: /etc/ldap/ssl/server.crt +- +add: olcTLSCertificateFile +olcTLSCertificateFile: /etc/ldap/ssl/server.crt +- +add: olcTLSCertificateKeyFile +olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key +- +add: olcTLSVerifyClient +olcTLSVerifyClient: never +- +add: olcAuthzRegexp +olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com +- +replace: olcLogLevel +olcLogLevel: -1 + +dn: cn=module{0},cn=config +changetype: modify +add: olcModuleLoad +olcModuleLoad: sssvlv +- +add: olcModuleLoad +olcModuleLoad: ppolicy +- +add: olcModuleLoad +olcModuleLoad: dds +EOF + +sudo service slapd restart + +sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// << EOF +dn: olcOverlay=sssvlv,$DBDN +objectClass: olcOverlayConfig +objectClass: olcSssVlvConfig +olcOverlay: sssvlv +olcSssVlvMax: 10 +olcSssVlvMaxKeys: 5 + +dn: olcOverlay=ppolicy,$DBDN +objectClass: olcOverlayConfig +objectClass: olcPPolicyConfig +olcOverlay: ppolicy +### This would clutter our DIT and make tests to fail, while ppolicy does not +### seem to work as we expect (it does not seem to provide expected controls) +## olcPPolicyDefault: cn=default,ou=pwpolicies,dc=my-domain,dc=com +## olcPPolicyHashCleartext: FALSE +## olcPPolicyUseLockout: TRUE + +dn: olcOverlay=dds,$DBDN +objectClass: olcOverlayConfig +objectClass: olcDdsConfig +olcOverlay: dds +EOF + +sudo service slapd restart + +sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// << EOF +dn: $DBDN +changetype: modify +add: olcDbIndex +olcDbIndex: entryExpireTimestamp eq +EOF + +sudo service slapd restart + +ldapadd -H ldapi:/// -D cn=Manager,dc=my-domain,dc=com -w secret <- + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + uses: ./.github/actions/setup-x64 + - name: Test + uses: ./.github/actions/test-linux + - name: Test Tracing JIT + uses: ./.github/actions/test-linux + with: + runTestsParameters: -d zend_extension=opcache.so -d opcache.jit_buffer_size=16M + MACOS_DEBUG_NTS: + runs-on: macos-10.15 + steps: + - name: git checkout + uses: actions/checkout@v2 + - name: brew + uses: ./.github/actions/brew + - name: ./configure + uses: ./.github/actions/configure-macos + with: + configurationParameters: --enable-debug --disable-zts + - name: make + run: |- + export PATH="/usr/local/opt/bison/bin:$PATH" + make -j$(sysctl -n hw.logicalcpu) >/dev/null + - name: make install + run: sudo make install + - name: Test + uses: ./.github/actions/test-macos + - name: Test Tracing JIT + uses: ./.github/actions/test-macos + with: + runTestsParameters: >- + -d zend_extension=opcache.so + -d opcache.protect_memory=1 + -d opcache.jit_buffer_size=16M diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4f871281fd5c6..a8fc6bcbb70bc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -22,22 +22,11 @@ schedules: - master jobs: - - template: azure/job.yml - parameters: - configurationName: DEBUG_NTS - configurationParameters: '--enable-debug --disable-zts' - - template: azure/job.yml - parameters: - configurationName: RELEASE_ZTS - configurationParameters: '--disable-debug --enable-zts' - - template: azure/i386/job.yml - parameters: - configurationName: I386_DEBUG_ZTS - configurationParameters: '--enable-debug --enable-zts' - - template: azure/macos/job.yml - parameters: - configurationName: MACOS_DEBUG_NTS - configurationParameters: '--enable-debug --disable-zts' + # Azure pipelines don't work atm + # - template: azure/i386/job.yml + # parameters: + # configurationName: I386_DEBUG_ZTS + # configurationParameters: '--enable-debug --enable-zts' - ${{ if eq(variables['Build.Reason'], 'Schedule') }}: - template: azure/job.yml parameters: From bbc111ed3f6062fa1c1bb30865e8c4a9e1ff90ba Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Wed, 23 Feb 2022 22:56:55 +0200 Subject: [PATCH 155/227] Add NEWS entry for recent MBString bugfix (re: '7bit' encoding) Thanks to Kamil Tekiela for mentioning that this should be done. --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 7ab4801312689..75da613024740 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,9 @@ PHP NEWS . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) . Fixed bug GH-7980 (Unexpected result for iconv_mime_decode). (cmb) +- MBString: + . Fixed bug GH-8128 (mb_check_encoding wrong result for 7bit). (alexdowad) + - MySQLnd: . Fixed bug GH-8058 (NULL pointer dereference in mysqlnd package). (Kamil Tekiela) From 1e8d35adaba196caa0173de136888952efa7c461 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 23 Feb 2022 20:25:29 +0100 Subject: [PATCH 156/227] GitHub actions test with firebird, dblib and werror --- .github/actions/configure-x64/action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/actions/configure-x64/action.yml b/.github/actions/configure-x64/action.yml index 73ce6322d25af..f9b774218f4ef 100644 --- a/.github/actions/configure-x64/action.yml +++ b/.github/actions/configure-x64/action.yml @@ -78,4 +78,7 @@ runs: --with-oci8=shared,instantclient,/opt/oracle/instantclient \ --with-config-file-path=/etc \ --with-config-file-scan-dir=/etc/php.d \ + --with-pdo-firebird \ + --with-pdo-dblib \ + --enable-werror \ ${{ inputs.configurationParameters }} From e80ec3fe165a9db44561e9943e0d3020b33e245f Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 23 Feb 2022 22:46:10 +0100 Subject: [PATCH 157/227] Mark failing JIT test with XFAIL --- ext/opcache/tests/jit/assign_dim_op_007.phpt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/opcache/tests/jit/assign_dim_op_007.phpt b/ext/opcache/tests/jit/assign_dim_op_007.phpt index e8708a1255131..cf7125c2a4554 100644 --- a/ext/opcache/tests/jit/assign_dim_op_007.phpt +++ b/ext/opcache/tests/jit/assign_dim_op_007.phpt @@ -5,6 +5,8 @@ opcache.enable=1 opcache.enable_cli=1 opcache.file_update_protection=0 opcache.jit_buffer_size=1M +--XFAIL-- +See https://github.com/php/php-src/issues/8147 --FILE-- Date: Wed, 23 Feb 2022 19:23:00 -0500 Subject: [PATCH 158/227] Fixes infinite recursion introduced by patch to SplFixedArray (#8105) Closes GH-8079 Track whether the spl_fixedarray was modified since the last call to get_properties --- ext/spl/spl_fixedarray.c | 25 +++++++++++++++++++++ ext/spl/tests/fixedarray_023.phpt | 36 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 ext/spl/tests/fixedarray_023.phpt diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index ec53935ac9d2e..cdf628cfb4ee6 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -42,6 +42,8 @@ ZEND_GET_MODULE(spl_fixedarray) typedef struct _spl_fixedarray { zend_long size; zval *elements; + /* True if this was modified after the last call to get_properties or the hash table wasn't rebuilt. */ + bool should_rebuild_properties; } spl_fixedarray; typedef struct _spl_fixedarray_object { @@ -104,6 +106,7 @@ static void spl_fixedarray_init(spl_fixedarray *array, zend_long size) array->size = 0; /* reset size in case ecalloc() fails */ array->elements = safe_emalloc(size, sizeof(zval), 0); array->size = size; + array->should_rebuild_properties = true; spl_fixedarray_init_elems(array, 0, size); } else { spl_fixedarray_default_ctor(array); @@ -166,6 +169,7 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size) /* nothing to do */ return; } + array->should_rebuild_properties = true; /* first initialization */ if (array->size == 0) { @@ -205,6 +209,22 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) HashTable *ht = zend_std_get_properties(obj); if (!spl_fixedarray_empty(&intern->array)) { + /* + * Usually, the reference count of the hash table is 1, + * except during cyclic reference cycles. + * + * Maintain the DEBUG invariant that a hash table isn't modified during iteration, + * and avoid unnecessary work rebuilding a hash table for unmodified properties. + * + * See https://github.com/php/php-src/issues/8079 and ext/spl/tests/fixedarray_022.phpt + * Also see https://github.com/php/php-src/issues/8044 for alternate considered approaches. + */ + if (!intern->array.should_rebuild_properties) { + /* Return the same hash table so that recursion cycle detection works in internal functions. */ + return ht; + } + intern->array.should_rebuild_properties = false; + zend_long j = zend_hash_num_elements(ht); if (GC_REFCOUNT(ht) > 1) { @@ -354,6 +374,9 @@ static zval *spl_fixedarray_object_read_dimension(zend_object *object, zval *off } return &EG(uninitialized_zval); } + if (type != BP_VAR_IS && type != BP_VAR_R) { + intern->array.should_rebuild_properties = true; + } return spl_fixedarray_object_read_dimension_helper(intern, offset); } @@ -378,6 +401,7 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object * zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { + intern->array.should_rebuild_properties = true; /* Fix #81429 */ zval *ptr = &(intern->array.elements[index]); zval tmp; @@ -425,6 +449,7 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object * zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { + intern->array.should_rebuild_properties = true; zval_ptr_dtor(&(intern->array.elements[index])); ZVAL_NULL(&intern->array.elements[index]); } diff --git a/ext/spl/tests/fixedarray_023.phpt b/ext/spl/tests/fixedarray_023.phpt new file mode 100644 index 0000000000000..1d60a2ce6d9f7 --- /dev/null +++ b/ext/spl/tests/fixedarray_023.phpt @@ -0,0 +1,36 @@ +--TEST-- +SPL: FixedArray: Infinite loop in var_export bugfix +--FILE-- + +--EXPECTF-- +Warning: var_export does not handle circular references in %s on line 8 + +Warning: var_export does not handle circular references in %s on line 8 +SplFixedArray::__set_state(array( + 0 => NAN, + 1 => 0.0, + 2 => NULL, + 3 => NULL, +)) +object(SplFixedArray)#2 (4) refcount(6){ + [0]=> + float(NAN) + [1]=> + float(-0) + [2]=> + *RECURSION* + [3]=> + *RECURSION* +} \ No newline at end of file From 33cd61c9045ae8675448456cdda6fb244b2efa01 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 23 Feb 2022 14:14:46 +0100 Subject: [PATCH 159/227] Fix GH-8140: Wrong first class callable by name optimization When optimizing by name function calls, we must not replace `CALLABLE_CONVERT` opcodes, but have to keep them. Closes GH-8144. --- NEWS | 1 + Zend/Optimizer/optimize_func_calls.c | 8 ++++++-- ext/opcache/tests/opt/gh8140a.phpt | 16 ++++++++++++++++ ext/opcache/tests/opt/gh8140b.phpt | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/opt/gh8140a.phpt create mode 100644 ext/opcache/tests/opt/gh8140b.phpt diff --git a/NEWS b/NEWS index 75da613024740..ea8ee5879e72b 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PHP NEWS variables. (ilutov) . Fixed bug GH-7958 (Nested CallbackFilterIterator is leaking memory). (cmb) . Fixed bug GH-8074 (Wrong type inference of range() result). (cmb) + . Fixed bug GH-8140 (Wrong first class callable by name optimization). (cmb) - GD: . Fixed libpng warning when loading interlaced images. (Brett) diff --git a/Zend/Optimizer/optimize_func_calls.c b/Zend/Optimizer/optimize_func_calls.c index e2e16f90b8654..351010177f630 100644 --- a/Zend/Optimizer/optimize_func_calls.c +++ b/Zend/Optimizer/optimize_func_calls.c @@ -200,14 +200,18 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); literal_dtor(&ZEND_OP2_LITERAL(fcall)); fcall->op2.constant = fcall->op2.constant + 1; - opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + if (opline->opcode != ZEND_CALLABLE_CONVERT) { + opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + } } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); literal_dtor(&op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant + 2]); fcall->op2.constant = fcall->op2.constant + 1; - opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + if (opline->opcode != ZEND_CALLABLE_CONVERT) { + opline->opcode = zend_get_call_op(fcall, call_stack[call].func); + } } else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL || fcall->opcode == ZEND_INIT_METHOD_CALL || fcall->opcode == ZEND_NEW) { diff --git a/ext/opcache/tests/opt/gh8140a.phpt b/ext/opcache/tests/opt/gh8140a.phpt new file mode 100644 index 0000000000000..03f097c77c5ce --- /dev/null +++ b/ext/opcache/tests/opt/gh8140a.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-8140 (Wrong first class callable by name optimization) +--FILE-- + +--EXPECT-- +Hello, world! diff --git a/ext/opcache/tests/opt/gh8140b.phpt b/ext/opcache/tests/opt/gh8140b.phpt new file mode 100644 index 0000000000000..60da3a79e1408 --- /dev/null +++ b/ext/opcache/tests/opt/gh8140b.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-8140 (Wrong first class callable by name optimization) +--FILE-- + +--EXPECT-- +Hello, world! From 67dd48fbd5e0b081f95299244d889e30fe6dbf06 Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Thu, 24 Feb 2022 15:44:09 +0100 Subject: [PATCH 160/227] fix [-Wstrict-prototypes] buid warnings --- Zend/zend_cpuinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index fcaf33d5e721c..ebfbab799795d 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -208,7 +208,7 @@ static inline int zend_cpu_supports_avx2(void) { /* __builtin_cpu_supports has pclmul from gcc9 */ #if PHP_HAVE_BUILTIN_CPU_SUPPORTS && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) ZEND_NO_SANITIZE_ADDRESS -static inline int zend_cpu_supports_pclmul() { +static inline int zend_cpu_supports_pclmul(void) { #if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); #endif From 8c60e21515a566f500f21e36cfc572ab0918df22 Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Thu, 24 Feb 2022 16:14:47 +0100 Subject: [PATCH 161/227] Avoid possible [-Wstrict-prototypes] build warnings --- Zend/zend_alloc.c | 2 +- Zend/zend_extensions.c | 4 ++-- Zend/zend_gc.c | 2 +- ext/standard/crc32_x86.c | 2 +- main/fastcgi.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index f91c38bb9b308..9635068a6bb86 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2816,7 +2816,7 @@ static void *tracked_realloc(void *ptr, size_t new_size) { return ptr; } -static void tracked_free_all() { +static void tracked_free_all(void) { HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs; zend_ulong h; ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) { diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index 4d4b1ffe09b41..8e49866d2305e 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -203,7 +203,7 @@ static int zend_extension_startup(zend_extension *extension) } -void zend_startup_extensions_mechanism() +void zend_startup_extensions_mechanism(void) { /* Startup extensions mechanism */ zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1); @@ -212,7 +212,7 @@ void zend_startup_extensions_mechanism() } -void zend_startup_extensions() +void zend_startup_extensions(void) { zend_llist_apply_with_del(&zend_extensions, (int (*)(void *)) zend_extension_startup); } diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index de7353013f0b4..3319b7aa34e64 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1695,7 +1695,7 @@ ZEND_API void zend_get_gc_buffer_grow(zend_get_gc_buffer *gc_buffer) { gc_buffer->cur = gc_buffer->start + old_capacity; } -static void zend_get_gc_buffer_release() { +static void zend_get_gc_buffer_release(void) { zend_get_gc_buffer *gc_buffer = &EG(get_gc_buffer); efree(gc_buffer->start); gc_buffer->start = gc_buffer->end = gc_buffer->cur = NULL; diff --git a/ext/standard/crc32_x86.c b/ext/standard/crc32_x86.c index eec023264002f..fdcbed8782557 100644 --- a/ext/standard/crc32_x86.c +++ b/ext/standard/crc32_x86.c @@ -323,7 +323,7 @@ typedef size_t (*crc32_x86_simd_func_t)(X86_CRC32_TYPE type, uint32_t *crc, cons ZEND_NO_SANITIZE_ADDRESS ZEND_ATTRIBUTE_UNUSED /* clang mistakenly warns about this */ -static crc32_x86_simd_func_t resolve_crc32_x86_simd_update() { +static crc32_x86_simd_func_t resolve_crc32_x86_simd_update(void) { if (zend_cpu_supports_sse42() && zend_cpu_supports_pclmul()) { return crc32_sse42_pclmul_update; } diff --git a/main/fastcgi.c b/main/fastcgi.c index e3acd9ac3a186..6020cf4fda9a4 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -1742,7 +1742,7 @@ void fcgi_free_mgmt_var_cb(zval *zv) pefree(Z_STR_P(zv), 1); } -const char *fcgi_get_last_client_ip() +const char *fcgi_get_last_client_ip(void) { static char str[INET6_ADDRSTRLEN]; From 8b8cf8f8f507c503282465264e2f9e0f72ef4b03 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 28 Feb 2022 10:58:14 +0300 Subject: [PATCH 162/227] JIT: Fix register clobbering --- ext/opcache/jit/zend_jit_arm64.dasc | 20 ++++++++++---------- ext/opcache/tests/jit/assign_dim_op_007.phpt | 2 -- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 6d6bc471ec27e..31b5260605430 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3816,7 +3816,7 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(op1_def_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL op1_def_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL op1_def_addr, val, TMP2, TMP1 } } else { uint64_t val = 0xc3e0000000000000; @@ -3824,7 +3824,7 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(op1_def_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL op1_def_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL op1_def_addr, val, TMP2, TMP1 } } if (Z_MODE(op1_def_addr) == IS_MEM_ZVAL) { @@ -4155,7 +4155,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(res_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL res_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL res_addr, val, TMP2, TMP1 } break; } else if (opcode == ZEND_SUB) { @@ -4164,7 +4164,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, | LOAD_64BIT_VAL TMP1, val | fmov Rd(Z_REG(res_addr)-ZREG_V0), TMP1 } else { - | SET_ZVAL_LVAL res_addr, val, REG0, TMP1 + | SET_ZVAL_LVAL res_addr, val, TMP2, TMP1 } break; } @@ -12942,20 +12942,20 @@ static int zend_jit_incdec_obj(dasm_State **Dst, |3: if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_POST_INC_OBJ) { uint64_t val = 0x43e0000000000000; - | LOAD_64BIT_VAL REG0, val - | SET_ZVAL_LVAL_FROM_REG var_addr, REG0, TMP1 + | LOAD_64BIT_VAL TMP2, val + | SET_ZVAL_LVAL_FROM_REG var_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO var_addr, IS_DOUBLE, TMP1w, TMP2 if (opline->opcode == ZEND_PRE_INC_OBJ && opline->result_type != IS_UNUSED) { - | SET_ZVAL_LVAL_FROM_REG res_addr, REG0, TMP1 + | SET_ZVAL_LVAL_FROM_REG res_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO res_addr, IS_DOUBLE, TMP1w, TMP2 } } else { uint64_t val = 0xc3e0000000000000; - | LOAD_64BIT_VAL REG0, val - | SET_ZVAL_LVAL_FROM_REG var_addr, REG0, TMP1 + | LOAD_64BIT_VAL TMP2, val + | SET_ZVAL_LVAL_FROM_REG var_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO var_addr, IS_DOUBLE, TMP1w, TMP2 if (opline->opcode == ZEND_PRE_DEC_OBJ && opline->result_type != IS_UNUSED) { - | SET_ZVAL_LVAL_FROM_REG res_addr, REG0, TMP1 + | SET_ZVAL_LVAL_FROM_REG res_addr, TMP2, TMP1 | SET_ZVAL_TYPE_INFO res_addr, IS_DOUBLE, TMP1w, TMP2 } } diff --git a/ext/opcache/tests/jit/assign_dim_op_007.phpt b/ext/opcache/tests/jit/assign_dim_op_007.phpt index cf7125c2a4554..e8708a1255131 100644 --- a/ext/opcache/tests/jit/assign_dim_op_007.phpt +++ b/ext/opcache/tests/jit/assign_dim_op_007.phpt @@ -5,8 +5,6 @@ opcache.enable=1 opcache.enable_cli=1 opcache.file_update_protection=0 opcache.jit_buffer_size=1M ---XFAIL-- -See https://github.com/php/php-src/issues/8147 --FILE-- Date: Mon, 28 Feb 2022 11:44:22 +0300 Subject: [PATCH 163/227] Fixed incorrect DCE for FREE Fixes oss-fuzz #44863 --- ext/opcache/Optimizer/dce.c | 4 +++- ext/opcache/tests/opt/dce_013.phpt | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/dce_013.phpt diff --git a/ext/opcache/Optimizer/dce.c b/ext/opcache/Optimizer/dce.c index 47f5f271062e2..f945856dfb293 100644 --- a/ext/opcache/Optimizer/dce.c +++ b/ext/opcache/Optimizer/dce.c @@ -391,7 +391,9 @@ static zend_bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) { } /* We mark FREEs as dead, but they're only really dead if the destroyed var is dead */ - if (opline->opcode == ZEND_FREE && may_be_refcounted(ssa->var_info[ssa_op->op1_use].type) + if (opline->opcode == ZEND_FREE + && ((ssa->var_info[ssa_op->op1_use].type & (MAY_BE_REF|MAY_BE_ANY|MAY_BE_UNDEF)) == 0 + || may_be_refcounted(ssa->var_info[ssa_op->op1_use].type)) && !is_var_dead(ctx, ssa_op->op1_use)) { return 0; } diff --git a/ext/opcache/tests/opt/dce_013.phpt b/ext/opcache/tests/opt/dce_013.phpt new file mode 100644 index 0000000000000..ac5211498f6d1 --- /dev/null +++ b/ext/opcache/tests/opt/dce_013.phpt @@ -0,0 +1,12 @@ +--TEST-- +Incorrect DCE of FREE +--FILE-- + +DONE +--EXPECT-- +DONE From 0d266a24d61dd93bba4ed8837163f099b0ee0374 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 16 Feb 2022 12:32:17 +0100 Subject: [PATCH 164/227] Fix GH-8080: ReflectionClass::getConstants() depends on def. order When we need to evaluate constant ASTs, we always have to do that in the scope where the constant has been defined, which may be a parent of the `ReflectionClass`'s scope. Closes GH-8106. --- NEWS | 4 ++++ ext/reflection/php_reflection.c | 4 ++-- ext/reflection/tests/gh8080.phpt | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 ext/reflection/tests/gh8080.phpt diff --git a/NEWS b/NEWS index 022cd11a62495..7d8806639f1ba 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,10 @@ PHP NEWS - OPcache: . Fixed bug GH-8074 (Wrong type inference of range() result). (cmb) +- Reflection: + . Fixed bug GH-8080 (ReflectionClass::getConstants() depends on def. order). + (cmb) + - Zlib: . Fixed bug GH-7953 (ob_clean() only does not set Content-Encoding). (cmb) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index c2c379be2823a..0210fa5ef3fd5 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4454,7 +4454,7 @@ ZEND_METHOD(ReflectionClass, getConstants) array_init(return_value); ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, constant) { - if (UNEXPECTED(zval_update_constant_ex(&constant->value, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&constant->value, constant->ce) != SUCCESS)) { RETURN_THROWS(); } @@ -4511,7 +4511,7 @@ ZEND_METHOD(ReflectionClass, getConstant) GET_REFLECTION_OBJECT_PTR(ce); ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { - if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&c->value, c->ce) != SUCCESS)) { RETURN_THROWS(); } } ZEND_HASH_FOREACH_END(); diff --git a/ext/reflection/tests/gh8080.phpt b/ext/reflection/tests/gh8080.phpt new file mode 100644 index 0000000000000..c9c861051ab85 --- /dev/null +++ b/ext/reflection/tests/gh8080.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-8080 (ReflectionClass::getConstants() depends on def. order) +--FILE-- + 'Test', + ]; + private const TEST = 'test'; +} + +class B extends A {} + +$r = new ReflectionClass(B::class); +var_dump( + $r->getConstants(), + $r->getConstant("LIST") +); +?> +--EXPECT-- +array(1) { + ["LIST"]=> + array(1) { + ["test"]=> + string(4) "Test" + } +} +array(1) { + ["test"]=> + string(4) "Test" +} From ac8a53cab1297f8546146f93f3fa7897e396b047 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 28 Feb 2022 13:48:53 +0300 Subject: [PATCH 165/227] JIT: Fix register allocator Fixes oss-fuzz #44916 --- ext/opcache/jit/zend_jit_trace.c | 16 +++++++++++++++ ext/opcache/jit/zend_jit_x86.dasc | 8 ++++++++ ext/opcache/tests/jit/reg_alloc_011.phpt | 25 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 ext/opcache/tests/jit/reg_alloc_011.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 223792e2eae92..5244b1eaa315b 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -6389,6 +6389,22 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (p->stop == ZEND_JIT_TRACE_STOP_LOOP || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { + if (ra) { + zend_ssa_phi *phi = ssa->blocks[1].phis; + + while (phi) { + if (ra[phi->ssa_var] + && ra[phi->sources[1]] + && STACK_MEM_TYPE(stack, phi->var) != STACK_TYPE(stack, phi->var) + && (ra[phi->ssa_var]->flags & (ZREG_LOAD|ZREG_STORE)) == 0 + && (ra[phi->sources[1]]->flags & (ZREG_LOAD|ZREG_STORE)) == 0) { + /* Store actual type to memory to avoid deoptimization mistakes */ + /* TODO: Alternatively, we may try to update alredy generated deoptimization info */ + zend_jit_store_var_type(&dasm_state, phi->var, STACK_TYPE(stack, phi->var)); + } + phi = phi->next; + } + } if (p->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { if ((t->flags & ZEND_JIT_TRACE_USES_INITIAL_IP) && !zend_jit_set_ip(&dasm_state, p->opline)) { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 462ba36168485..0539165687afb 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3867,6 +3867,14 @@ static int zend_jit_store_var(dasm_State **Dst, uint32_t info, int var, zend_reg return zend_jit_spill_store(Dst, src, dst, info, set_type); } +static int zend_jit_store_var_type(dasm_State **Dst, int var, uint8_t type) +{ + zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var)); + + | SET_ZVAL_TYPE_INFO dst, type + return 1; +} + static int zend_jit_store_var_if_necessary(dasm_State **Dst, int var, zend_jit_addr src, uint32_t info) { if (Z_MODE(src) == IS_REG && Z_STORE(src)) { diff --git a/ext/opcache/tests/jit/reg_alloc_011.phpt b/ext/opcache/tests/jit/reg_alloc_011.phpt new file mode 100644 index 0000000000000..f628adf7795ae --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_011.phpt @@ -0,0 +1,25 @@ +--TEST-- +Register Alloction 011: Missed type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file From 0a5162b2b61fc9a11d2a6df3afce2d340bb3c4ab Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 28 Feb 2022 13:55:25 +0300 Subject: [PATCH 166/227] Allow setting full type info --- ext/opcache/jit/zend_jit_arm64.dasc | 2 +- ext/opcache/jit/zend_jit_x86.dasc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 2b6394d68551b..b29a69aa65075 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3560,7 +3560,7 @@ static int zend_jit_store_var(dasm_State **Dst, uint32_t info, int var, zend_reg return zend_jit_spill_store(Dst, src, dst, info, set_type); } -static int zend_jit_store_var_type(dasm_State **Dst, int var, uint8_t type) +static int zend_jit_store_var_type(dasm_State **Dst, int var, uint32_t type) { zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var)); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index c073c5d873d72..ea9c7ba6eedd8 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3900,7 +3900,7 @@ static int zend_jit_store_var(dasm_State **Dst, uint32_t info, int var, zend_reg return zend_jit_spill_store(Dst, src, dst, info, set_type); } -static int zend_jit_store_var_type(dasm_State **Dst, int var, uint8_t type) +static int zend_jit_store_var_type(dasm_State **Dst, int var, uint32_t type) { zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var)); From 70f7e7d83fe213712a0828ae4872daaed03a2544 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 28 Feb 2022 15:43:03 +0300 Subject: [PATCH 167/227] JIT: Fix memory leak Fixes oss-fuzz #44920 --- ext/opcache/jit/zend_jit_disasm_x86.c | 1 + ext/opcache/jit/zend_jit_helpers.c | 14 +++++++++ ext/opcache/jit/zend_jit_x86.dasc | 28 +++++++++++++++--- ext/opcache/tests/jit/assign_obj_op_002.phpt | 31 ++++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_obj_op_002.phpt diff --git a/ext/opcache/jit/zend_jit_disasm_x86.c b/ext/opcache/jit/zend_jit_disasm_x86.c index 1258165815594..504c2efaec663 100644 --- a/ext/opcache/jit/zend_jit_disasm_x86.c +++ b/ext/opcache/jit/zend_jit_disasm_x86.c @@ -461,6 +461,7 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_jit_post_inc_typed_ref); REGISTER_HELPER(zend_jit_post_dec_typed_ref); REGISTER_HELPER(zend_jit_assign_op_to_typed_ref); + REGISTER_HELPER(zend_jit_assign_op_to_typed_ref_tmp); REGISTER_HELPER(zend_jit_only_vars_by_reference); REGISTER_HELPER(zend_jit_invalid_array_access); REGISTER_HELPER(zend_jit_invalid_property_read); diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 2eb3bb3cc1880..dd01532b5b705 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2259,6 +2259,20 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref(zend_reference *ref, z } } +static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref_tmp(zend_reference *ref, zval *val, binary_op_type binary_op) +{ + zval z_copy; + + binary_op(&z_copy, &ref->val, val); + if (EXPECTED(zend_verify_ref_assignable_zval(ref, &z_copy, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))))) { + zval_ptr_dtor(&ref->val); + ZVAL_COPY_VALUE(&ref->val, &z_copy); + } else { + zval_ptr_dtor(&z_copy); + } + zval_ptr_dtor_nogc(val); +} + static void ZEND_FASTCALL zend_jit_only_vars_by_reference(zval *arg) { ZVAL_NEW_REF(arg, arg); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 0539165687afb..b0635a77029bc 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -6776,7 +6776,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 | PUSH_ADDR binary_op, r0 |.endif | SET_EX_OPLINE opline, r0 - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -6900,7 +6905,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t | PUSH_ADDR binary_op, r0 |.endif | SET_EX_OPLINE opline, r0 - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) + && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -13974,7 +13984,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, | sub r4, 12 | PUSH_ADDR binary_op, r0 |.endif - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif @@ -14044,7 +14059,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst, | sub r4, 12 | PUSH_ADDR binary_op, r0 |.endif - | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR)) + && (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0 + } else { + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + } |.if not(X64) | add r4, 12 |.endif diff --git a/ext/opcache/tests/jit/assign_obj_op_002.phpt b/ext/opcache/tests/jit/assign_obj_op_002.phpt new file mode 100644 index 0000000000000..3d6ac3f897bff --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_op_002.phpt @@ -0,0 +1,31 @@ +--TEST-- +JIT ASSIGN_OBJ_OP: memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +prop .= $a->prop . "leak"; + return "test"; + } +} + +$a = new A; +$prop = &$a->prop; +$a->prop = new B; +var_dump($a); +?> +--EXPECT-- +object(A)#1 (1) { + ["prop"]=> + &string(4) "test" +} From 5ca2dd3d16e5d9591040a58313a2c0a0b94b7b36 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 28 Feb 2022 16:37:17 +0300 Subject: [PATCH 168/227] Fixed assertion after clobbering object by user error handler, because of creation dynamic property deprecation warning. Fixes oss-fuzz #44932 --- Zend/tests/dynamic_prop_deprecation_002.phpt | 9 +++++++-- Zend/zend_object_handlers.c | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Zend/tests/dynamic_prop_deprecation_002.phpt b/Zend/tests/dynamic_prop_deprecation_002.phpt index 2ab7452fedb67..bd0d3aa5a7df9 100644 --- a/Zend/tests/dynamic_prop_deprecation_002.phpt +++ b/Zend/tests/dynamic_prop_deprecation_002.phpt @@ -7,7 +7,12 @@ set_error_handler(function($code, $msg){ $GLOBALS['a']=null; }); $a = new class{}; -[&$a->y]; +try { + [&$a->y]; +} catch (Throwable $ex) { + echo "Exception: " .$ex->getMessage() . "\n"; +} ?> --EXPECT-- -Err: Creation of dynamic property class@anonymous::$y is deprecated \ No newline at end of file +Err: Creation of dynamic property class@anonymous::$y is deprecated +Exception: Cannot create dynamic property class@anonymous::$y diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 721abe46998b8..746897f641e0e 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -283,7 +283,13 @@ static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property( zend_error(E_DEPRECATED, "Creation of dynamic property %s::$%s is deprecated", ZSTR_VAL(obj->ce->name), ZSTR_VAL(member)); if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_class_entry *ce = obj->ce; zend_objects_store_del(obj); + if (!EG(exception)) { + /* We cannot continue execution and have to throw an exception */ + zend_throw_error(NULL, "Cannot create dynamic property %s::$%s", + ZSTR_VAL(ce->name), ZSTR_VAL(member)); + } return 0; } return 1; From aced867a952c189a3968a9ecf3e6ca28facc2153 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 28 Feb 2022 18:25:49 +0300 Subject: [PATCH 169/227] Fix typr inference Fixes oss-fuzz #45020 --- Zend/Optimizer/zend_inference.c | 1 + ext/opcache/tests/jit/assign_dim_013.phpt | 26 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_013.phpt diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 99e037829e875..6c5d96bd83158 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -2661,6 +2661,7 @@ static zend_always_inline int _zend_update_type_info( case ZEND_ASSIGN_DIM: if (opline->op1_type == IS_CV) { tmp = assign_dim_result_type(t1, t2, OP1_DATA_INFO(), opline->op2_type); + tmp |= ssa->var_info[ssa_op->op1_def].type & (MAY_BE_ARRAY_PACKED|MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH); UPDATE_SSA_TYPE(tmp, ssa_op->op1_def); COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def); } diff --git a/ext/opcache/tests/jit/assign_dim_013.phpt b/ext/opcache/tests/jit/assign_dim_013.phpt new file mode 100644 index 0000000000000..49907b358a21a --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_013.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT ASSIGN_DIM: 013 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +y = set_error_handler(function(){}); + foreach($obj as $y) { + } + $arr = ['' => y]; + } +} +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "y" in %sassign_dim_013.php:8 +Stack trace: +#0 %sassign_dim_013.php(11): test() +#1 {main} + thrown in %sassign_dim_013.php on line 8 \ No newline at end of file From bb0b4eb996c86b927df86f6bdb1e8ac0749e5333 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Mar 2022 00:00:22 +0300 Subject: [PATCH 170/227] Fix infiniry recursion during serialize() of "tricky" object Fixes oss-fuzz #44954 --- .../serialize/serialization_objects_016.phpt | 32 +++++++++++++++++++ ext/standard/var.c | 6 +++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/serialize/serialization_objects_016.phpt diff --git a/ext/standard/tests/serialize/serialization_objects_016.phpt b/ext/standard/tests/serialize/serialization_objects_016.phpt new file mode 100644 index 0000000000000..92b83f5f3c9df --- /dev/null +++ b/ext/standard/tests/serialize/serialization_objects_016.phpt @@ -0,0 +1,32 @@ +--TEST-- +Object serialization / unserialization: circular object with rc=1 +--FILE-- +y=$t; +$y=(array)$t; +unset($t); +var_dump($y); +$s=serialize($y); +var_dump($s); +$x=unserialize($s); +var_dump($x); +vaR_dump(serialize($x)); +?> +--EXPECTF-- +array(1) { + ["y"]=> + object(stdClass)#%d (1) { + ["y"]=> + *RECURSION* + } +} +string(45) "a:1:{s:1:"y";O:8:"stdClass":1:{s:1:"y";r:2;}}" +array(1) { + ["y"]=> + object(stdClass)#%d (1) { + ["y"]=> + *RECURSION* + } +} +string(45) "a:1:{s:1:"y";O:8:"stdClass":1:{s:1:"y";r:2;}}" diff --git a/ext/standard/var.c b/ext/standard/var.c index ef4b019fb6e76..c429763eb9c86 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -662,7 +662,11 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) / data->n += 1; - if (!is_ref && (Z_TYPE_P(var) != IS_OBJECT || Z_REFCOUNT_P(var) == 1)) { + if (is_ref) { + /* pass */ + } else if (Z_TYPE_P(var) != IS_OBJECT) { + return 0; + } else if (Z_REFCOUNT_P(var) == 1 && (Z_OBJ_P(var)->properties == NULL || GC_REFCOUNT(Z_OBJ_P(var)->properties) == 1)) { return 0; } From 01702a851b3902ac043d634f8cd7452edb26df1b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Mar 2022 01:33:22 +0300 Subject: [PATCH 171/227] Fix use after free Fixes oss-fuzz #44885 --- .../resume_running_generator_error_003.phpt | 24 +++++++++++++++++++ Zend/zend_generators.c | 3 +-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/generators/errors/resume_running_generator_error_003.phpt diff --git a/Zend/tests/generators/errors/resume_running_generator_error_003.phpt b/Zend/tests/generators/errors/resume_running_generator_error_003.phpt new file mode 100644 index 0000000000000..c72f9ba87258c --- /dev/null +++ b/Zend/tests/generators/errors/resume_running_generator_error_003.phpt @@ -0,0 +1,24 @@ +--TEST-- +Use-after-free when resume an already running generator +--FILE-- +send($y); +} +$gen=gen(); +try { + $gen->send($gen); +}catch(y) { +} +?> +--EXPECTF-- +Warning: Undefined variable $y in %sresume_running_generator_error_003.php on line 4 + +Fatal error: Uncaught Error: Cannot resume an already running generator in %sresume_running_generator_error_003.php:4 +Stack trace: +#0 %sresume_running_generator_error_003.php(4): Generator->send(NULL) +#1 [internal function]: gen() +#2 %sresume_running_generator_error_003.php(8): Generator->send(Object(Generator)) +#3 {main} + thrown in %sresume_running_generator_error_003.php on line 4 diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 2e6e22effab9d..66d3bb3b62424 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -923,8 +923,7 @@ ZEND_METHOD(Generator, send) root = zend_generator_get_current(generator); /* Put sent value in the target VAR slot, if it is used */ - if (root->send_target) { - zval_ptr_dtor(root->send_target); + if (root->send_target && !(root->flags & ZEND_GENERATOR_CURRENTLY_RUNNING)) { ZVAL_COPY(root->send_target, value); } From 5507201a389f3ac0e3e25d5e805a5d54208a1410 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 1 Mar 2022 11:30:01 +0100 Subject: [PATCH 172/227] Prepare for PHP 8.0.18 --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7d8806639f1ba..19ef33896c5c4 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 2022, PHP 8.0.17 +?? ??? 2022, PHP 8.0.18 - Core: . Fixed Haiku ZTS build. (David Carlier) From 05f2fb3af33e564c5da3aaca7e525d97af640a9d Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 1 Mar 2022 11:32:28 +0100 Subject: [PATCH 173/227] Fix NEWS format --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 19ef33896c5c4..c74365d2e079f 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.18 + +17 Mar 2022, PHP 8.0.17 + - Core: . Fixed Haiku ZTS build. (David Carlier) From e6cf583160f2054da92426e69143e80ee28e8e16 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Feb 2022 01:26:23 +0100 Subject: [PATCH 174/227] Fix GH-8082: Prevent leaking memory on observed transient run_time_caches This is achieved by tracking the observers on the run_time_cache (with a fixed amount of slots, 2 for each observer). That way round, if the run_time_cache is freed all associated observer data is as well. This approach has been chosen, as to avoid any ABI or API breakage. Future versions may for example choose to provide a hookable API for run_time_cache freeing or similar. --- NEWS | 2 + Zend/zend.c | 2 - Zend/zend_extensions.c | 11 +- Zend/zend_extensions.h | 1 + Zend/zend_observer.c | 200 +++++++++---------- Zend/zend_observer.h | 1 + ext/zend_test/tests/observer_bug81430_1.phpt | 2 +- ext/zend_test/tests/observer_bug81430_2.phpt | 2 +- main/main.c | 3 + 9 files changed, 111 insertions(+), 113 deletions(-) diff --git a/NEWS b/NEWS index c74365d2e079f..9b35952df519b 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS - Core: . Fixed Haiku ZTS build. (David Carlier) + . Fixed bug GH-8082 (op_arrays with temporary run_time_cache leak memory + when observed). (Bob) - GD: . Fixed libpng warning when loading interlaced images. (Brett) diff --git a/Zend/zend.c b/Zend/zend.c index cbd5aef42b9fe..cb245bb7704ee 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1215,8 +1215,6 @@ ZEND_API void zend_deactivate(void) /* {{{ */ /* we're no longer executing anything */ EG(current_execute_data) = NULL; - zend_observer_deactivate(); - zend_try { shutdown_scanner(); } zend_end_try(); diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index 4d4b1ffe09b41..c3efc0719bc94 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -267,8 +267,17 @@ ZEND_API int zend_get_resource_handle(const char *module_name) ZEND_API int zend_get_op_array_extension_handle(const char *module_name) { + int handle = zend_op_array_extension_handles++; zend_add_system_entropy(module_name, "zend_get_op_array_extension_handle", &zend_op_array_extension_handles, sizeof(int)); - return zend_op_array_extension_handles++; + return handle; +} + +ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles) +{ + int handle = zend_op_array_extension_handles; + zend_op_array_extension_handles += handles; + zend_add_system_entropy(module_name, "zend_get_op_array_extension_handle", &zend_op_array_extension_handles, sizeof(int)); + return handle; } ZEND_API zend_extension *zend_get_extension(const char *extension_name) diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 9f96d3b0fadba..195d508c3f358 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -115,6 +115,7 @@ extern ZEND_API int zend_op_array_extension_handles; ZEND_API int zend_get_resource_handle(const char *module_name); ZEND_API int zend_get_op_array_extension_handle(const char *module_name); +ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles); ZEND_API void zend_extension_dispatch_message(int message, void *arg); END_EXTERN_C() diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index b970acd85c8e5..f347738107850 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -31,28 +31,36 @@ #define ZEND_OBSERVABLE_FN(fn_flags) \ (!(fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) -typedef struct _zend_observer_fcall_data { - // points after the last handler - zend_observer_fcall_handlers *end; - // a variadic array using "struct hack" - zend_observer_fcall_handlers handlers[1]; -} zend_observer_fcall_data; - zend_llist zend_observers_fcall_list; zend_llist zend_observer_error_callbacks; int zend_observer_fcall_op_array_extension; -ZEND_TLS zend_arena *fcall_handlers_arena; ZEND_TLS zend_execute_data *first_observed_frame; ZEND_TLS zend_execute_data *current_observed_frame; // Call during minit/startup ONLY -ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) { - if (!ZEND_OBSERVER_ENABLED) { - /* We don't want to get an extension handle unless an ext installs an observer */ +ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) +{ + zend_llist_add_element(&zend_observers_fcall_list, &init); +} + +// Called by engine before MINITs +ZEND_API void zend_observer_startup(void) +{ + zend_llist_init(&zend_observers_fcall_list, sizeof(zend_observer_fcall_init), NULL, 1); + zend_llist_init(&zend_observer_error_callbacks, sizeof(zend_observer_error_cb), NULL, 1); + + zend_observer_fcall_op_array_extension = -1; +} + +ZEND_API void zend_observer_post_startup(void) +{ + if (zend_observers_fcall_list.count) { + /* We don't want to get an extension handle unless an ext installs an observer + * Allocate each a begin and an end pointer */ zend_observer_fcall_op_array_extension = - zend_get_op_array_extension_handle("Zend Observer"); + zend_get_op_array_extension_handles("Zend Observer", (int) zend_observers_fcall_list.count * 2); /* ZEND_CALL_TRAMPOLINE has SPEC(OBSERVER) but zend_init_call_trampoline_op() * is called before any extensions have registered as an observer. So we @@ -62,123 +70,98 @@ ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) { /* ZEND_HANDLE_EXCEPTION also has SPEC(OBSERVER) and no observer extensions * exist when zend_init_exception_op() is called. */ ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)); - ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1); - ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2); + ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op) + 1); + ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op) + 2); } - zend_llist_add_element(&zend_observers_fcall_list, &init); -} - -// Called by engine before MINITs -ZEND_API void zend_observer_startup(void) { - zend_llist_init(&zend_observers_fcall_list, sizeof(zend_observer_fcall_init), NULL, 1); - zend_llist_init(&zend_observer_error_callbacks, sizeof(zend_observer_error_cb), NULL, 1); - - zend_observer_fcall_op_array_extension = -1; } -ZEND_API void zend_observer_activate(void) { - if (ZEND_OBSERVER_ENABLED) { - fcall_handlers_arena = zend_arena_create(4096); - } else { - fcall_handlers_arena = NULL; - } +ZEND_API void zend_observer_activate(void) +{ first_observed_frame = NULL; current_observed_frame = NULL; } -ZEND_API void zend_observer_deactivate(void) { - if (fcall_handlers_arena) { - zend_arena_destroy(fcall_handlers_arena); - } +ZEND_API void zend_observer_deactivate(void) +{ + // now empty and unused, but kept for ABI compatibility } -ZEND_API void zend_observer_shutdown(void) { +ZEND_API void zend_observer_shutdown(void) +{ zend_llist_destroy(&zend_observers_fcall_list); zend_llist_destroy(&zend_observer_error_callbacks); } -static void zend_observer_fcall_install(zend_execute_data *execute_data) { - zend_llist_element *element; +static void zend_observer_fcall_install(zend_execute_data *execute_data) +{ zend_llist *list = &zend_observers_fcall_list; zend_function *function = execute_data->func; zend_op_array *op_array = &function->op_array; - if (fcall_handlers_arena == NULL) { - return; - } - ZEND_ASSERT(function->type != ZEND_INTERNAL_FUNCTION); - zend_llist handlers_list; - zend_llist_init(&handlers_list, sizeof(zend_observer_fcall_handlers), NULL, 0); - for (element = list->head; element; element = element->next) { + ZEND_ASSERT(RUN_TIME_CACHE(op_array)); + zend_observer_fcall_begin_handler *begin_handlers = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(op_array); + zend_observer_fcall_end_handler *end_handlers = (zend_observer_fcall_end_handler *)begin_handlers + list->count, *end_handlers_start = end_handlers; + + *begin_handlers = ZEND_OBSERVER_NOT_OBSERVED; + *end_handlers = ZEND_OBSERVER_NOT_OBSERVED; + + for (zend_llist_element *element = list->head; element; element = element->next) { zend_observer_fcall_init init; memcpy(&init, element->data, sizeof init); zend_observer_fcall_handlers handlers = init(execute_data); - if (handlers.begin || handlers.end) { - zend_llist_add_element(&handlers_list, &handlers); + if (handlers.begin) { + *(begin_handlers++) = handlers.begin; } - } - - ZEND_ASSERT(RUN_TIME_CACHE(op_array)); - void *ext; - if (handlers_list.count) { - size_t size = sizeof(zend_observer_fcall_data) + (handlers_list.count - 1) * sizeof(zend_observer_fcall_handlers); - zend_observer_fcall_data *fcall_data = zend_arena_alloc(&fcall_handlers_arena, size); - zend_observer_fcall_handlers *handlers = fcall_data->handlers; - for (element = handlers_list.head; element; element = element->next) { - memcpy(handlers++, element->data, sizeof *handlers); + if (handlers.end) { + *(end_handlers++) = handlers.end; } - fcall_data->end = handlers; - ext = fcall_data; - } else { - ext = ZEND_OBSERVER_NOT_OBSERVED; } - - ZEND_OBSERVER_DATA(op_array) = ext; - zend_llist_destroy(&handlers_list); + + // end handlers are executed in reverse order + for (--end_handlers; end_handlers_start < end_handlers; --end_handlers, ++end_handlers_start) { + zend_observer_fcall_end_handler tmp = *end_handlers; + *end_handlers = *end_handlers_start; + *end_handlers_start = tmp; + } } static void ZEND_FASTCALL _zend_observe_fcall_begin(zend_execute_data *execute_data) { - zend_op_array *op_array; - uint32_t fn_flags; - zend_observer_fcall_data *fcall_data; - zend_observer_fcall_handlers *handlers, *end; - if (!ZEND_OBSERVER_ENABLED) { return; } - op_array = &execute_data->func->op_array; - fn_flags = op_array->fn_flags; + zend_op_array *op_array = &execute_data->func->op_array; + uint32_t fn_flags = op_array->fn_flags; if (!ZEND_OBSERVABLE_FN(fn_flags)) { return; } - fcall_data = ZEND_OBSERVER_DATA(op_array); - if (!fcall_data) { + zend_observer_fcall_begin_handler *handler = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(op_array); + if (!*handler) { zend_observer_fcall_install(execute_data); - fcall_data = ZEND_OBSERVER_DATA(op_array); } - ZEND_ASSERT(fcall_data); - if (fcall_data == ZEND_OBSERVER_NOT_OBSERVED) { - return; - } + zend_observer_fcall_begin_handler *possible_handlers_end = handler + zend_observers_fcall_list.count; - if (first_observed_frame == NULL) { - first_observed_frame = execute_data; + zend_observer_fcall_end_handler *end_handler = (zend_observer_fcall_end_handler *)possible_handlers_end; + if (*end_handler != ZEND_OBSERVER_NOT_OBSERVED) { + if (first_observed_frame == NULL) { + first_observed_frame = execute_data; + } + current_observed_frame = execute_data; } - current_observed_frame = execute_data; - end = fcall_data->end; - for (handlers = fcall_data->handlers; handlers != end; ++handlers) { - if (handlers->begin) { - handlers->begin(execute_data); - } + if (*handler == ZEND_OBSERVER_NOT_OBSERVED) { + return; } + + do { + (*handler)(execute_data); + } while (++handler != possible_handlers_end && *handler != NULL); } ZEND_API void ZEND_FASTCALL zend_observer_generator_resume(zend_execute_data *execute_data) @@ -194,43 +177,48 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute } } -ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( - zend_execute_data *execute_data, - zval *return_value) +static inline bool zend_observer_is_skipped_frame(zend_execute_data *execute_data) { + zend_function *func = execute_data->func; + + if (!func || func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(func->common.fn_flags)) { + return true; + } + + zend_observer_fcall_end_handler end_handler = (&ZEND_OBSERVER_DATA(&func->op_array))[zend_observers_fcall_list.count]; + if (end_handler == NULL || end_handler == ZEND_OBSERVER_NOT_OBSERVED) { + return true; + } + + return false; +} + +ZEND_API void ZEND_FASTCALL zend_observer_fcall_end(zend_execute_data *execute_data, zval *return_value) { zend_function *func = execute_data->func; - zend_observer_fcall_data *fcall_data; - zend_observer_fcall_handlers *handlers, *end; if (!ZEND_OBSERVER_ENABLED || !ZEND_OBSERVABLE_FN(func->common.fn_flags)) { return; } - fcall_data = (zend_observer_fcall_data*)ZEND_OBSERVER_DATA(&func->op_array); + zend_observer_fcall_end_handler *handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(&func->op_array) + zend_observers_fcall_list.count; // TODO: Fix exceptions from generators // ZEND_ASSERT(fcall_data); - if (!fcall_data || fcall_data == ZEND_OBSERVER_NOT_OBSERVED) { + if (!*handler || *handler == ZEND_OBSERVER_NOT_OBSERVED) { return; } - handlers = fcall_data->end; - end = fcall_data->handlers; - while (handlers-- != end) { - if (handlers->end) { - handlers->end(execute_data, return_value); - } - } + zend_observer_fcall_end_handler *possible_handlers_end = handler + zend_observers_fcall_list.count; + do { + (*handler)(execute_data, return_value); + } while (++handler != possible_handlers_end && *handler != NULL); if (first_observed_frame == execute_data) { first_observed_frame = NULL; current_observed_frame = NULL; } else { zend_execute_data *ex = execute_data->prev_execute_data; - while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION - || !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags) - || !ZEND_OBSERVER_DATA(&ex->func->op_array) - || ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) { + while (ex && zend_observer_is_skipped_frame(ex)) { ex = ex->prev_execute_data; } current_observed_frame = ex; @@ -246,7 +234,6 @@ ZEND_API void zend_observer_fcall_end_all(void) } ex = ex->prev_execute_data; } - current_observed_frame = NULL; } ZEND_API void zend_observer_error_register(zend_observer_error_cb cb) @@ -256,11 +243,8 @@ ZEND_API void zend_observer_error_register(zend_observer_error_cb cb) void zend_observer_error_notify(int type, const char *error_filename, uint32_t error_lineno, zend_string *message) { - zend_llist_element *element; - zend_observer_error_cb callback; - - for (element = zend_observer_error_callbacks.head; element; element = element->next) { - callback = *(zend_observer_error_cb *) (element->data); + for (zend_llist_element *element = zend_observer_error_callbacks.head; element; element = element->next) { + zend_observer_error_cb callback = *(zend_observer_error_cb *) (element->data); callback(type, error_filename, error_lineno, message); } } diff --git a/Zend/zend_observer.h b/Zend/zend_observer.h index cb29729ec45da..2a2fce0761127 100644 --- a/Zend/zend_observer.h +++ b/Zend/zend_observer.h @@ -56,6 +56,7 @@ typedef zend_observer_fcall_handlers (*zend_observer_fcall_init)(zend_execute_da ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init); ZEND_API void zend_observer_startup(void); // Called by engine before MINITs +ZEND_API void zend_observer_post_startup(void); // Called by engine after MINITs ZEND_API void zend_observer_activate(void); ZEND_API void zend_observer_deactivate(void); ZEND_API void zend_observer_shutdown(void); diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt index cac53ef70cbbb..1d1e3c4256e0e 100644 --- a/ext/zend_test/tests/observer_bug81430_1.phpt +++ b/ext/zend_test/tests/observer_bug81430_1.phpt @@ -1,7 +1,7 @@ --TEST-- Bug #81430 (Attribute instantiation frame accessing invalid frame pointer) --EXTENSIONS-- -zend_test +zend-test --INI-- memory_limit=20M zend_test.observer.enabled=1 diff --git a/ext/zend_test/tests/observer_bug81430_2.phpt b/ext/zend_test/tests/observer_bug81430_2.phpt index 4d56248a80f34..a575fb9d7a038 100644 --- a/ext/zend_test/tests/observer_bug81430_2.phpt +++ b/ext/zend_test/tests/observer_bug81430_2.phpt @@ -1,7 +1,7 @@ --TEST-- Bug #81430 (Attribute instantiation leaves dangling execute_data pointer) --EXTENSIONS-- -zend_test +zend-test --INI-- memory_limit=20M zend_test.observer.enabled=1 diff --git a/main/main.c b/main/main.c index 073d260ac6898..7bd5400760f05 100644 --- a/main/main.c +++ b/main/main.c @@ -2280,6 +2280,9 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod module->version = PHP_VERSION; module->info_func = PHP_MINFO(php_core); } + + /* freeze the list of observer fcall_init handlers */ + zend_observer_post_startup(); /* Extensions that add engine hooks after this point do so at their own peril */ zend_finalize_system_id(); From 723058c3bfd3ecf4b4000e4acb83b75d5d866909 Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Wed, 2 Mar 2022 17:38:22 +0100 Subject: [PATCH 175/227] Bump for 8.1.5-dev --- NEWS | 5 ++++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 5474de448427d..b94b61c0f083d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.4 +?? ??? ????, PHP 8.1.5 + + +17 Mar 2022, PHP 8.1.4 - Core: . Fixed Haiku ZTS build. (David Carlier) diff --git a/Zend/zend.h b/Zend/zend.h index 67afd49421fd9..7dc686cc104f9 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.4-dev" +#define ZEND_VERSION "4.1.5-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 57e01def67e0e..90d6270a55dd1 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.4-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.5-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index fd5b1b0854a9b..a879ae407415d 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 -#define PHP_RELEASE_VERSION 4 +#define PHP_RELEASE_VERSION 5 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.4-dev" -#define PHP_VERSION_ID 80104 +#define PHP_VERSION "8.1.5-dev" +#define PHP_VERSION_ID 80105 From 925a30979c9afac158a5970bb371d50d1d2a676e Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 18 Feb 2022 13:23:57 +0100 Subject: [PATCH 176/227] Allowing catching arg type deprecations in intl classes Closes GH-8115 Closes GH-8117 --- NEWS | 3 ++ .../rulebasedbreakiterator_methods.cpp | 13 ++++-- .../calendar/gregoriancalendar_methods.cpp | 17 +++++--- ext/intl/collator/collator_create.c | 17 +++++--- ext/intl/dateformat/dateformat_create.cpp | 17 +++++--- .../datepatterngenerator_methods.cpp | 17 +++++--- ext/intl/formatter/formatter_main.c | 17 +++++--- ext/intl/msgformat/msgformat.c | 17 +++++--- .../resourcebundle/resourcebundle_class.c | 17 +++++--- ext/intl/tests/gh8115.phpt | 40 +++++++++++++++++++ 10 files changed, 136 insertions(+), 39 deletions(-) create mode 100644 ext/intl/tests/gh8115.phpt diff --git a/NEWS b/NEWS index b94b61c0f083d..36030ab4c8f27 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.5 +- Intl: + . Fixed bug GH-8115 (Can't catch arg type deprecation when instantiating Intl + classes). (ilutov) 17 Mar 2022, PHP 8.1.4 diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index 3e8684c793669..2f5658a1e1a81 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -31,7 +31,7 @@ static inline RuleBasedBreakIterator *fetch_rbbi(BreakIterator_object *bio) { return (RuleBasedBreakIterator*)bio->biter; } -static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS) +static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { char *rules; size_t rules_len; @@ -51,6 +51,9 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS) RETURN_THROWS(); } + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + // instantiation of ICU object RuleBasedBreakIterator *rbbi; @@ -95,11 +98,13 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS) U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU); - zend_restore_error_handling(&error_handling); + _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRules) diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index 1803e703a82c9..757b280cd972a 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -44,7 +44,7 @@ static inline GregorianCalendar *fetch_greg(Calendar_object *co) { } static void _php_intlgregcal_constructor_body( - INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) + INTERNAL_FUNCTION_PARAMETERS, bool is_constructor, zend_error_handling *error_handling, bool *error_handling_replaced) { zval *tz_object = NULL; zval args_a[6], @@ -84,6 +84,11 @@ static void _php_intlgregcal_constructor_body( RETURN_THROWS(); } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + // instantion of ICU object Calendar_object *co = Z_INTL_CALENDAR_P(return_value); GregorianCalendar *gcal = NULL; @@ -188,17 +193,19 @@ U_CFUNC PHP_FUNCTION(intlgregcal_create_instance) intl_error_reset(NULL); object_init_ex(return_value, GregorianCalendar_ce_ptr); - _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ 0, NULL, NULL); } U_CFUNC PHP_METHOD(IntlGregorianCalendar, __construct) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); - zend_restore_error_handling(&error_handling); + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ 1, &error_handling, &error_handling_replaced); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change) diff --git a/ext/intl/collator/collator_create.c b/ext/intl/collator/collator_create.c index bca1fc19b69b0..5fc4293e9773b 100644 --- a/ext/intl/collator/collator_create.c +++ b/ext/intl/collator/collator_create.c @@ -22,7 +22,7 @@ #include "intl_data.h" /* {{{ */ -static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char* locale; size_t locale_len = 0; @@ -38,6 +38,11 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); COLLATOR_METHOD_FETCH_OBJECT; @@ -56,7 +61,7 @@ static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_FUNCTION( collator_create ) { object_init_ex( return_value, Collator_ce_ptr ); - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -67,14 +72,16 @@ PHP_FUNCTION( collator_create ) PHP_METHOD( Collator, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index 2abd081385ad6..58867746ef0ca 100644 --- a/ext/intl/dateformat/dateformat_create.cpp +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -45,7 +45,7 @@ extern "C" { UDAT_PATTERN == (i)) /* {{{ */ -static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { zval *object; char *locale_str; @@ -81,6 +81,11 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_STRING_OR_NULL(pattern_str, pattern_str_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { @@ -189,7 +194,7 @@ return FAILURE; U_CFUNC PHP_FUNCTION( datefmt_create ) { object_init_ex( return_value, IntlDateFormatter_ce_ptr ); - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -200,18 +205,20 @@ U_CFUNC PHP_FUNCTION( datefmt_create ) U_CFUNC PHP_METHOD( IntlDateFormatter, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_string *err = intl_error_get_message(NULL); zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); zend_string_release_ex(err, 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/dateformat/datepatterngenerator_methods.cpp b/ext/intl/dateformat/datepatterngenerator_methods.cpp index 37a0c6c496e88..b473bf5d8669e 100644 --- a/ext/intl/dateformat/datepatterngenerator_methods.cpp +++ b/ext/intl/dateformat/datepatterngenerator_methods.cpp @@ -30,7 +30,7 @@ using icu::DateTimePatternGenerator; using icu::Locale; using icu::StringPiece; -static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) +static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { char *locale_str; size_t locale_len = 0; @@ -44,6 +44,11 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_STRING_OR_NULL(locale_str, locale_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + DTPATTERNGEN_METHOD_FETCH_OBJECT_NO_CHECK; if (dtpgo->dtpg != NULL) { @@ -74,7 +79,7 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) { object_init_ex( return_value, IntlDatePatternGenerator_ce_ptr ); - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -83,19 +88,21 @@ U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) U_CFUNC PHP_METHOD( IntlDatePatternGenerator, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_string *err = intl_error_get_message(NULL); zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); zend_string_release_ex(err, 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c index bea662081c36d..ed1806d6bbc55 100644 --- a/ext/intl/formatter/formatter_main.c +++ b/ext/intl/formatter/formatter_main.c @@ -23,7 +23,7 @@ #include "intl_convert.h" /* {{{ */ -static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char* locale; char* pattern = NULL; @@ -40,6 +40,11 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); object = return_value; FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; @@ -74,7 +79,7 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_FUNCTION( numfmt_create ) { object_init_ex( return_value, NumberFormatter_ce_ptr ); - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -85,15 +90,17 @@ PHP_FUNCTION( numfmt_create ) PHP_METHOD( NumberFormatter, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.c index 5be01e22e0a41..c363dd9706fb2 100644 --- a/ext/intl/msgformat/msgformat.c +++ b/ext/intl/msgformat/msgformat.c @@ -25,7 +25,7 @@ #include "intl_convert.h" /* {{{ */ -static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char* locale; char* pattern; @@ -45,6 +45,11 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; @@ -104,7 +109,7 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_FUNCTION( msgfmt_create ) { object_init_ex( return_value, MessageFormatter_ce_ptr ); - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -115,17 +120,19 @@ PHP_FUNCTION( msgfmt_create ) PHP_METHOD( MessageFormatter, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_string *err = intl_error_get_message(NULL); zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); zend_string_release_ex(err, 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index 589572024f009..aa4671a1b1310 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -74,7 +74,7 @@ static zend_object *ResourceBundle_object_create( zend_class_entry *ce ) /* }}} */ /* {{{ ResourceBundle_ctor */ -static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) +static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) { const char *bundlename; size_t bundlename_len = 0; @@ -93,6 +93,11 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (error_handling != NULL) { + zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); + *error_handling_replaced = 1; + } + if (rb->me) { zend_throw_error(NULL, "ResourceBundle object is already constructed"); return FAILURE; @@ -139,15 +144,17 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) PHP_METHOD( ResourceBundle, __construct ) { zend_error_handling error_handling; + bool error_handling_replaced = 0; - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); return_value = ZEND_THIS; - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } } - zend_restore_error_handling(&error_handling); + if (error_handling_replaced) { + zend_restore_error_handling(&error_handling); + } } /* }}} */ @@ -155,7 +162,7 @@ PHP_METHOD( ResourceBundle, __construct ) PHP_FUNCTION( resourcebundle_create ) { object_init_ex( return_value, ResourceBundle_ce_ptr ); - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } diff --git a/ext/intl/tests/gh8115.phpt b/ext/intl/tests/gh8115.phpt new file mode 100644 index 0000000000000..47e32658e5a7d --- /dev/null +++ b/ext/intl/tests/gh8115.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-8115 (Can't catch deprecation in IntlDateFormatter) +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +Caught (8192): IntlDateFormatter::__construct(): Passing null to parameter #2 ($dateType) of type int is deprecated +Caught (8192): IntlDateFormatter::__construct(): Passing null to parameter #3 ($timeType) of type int is deprecated +Caught (8192): IntlRuleBasedBreakIterator::__construct(): Passing null to parameter #1 ($rules) of type string is deprecated +Caught (8192): IntlRuleBasedBreakIterator::__construct(): Passing null to parameter #2 ($compiled) of type bool is deprecated +Caught (8192): Collator::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated +Caught (8192): NumberFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated +Caught (8192): NumberFormatter::__construct(): Passing null to parameter #2 ($style) of type int is deprecated +Caught (8192): MessageFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated +Caught (8192): MessageFormatter::__construct(): Passing null to parameter #2 ($pattern) of type string is deprecated +Caught (8192): ResourceBundle::__construct(): Passing null to parameter #3 ($fallback) of type bool is deprecated From 67440096c50b771d5a99c15ad59dbd2519cc8360 Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Fri, 4 Mar 2022 13:24:08 +0100 Subject: [PATCH 177/227] Added: [zend_]memory_reset_peak_usage() (#8151) --- NEWS | 1 + UPGRADING | 4 ++++ Zend/tests/memory_reset_peak_usage.phpt | 23 +++++++++++++++++++++++ Zend/zend_alloc.c | 8 ++++++++ Zend/zend_alloc.h | 1 + ext/standard/basic_functions_arginfo.h | 5 +++++ ext/standard/var.c | 8 ++++++++ 7 files changed, 50 insertions(+) create mode 100644 Zend/tests/memory_reset_peak_usage.phpt diff --git a/NEWS b/NEWS index ab565d58ae5bd..49d3d7bac0ae2 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,7 @@ PHP NEWS . Finished AVIF support in getimagesize(). (Yannis Guyon) . Fixed bug GH-7847 (stripos with large haystack has bad performance). (ilutov) + . New function memory_reset_peak_usage(). (Patrick Allaert) - Zip: . add ZipArchive::clearError() method diff --git a/UPGRADING b/UPGRADING index efc6f36df0eef..b91229ec627ea 100644 --- a/UPGRADING +++ b/UPGRADING @@ -114,6 +114,10 @@ PHP 8.2 UPGRADE NOTES 6. New Functions ======================================== +- Standard: + . The peak memory usage can now be reset to the current usage thanks to + memory_reset_peak_usage(). + ======================================== 7. New Classes and Interfaces ======================================== diff --git a/Zend/tests/memory_reset_peak_usage.phpt b/Zend/tests/memory_reset_peak_usage.phpt new file mode 100644 index 0000000000000..0599e7c313c41 --- /dev/null +++ b/Zend/tests/memory_reset_peak_usage.phpt @@ -0,0 +1,23 @@ +--TEST-- +void memory_reset_peak_usage(); +--SKIPIF-- + +--INI-- +memory_limit=-1 +--FILE-- + $m0); +unset($array0, $array1); +memory_reset_peak_usage(); +var_dump(memory_get_peak_usage() < $m1); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 9635068a6bb86..d8a7b07db77fc 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2724,6 +2724,14 @@ ZEND_API size_t zend_memory_peak_usage(bool real_usage) return 0; } +ZEND_API void zend_memory_reset_peak_usage(void) +{ +#if ZEND_MM_STAT + AG(mm_heap)->real_peak = AG(mm_heap)->real_size; + AG(mm_heap)->peak = AG(mm_heap)->size; +#endif +} + ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown) { zend_mm_shutdown(AG(mm_heap), full_shutdown, silent); diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 9603af8a27d3f..f517b1231d1d2 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -229,6 +229,7 @@ ZEND_API bool is_zend_ptr(const void *ptr); ZEND_API size_t zend_memory_usage(bool real_usage); ZEND_API size_t zend_memory_peak_usage(bool real_usage); +ZEND_API void zend_memory_reset_peak_usage(void); /* fast cache for HashTables */ #define ALLOC_HASHTABLE(ht) \ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 850c3f7a3051a..10a6cfd7f2af0 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -2175,6 +2175,9 @@ ZEND_END_ARG_INFO() #define arginfo_memory_get_peak_usage arginfo_memory_get_usage +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_memory_reset_peak_usage, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_version_compare, 0, 2, MAY_BE_LONG|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, version1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, version2, IS_STRING, 0) @@ -2824,6 +2827,7 @@ ZEND_FUNCTION(serialize); ZEND_FUNCTION(unserialize); ZEND_FUNCTION(memory_get_usage); ZEND_FUNCTION(memory_get_peak_usage); +ZEND_FUNCTION(memory_reset_peak_usage); ZEND_FUNCTION(version_compare); #if defined(PHP_WIN32) ZEND_FUNCTION(sapi_windows_cp_set); @@ -3479,6 +3483,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(unserialize, arginfo_unserialize) ZEND_FE(memory_get_usage, arginfo_memory_get_usage) ZEND_FE(memory_get_peak_usage, arginfo_memory_get_peak_usage) + ZEND_FE(memory_reset_peak_usage, arginfo_memory_reset_peak_usage) ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(version_compare, arginfo_version_compare) #if defined(PHP_WIN32) ZEND_FE(sapi_windows_cp_set, arginfo_sapi_windows_cp_set) diff --git a/ext/standard/var.c b/ext/standard/var.c index c429763eb9c86..dc9f8639b146f 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1478,6 +1478,14 @@ PHP_FUNCTION(memory_get_peak_usage) { } /* }}} */ +/* {{{ Resets the peak PHP memory usage */ +PHP_FUNCTION(memory_reset_peak_usage) { + ZEND_PARSE_PARAMETERS_NONE(); + + zend_memory_reset_peak_usage(); +} +/* }}} */ + PHP_INI_BEGIN() STD_PHP_INI_ENTRY("unserialize_max_depth", "4096", PHP_INI_ALL, OnUpdateLong, unserialize_max_depth, php_basic_globals, basic_globals) PHP_INI_END() From 57ef16bb5d10087483c995c3c12c131b4bf1a60c Mon Sep 17 00:00:00 2001 From: risner Date: Mon, 7 Feb 2022 12:22:50 -0500 Subject: [PATCH 178/227] Fix GH-8048: disk_*_space wrong for some filesystems on macOS A macOS bug in libc statvfs(3) call truncates 64 bit elements (e.g. f_blocks) to 32 bits. Thus, we force macOS to use statfs. Closes GH-8056. --- NEWS | 2 ++ ext/standard/filestat.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/NEWS b/NEWS index 9b35952df519b..1ccffaae6c1d9 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.18 +- Standard: + . Fixed bug GH-8048 (Force macOS to use statfs). (risner) 17 Mar 2022, PHP 8.0.17 diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 0d79bba461bea..e537f35829106 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -42,6 +42,16 @@ # include #endif +#if defined(__APPLE__) + /* + Apple statvfs has an interger overflow in libc copying to statvfs. + cvt_statfs_to_statvfs(struct statfs *from, struct statvfs *to) { + to->f_blocks = (fsblkcnt_t)from->f_blocks; + */ +# undef HAVE_SYS_STATVFS_H +# undef HAVE_STATVFS +#endif + #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS) # include #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS) From 8b15858c58a93133a08c729da92923b68eb94dec Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 23 Feb 2022 19:41:19 +0000 Subject: [PATCH 179/227] Fix GH-8142: Compilation error on cygwin * pcntl: SIGPOLL/si_band is unsupported * intl: enable the signal apis with `_POSIX_C_SOURCE` Closes GH-8146. --- NEWS | 6 ++++++ ext/intl/config.m4 | 3 +++ ext/pcntl/pcntl.c | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1ccffaae6c1d9..d15374080241d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,12 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.18 +- Intl: + . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) + +- Pcntl: + . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) + - Standard: . Fixed bug GH-8048 (Force macOS to use statfs). (risner) diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index b511f00451b81..36221a9d7bfb4 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -85,6 +85,9 @@ if test "$PHP_INTL" != "no"; then PHP_REQUIRE_CXX() PHP_CXX_COMPILE_STDCXX(11, mandatory, PHP_INTL_STDCXX) PHP_INTL_CXX_FLAGS="$INTL_COMMON_FLAGS $PHP_INTL_STDCXX $ICU_CXXFLAGS" + case $host_alias in + *cygwin*) PHP_INTL_CXX_FLAGS="$PHP_INTL_CXX_FLAGS -D_POSIX_C_SOURCE=200809L" + esac if test "$ext_shared" = "no"; then PHP_ADD_SOURCES(PHP_EXT_DIR(intl), $PHP_INTL_CXX_SOURCES, $PHP_INTL_CXX_FLAGS) else diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index e59decb3a55fc..2b1f9f5f1f027 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1160,7 +1160,7 @@ static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_sigi case SIGBUS: add_assoc_double_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo->si_addr); break; -#ifdef SIGPOLL +#if defined(SIGPOLL) && !defined(__CYGWIN__) case SIGPOLL: add_assoc_long_ex(user_siginfo, "band", sizeof("band")-1, siginfo->si_band); # ifdef si_fd From cbbf3502a28c4feda736f6a43107a01e7e163ba2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 7 Mar 2022 03:53:38 +0100 Subject: [PATCH 180/227] Fix GH-8176: Fix leaking enum values in property initializers --- NEWS | 3 +++ Zend/tests/enum/gh8176.phpt | 23 +++++++++++++++++++++++ Zend/zend_execute_API.c | 12 ++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 Zend/tests/enum/gh8176.phpt diff --git a/NEWS b/NEWS index b7b605b4348b8..6726c114374a7 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.5 +- Core: + . Fixed bug GH-8176 (Enum values in property initializers leak). (Bob) + - Intl: . Fixed bug GH-8115 (Can't catch arg type deprecation when instantiating Intl classes). (ilutov) diff --git a/Zend/tests/enum/gh8176.phpt b/Zend/tests/enum/gh8176.phpt new file mode 100644 index 0000000000000..b3dac08d0c6ba --- /dev/null +++ b/Zend/tests/enum/gh8176.phpt @@ -0,0 +1,23 @@ +--TEST-- +Enum object in property initializer +--FILE-- + +--EXPECT-- +object(AClass)#2 (1) { + ["prop"]=> + enum(AnEnum::Value) +} diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f2ace090c6724..073bce2758b17 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -329,6 +329,18 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) ZVAL_UNDEF(&c->value); } } ZEND_HASH_FOREACH_END(); + + /* properties may contain objects as well */ + if (ce->default_properties_table) { + zval *p = ce->default_properties_table; + zval *end = p + ce->default_properties_count; + + while (p != end) { + i_zval_ptr_dtor(p); + ZVAL_UNDEF(p); + p++; + } + } } if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) { From f095d2c91b7177fb0d9791cfc89bee66cf9d4c3e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 7 Mar 2022 20:35:16 +0100 Subject: [PATCH 181/227] Fix freeing of internal attribute arguments --- NEWS | 3 +++ Zend/zend_attributes.c | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index d15374080241d..604bacc7c7572 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.18 +- Core: + . Fixed freeing of internal attribute arguments. (Bob) + - Intl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index 58cd813f7df39..45d1cbec46f94 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -181,6 +181,7 @@ ZEND_API zend_bool zend_is_attribute_repeated(HashTable *attributes, zend_attrib static void attr_free(zval *v) { zend_attribute *attr = Z_PTR_P(v); + bool persistent = attr->flags & ZEND_ATTRIBUTE_PERSISTENT; zend_string_release(attr->name); zend_string_release(attr->lcname); @@ -189,10 +190,14 @@ static void attr_free(zval *v) if (attr->args[i].name) { zend_string_release(attr->args[i].name); } - zval_ptr_dtor(&attr->args[i].value); + if (persistent) { + zval_internal_ptr_dtor(&attr->args[i].value); + } else { + zval_ptr_dtor(&attr->args[i].value); + } } - pefree(attr, attr->flags & ZEND_ATTRIBUTE_PERSISTENT); + pefree(attr, persistent); } ZEND_API zend_attribute *zend_add_attribute(HashTable **attributes, zend_string *name, uint32_t argc, uint32_t flags, uint32_t offset, uint32_t lineno) From 0d7e10c1a9babcb2592fb5cd9284e779b45af2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 7 Mar 2022 16:32:46 +0100 Subject: [PATCH 182/227] Fix memory leak of function attribute hash table (#8070) ==109253== 280 (56 direct, 224 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 ==109253== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==109253== by 0x6D9FA2: __zend_malloc (zend_alloc.c:3068) ==109253== by 0x745138: zend_add_attribute (zend_attributes.c:226) ==109253== by 0x6680D1: zend_add_parameter_attribute (zend_attributes.h:102) ==109253== by 0x66B787: zm_startup_zend_test (test.c:478) ==109253== by 0x7224CD: zend_startup_module_ex (zend_API.c:2202) ==109253== by 0x72252C: zend_startup_module_zval (zend_API.c:2217) ==109253== by 0x734288: zend_hash_apply (zend_hash.c:2011) ==109253== by 0x722C30: zend_startup_modules (zend_API.c:2328) ==109253== by 0x67409B: php_module_startup (main.c:2256) ==109253== by 0x88EDDE: php_cli_startup (php_cli.c:409) ==109253== by 0x890F61: main (php_cli.c:1334) --- NEWS | 2 ++ Zend/zend.c | 16 ++++++++++++++++ Zend/zend_opcode.c | 19 +++++++++++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 604bacc7c7572..a4c779472d4fb 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Core: . Fixed freeing of internal attribute arguments. (Bob) + . Fixed bug GH-8070 (memory leak of internal function attribute hash). + (Tim Düsterhus) - Intl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) diff --git a/Zend/zend.c b/Zend/zend.c index cb245bb7704ee..e9f9388ae2935 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -624,6 +624,22 @@ static void function_copy_ctor(zval *zv) /* {{{ */ } func->common.arg_info = new_arg_info + 1; } + if (old_func->common.attributes) { + zend_attribute *old_attr; + + func->common.attributes = NULL; + + ZEND_HASH_PACKED_FOREACH_PTR(old_func->common.attributes, old_attr) { + uint32_t i; + zend_attribute *attr; + + attr = zend_add_attribute(&func->common.attributes, old_attr->name, old_attr->argc, old_attr->flags, old_attr->offset, old_attr->lineno); + + for (i = 0 ; i < old_attr->argc; i++) { + ZVAL_DUP(&attr->args[i].value, &old_attr->args[i].value); + } + } ZEND_HASH_FOREACH_END(); + } } /* }}} */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 620d42dfc6e59..7ea2485e1c4af 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -153,6 +153,11 @@ ZEND_API void zend_function_dtor(zval *zv) /* For methods this will be called explicitly. */ if (!function->common.scope) { zend_free_internal_arg_info(&function->internal_function); + + if (function->common.attributes) { + zend_hash_release(function->common.attributes); + function->common.attributes = NULL; + } } if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) { @@ -394,11 +399,17 @@ ZEND_API void destroy_zend_class(zval *zv) zend_hash_destroy(&ce->properties_info); zend_string_release_ex(ce->name, 1); - /* TODO: eliminate this loop for classes without functions with arg_info */ + /* TODO: eliminate this loop for classes without functions with arg_info / attributes */ ZEND_HASH_FOREACH_PTR(&ce->function_table, fn) { - if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) && - fn->common.scope == ce) { - zend_free_internal_arg_info(&fn->internal_function); + if (fn->common.scope == ce) { + if (fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) { + zend_free_internal_arg_info(&fn->internal_function); + } + + if (fn->common.attributes) { + zend_hash_release(fn->common.attributes); + fn->common.attributes = NULL; + } } } ZEND_HASH_FOREACH_END(); From 070012d62add5c26ddc1e66ee93e7c77e389cac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 9 Feb 2022 19:16:57 +0100 Subject: [PATCH 183/227] Add tests for function parameter attributes to ext/zend_test These tests verify the correct workings of the previous fixes: - Parameter attributes for native functions should not leak memory. - Parameter attributes for native functions should behave as expected. --- ext/zend_test/test.c | 113 ++++++++++++ ext/zend_test/test.stub.php | 17 ++ ext/zend_test/test_arginfo.h | 78 +++++++- ext/zend_test/tests/attribute_arguments.phpt | 169 ++++++++++++++++++ .../tests/attribute_hash_table_leak.phpt | 68 +++++++ 5 files changed, 444 insertions(+), 1 deletion(-) create mode 100644 ext/zend_test/tests/attribute_arguments.phpt create mode 100644 ext/zend_test/tests/attribute_hash_table_leak.phpt diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 0dc6ddd5128cd..e2fec01aec09c 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -37,6 +37,9 @@ static zend_class_entry *zend_test_class; static zend_class_entry *zend_test_child_class; static zend_class_entry *zend_test_trait; static zend_class_entry *zend_test_attribute; +static zend_class_entry *zend_test_parameter_attribute; +static zend_class_entry *zend_test_class_with_method_with_parameter_attribute; +static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute; static zend_class_entry *zend_test_ns_foo_class; static zend_class_entry *zend_test_ns2_foo_class; static zend_class_entry *zend_test_ns2_ns_foo_class; @@ -278,6 +281,17 @@ static ZEND_FUNCTION(namespaced_func) RETURN_TRUE; } +static ZEND_FUNCTION(zend_test_parameter_with_attribute) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(1); +} + static zend_object *zend_test_class_new(zend_class_entry *class_type) { zend_object *obj = zend_objects_new(class_type); @@ -390,6 +404,50 @@ static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method) ZEND_PARSE_PARAMETERS_NONE(); } +static ZEND_METHOD(ZendTestParameterAttribute, __construct) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter); +} + +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(2); +} + +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(3); +} + +static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override) +{ + zend_string *parameter; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(parameter) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(4); +} + PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals) STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals) @@ -425,6 +483,61 @@ PHP_MINIT_FUNCTION(zend_test) attr->validator = zend_attribute_validate_zendtestattribute; } + zend_test_parameter_attribute = register_class_ZendTestParameterAttribute(); + zend_internal_attribute_register(zend_test_parameter_attribute, ZEND_ATTRIBUTE_TARGET_PARAMETER); + + { + zend_attribute *attr; + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value1"); + } + + zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute(); + + { + zend_attribute *attr; + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "no_override", sizeof("no_override") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value2"); + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value3"); + } + + zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute); + + { + zend_attribute *attr; + + attr = zend_add_parameter_attribute( + zend_hash_str_find_ptr(&zend_test_child_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1), + 0, + zend_test_parameter_attribute->name, + 1 + ); + + ZVAL_PSTRING(&attr->args[0].value, "value4"); + } + zend_test_ns_foo_class = register_class_ZendTestNS_Foo(); zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo(); zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo(); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index dda97938a409d..23ee3e9685a32 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -48,6 +48,21 @@ final class ZendTestAttribute { } + final class ZendTestParameterAttribute { + public string $parameter; + + public function __construct(string $parameter) {} + } + + class ZendTestClassWithMethodWithParameterAttribute { + final public function no_override(string $parameter): int {} + public function override(string $parameter): int {} + } + + class ZendTestChildClassWithMethodWithParameterAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(string $parameter): int {} + } + enum ZendTestUnitEnum { case Foo; case Bar; @@ -93,6 +108,8 @@ function zend_weakmap_remove(object $object): bool {} function zend_weakmap_dump(): array {} function zend_get_unit_enum(): ZendTestUnitEnum {} + + function zend_test_parameter_with_attribute(#[ZendTestParameterAttribute] string $parameter): int {} } namespace ZendTestNS { diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index dcf2df117fac8..590ef4403a9a6 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0af85c5349efaff6f19e003712d9ba929adc9ce1 */ + * Stub hash: 57eb52664b0a7b3dd2a38294e9a936d248274a14 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -65,6 +65,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_parameter_with_attribute, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -85,6 +89,16 @@ ZEND_END_ARG_INFO() #define arginfo_class__ZendTestTrait_testMethod arginfo_ZendTestNS2_ZendSubNS_namespaced_func +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestParameterAttribute___construct, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute + +#define arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute + #define arginfo_class_ZendTestNS_Foo_method arginfo_zend_test_void_return #define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_test_void_return @@ -109,6 +123,7 @@ static ZEND_FUNCTION(zend_weakmap_attach); static ZEND_FUNCTION(zend_weakmap_remove); static ZEND_FUNCTION(zend_weakmap_dump); static ZEND_FUNCTION(zend_get_unit_enum); +static ZEND_FUNCTION(zend_test_parameter_with_attribute); static ZEND_FUNCTION(namespaced_func); static ZEND_METHOD(_ZendTestClass, is_object); static ZEND_METHOD(_ZendTestClass, __toString); @@ -116,6 +131,10 @@ static ZEND_METHOD(_ZendTestClass, returnsStatic); static ZEND_METHOD(_ZendTestClass, returnsThrowable); static ZEND_METHOD(_ZendTestChildClass, returnsThrowable); static ZEND_METHOD(_ZendTestTrait, testMethod); +static ZEND_METHOD(ZendTestParameterAttribute, __construct); +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override); +static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override); +static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override); static ZEND_METHOD(ZendTestNS_Foo, method); static ZEND_METHOD(ZendTestNS2_Foo, method); static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method); @@ -139,6 +158,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove) ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump) ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum) + ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute) ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func) ZEND_FE_END }; @@ -175,6 +195,25 @@ static const zend_function_entry class_ZendTestAttribute_methods[] = { }; +static const zend_function_entry class_ZendTestParameterAttribute_methods[] = { + ZEND_ME(ZendTestParameterAttribute, __construct, arginfo_class_ZendTestParameterAttribute___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + +static const zend_function_entry class_ZendTestClassWithMethodWithParameterAttribute_methods[] = { + ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, no_override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) + ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + +static const zend_function_entry class_ZendTestChildClassWithMethodWithParameterAttribute_methods[] = { + ZEND_ME(ZendTestChildClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + static const zend_function_entry class_ZendTestUnitEnum_methods[] = { ZEND_FE_END }; @@ -306,6 +345,43 @@ static zend_class_entry *register_class_ZendTestAttribute(void) return class_entry; } +static zend_class_entry *register_class_ZendTestParameterAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL; + + zval property_parameter_default_value; + ZVAL_UNDEF(&property_parameter_default_value); + zend_string *property_parameter_name = zend_string_init("parameter", sizeof("parameter") - 1, 1); + zend_declare_typed_property(class_entry, property_parameter_name, &property_parameter_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_parameter_name); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} + +static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_class_entry *class_entry_ZendTestClassWithMethodWithParameterAttribute) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute); + + return class_entry; +} + static zend_class_entry *register_class_ZendTestUnitEnum(void) { zend_class_entry *class_entry = zend_register_internal_enum("ZendTestUnitEnum", IS_UNDEF, class_ZendTestUnitEnum_methods); diff --git a/ext/zend_test/tests/attribute_arguments.phpt b/ext/zend_test/tests/attribute_arguments.phpt new file mode 100644 index 0000000000000..e1ec8a89d9a00 --- /dev/null +++ b/ext/zend_test/tests/attribute_arguments.phpt @@ -0,0 +1,169 @@ +--TEST-- +Verify that parameter attributes for native functions correctly support arguments. +--EXTENSIONS-- +zend_test +--FILE-- +getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestClassWithMethodWithParameterAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestClassWithMethodWithParameterAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestChildClassWithMethodWithParameterAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ZendTestChildClassWithMethodWithParameterAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +class ChildClassWithNoAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(string $parameter): int + { + return 5; + } +} + +$reflection = new ReflectionMethod("ChildClassWithNoAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ChildClassWithNoAttribute", "override"); +var_dump(count($reflection->getParameters()[0]->getAttributes())); + +class ChildClassWithSameAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[ZendTestParameterAttribute("value5")] string $parameter): int + { + return 6; + } +} + +$reflection = new ReflectionMethod("ChildClassWithSameAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ChildClassWithSameAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class SomeAttribute { + public function __construct(public string $someParam) { } +} + +class ChildClassWithDifferentAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[SomeAttribute("value6")] string $parameter): int + { + return 7; + } +} + +$reflection = new ReflectionMethod("ChildClassWithDifferentAttribute", "no_override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +$reflection = new ReflectionMethod("ChildClassWithDifferentAttribute", "override"); +$attribute = $reflection->getParameters()[0]->getAttributes()[0]; +var_dump($attribute->getArguments()); +var_dump($attribute->newInstance()); + +?> +--EXPECTF-- +array(1) { + [0]=> + string(6) "value1" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value1" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value3" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value3" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value4" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value4" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +int(0) +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value5" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value5" +} +array(1) { + [0]=> + string(6) "value2" +} +object(ZendTestParameterAttribute)#%d (1) { + ["parameter"]=> + string(6) "value2" +} +array(1) { + [0]=> + string(6) "value6" +} +object(SomeAttribute)#%d (1) { + ["someParam"]=> + string(6) "value6" +} diff --git a/ext/zend_test/tests/attribute_hash_table_leak.phpt b/ext/zend_test/tests/attribute_hash_table_leak.phpt new file mode 100644 index 0000000000000..10c786393589e --- /dev/null +++ b/ext/zend_test/tests/attribute_hash_table_leak.phpt @@ -0,0 +1,68 @@ +--TEST-- +Verify that parameter attributes for native functions do not leak. +--EXTENSIONS-- +zend_test +--FILE-- +no_override("foo")); +var_dump($o->override("foo")); + +$o = new ZendTestChildClassWithMethodWithParameterAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +class ChildClassWithNoAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(string $parameter): int + { + return 5; + } +} + +$o = new ChildClassWithNoAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +class ChildClassWithSameAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[ZendTestParameterAttribute] string $parameter): int + { + return 6; + } +} + +$o = new ChildClassWithSameAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class SomeAttribute { + +} + +class ChildClassWithDifferentAttribute extends ZendTestClassWithMethodWithParameterAttribute { + public function override(#[SomeAttribute] string $parameter): int + { + return 7; + } +} + +$o = new ChildClassWithDifferentAttribute(); +var_dump($o->no_override("foo")); +var_dump($o->override("foo")); + +?> +--EXPECT-- +int(1) +int(2) +int(3) +int(2) +int(4) +int(2) +int(5) +int(2) +int(6) +int(2) +int(7) From 15949b61ba5813b5e1c3a97bee79d844e002d1f0 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 7 Mar 2022 22:24:55 +0100 Subject: [PATCH 184/227] Fix ZTS build after cherry-pick --- Zend/zend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend.c b/Zend/zend.c index e9f9388ae2935..20e4c786426b0 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -629,7 +629,7 @@ static void function_copy_ctor(zval *zv) /* {{{ */ func->common.attributes = NULL; - ZEND_HASH_PACKED_FOREACH_PTR(old_func->common.attributes, old_attr) { + ZEND_HASH_FOREACH_PTR(old_func->common.attributes, old_attr) { uint32_t i; zend_attribute *attr; From e6bdf980eb44527b5e28ba9f11bbf94566c205c2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 7 Mar 2022 22:31:36 +0100 Subject: [PATCH 185/227] Put packed back to attribute iterating after merge --- Zend/zend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend.c b/Zend/zend.c index cda035dac6012..23c93bb719230 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -670,7 +670,7 @@ static void function_copy_ctor(zval *zv) /* {{{ */ func->common.attributes = NULL; - ZEND_HASH_FOREACH_PTR(old_func->common.attributes, old_attr) { + ZEND_HASH_PACKED_FOREACH_PTR(old_func->common.attributes, old_attr) { uint32_t i; zend_attribute *attr; From 6a2c501626514eed1ef0102396d4908dc14498c7 Mon Sep 17 00:00:00 2001 From: Victor Kislov Date: Tue, 8 Mar 2022 14:00:23 +0200 Subject: [PATCH 186/227] Adjust PHP_SETUP_LIBXML description to mention what it doesnt use action-not-found Closes GH-8088. --- build/php.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php.m4 b/build/php.m4 index 01b8250598191..94e824f6cc263 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -2030,7 +2030,7 @@ ifelse([$3],[],,[else $3]) ]) dnl -dnl PHP_SETUP_LIBXML(shared-add [, action-found [, action-not-found]]) +dnl PHP_SETUP_LIBXML(shared-add [, action-found]) dnl dnl Common setup macro for libxml. dnl From 1d9a1f9be32d8e14d0b469a77219e3de0fccb406 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 28 Feb 2022 12:03:26 +0100 Subject: [PATCH 187/227] Fix GH-8121: SplFileObject - seek and key with csv file inconsistent First, we must not free the current line before we call `spl_filesystem_file_read_csv()`, because then the `current_line` will not be properly updated. Since the EOF check is superfluous here, we move that part of the code to the branch for subtypes. This issue has been introduced by the fix for bug 75917. Second, we only must increase the `current_line` if we're not reading ahead. This issue has been introduced by the fix for bug 62004. Closes GH-8138. --- NEWS | 4 ++++ ext/spl/spl_directory.c | 15 +++++++-------- ext/spl/tests/gh8121.csv | 5 +++++ ext/spl/tests/gh8121.phpt | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 ext/spl/tests/gh8121.csv create mode 100644 ext/spl/tests/gh8121.phpt diff --git a/NEWS b/NEWS index a4c779472d4fb..f4631f96c7d7b 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ PHP NEWS - Pcntl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) +- SPL: + . Fixed bug GH-8121 (SplFileObject - seek and key with csv file inconsistent). + (cmb) + - Standard: . Fixed bug GH-8048 (Force macOS to use statfs). (risner) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 045aad5bc1b02..165b986615999 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1938,7 +1938,11 @@ static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_obje zval retval; /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */ - if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) { + if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) { + return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL); + } + if (intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) { + zend_execute_data *execute_data = EG(current_execute_data); spl_filesystem_file_free_line(intern); if (php_stream_eof(intern->u.file.stream)) { @@ -1947,12 +1951,7 @@ static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_obje } return FAILURE; } - if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) { - return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL); - } else { - zend_execute_data *execute_data = EG(current_execute_data); - zend_call_method_with_0_params(Z_OBJ_P(this_ptr), Z_OBJCE_P(ZEND_THIS), &intern->u.file.func_getCurr, "getCurrentLine", &retval); - } + zend_call_method_with_0_params(Z_OBJ_P(this_ptr), Z_OBJCE_P(ZEND_THIS), &intern->u.file.func_getCurr, "getCurrentLine", &retval); if (!Z_ISUNDEF(retval)) { if (intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)) { intern->u.file.current_line_num++; @@ -2739,8 +2738,8 @@ PHP_METHOD(SplFileObject, seek) } } if (line_pos > 0) { - intern->u.file.current_line_num++; if (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { + intern->u.file.current_line_num++; spl_filesystem_file_free_line(intern); } } diff --git a/ext/spl/tests/gh8121.csv b/ext/spl/tests/gh8121.csv new file mode 100644 index 0000000000000..05fe5b0ac6242 --- /dev/null +++ b/ext/spl/tests/gh8121.csv @@ -0,0 +1,5 @@ +id,status,on_sale,brand,name,link,meta_title,meta_desc,description +1,2,15,Samsung,M21,samsung-m21,Samsung M21,Samsung M21,Samsung M21 +2,2,15,Samsung,M32,samsung-m32,Samsung M32,Samsung M32,Samsung M32 +3,2,15,Samsung,M21,samsung-m21,Samsung M21,Samsung M21,Samsung M21 +4,2,15,Samsung,M32,samsung-m32,Samsung M32,Samsung M32,Samsung M32 diff --git a/ext/spl/tests/gh8121.phpt b/ext/spl/tests/gh8121.phpt new file mode 100644 index 0000000000000..3e339cb52200c --- /dev/null +++ b/ext/spl/tests/gh8121.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-8121 (SplFileObject - seek and key with csv file inconsistent) +--FILE-- +setFlags($flags); + $file->seek(0); + var_dump($file->key()); + $file->seek(1); + var_dump($file->key()); + $file->seek(2); + var_dump($file->key()); + $file->seek(3); + var_dump($file->key()); +} +?> +--EXPECT-- +flags: 15 +int(0) +int(1) +int(2) +int(3) +flags: 7 +int(0) +int(1) +int(2) +int(3) +flags: 5 +int(0) +int(1) +int(2) +int(3) From e3ef7bbbb87bcbf6154a0a4854127b9cea8f92ff Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 5 Feb 2022 13:00:17 +0100 Subject: [PATCH 188/227] Adjust filename/lineno for constant expressions Closes GH-7771 Closes GH-8124 --- NEWS | 1 + Zend/tests/bug41633_2.phpt | 2 +- Zend/tests/gh7771_1.phpt | 15 +++++++++++++++ Zend/tests/gh7771_1_definition.inc | 5 +++++ Zend/tests/gh7771_2.phpt | 15 +++++++++++++++ Zend/tests/gh7771_2_definition.inc | 8 ++++++++ Zend/zend_ast.c | 14 ++++++++++++++ Zend/zend_execute_API.c | 27 +++++++++++++++++---------- Zend/zend_globals.h | 4 ++++ 9 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 Zend/tests/gh7771_1.phpt create mode 100644 Zend/tests/gh7771_1_definition.inc create mode 100644 Zend/tests/gh7771_2.phpt create mode 100644 Zend/tests/gh7771_2_definition.inc diff --git a/NEWS b/NEWS index 49d3d7bac0ae2..0bb7114961c14 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PHP NEWS - Core: . Fixed bug #81380 (Observer may not be initialized properly). (krakjoe) + . Fixed bug GH-7771 (Fix filename/lineno of constant expressions). (ilutov) - Intl: . Update all grandfathered language tags with preferred values diff --git a/Zend/tests/bug41633_2.phpt b/Zend/tests/bug41633_2.phpt index 975d2218b55e3..bb768c0e11743 100644 --- a/Zend/tests/bug41633_2.phpt +++ b/Zend/tests/bug41633_2.phpt @@ -11,4 +11,4 @@ echo Foo::A."\n"; Fatal error: Uncaught Error: Undefined constant self::B in %s:%d Stack trace: #0 {main} - thrown in %sbug41633_2.php on line 5 + thrown in %sbug41633_2.php on line 3 diff --git a/Zend/tests/gh7771_1.phpt b/Zend/tests/gh7771_1.phpt new file mode 100644 index 0000000000000..dc24b4041c716 --- /dev/null +++ b/Zend/tests/gh7771_1.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-7771 (Incorrect file/line for class constant expression exceptions) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_1_definition.inc:4 +Stack trace: +#0 {main} + thrown in %sgh7771_1_definition.inc on line 4 diff --git a/Zend/tests/gh7771_1_definition.inc b/Zend/tests/gh7771_1_definition.inc new file mode 100644 index 0000000000000..16e94f41a0fa4 --- /dev/null +++ b/Zend/tests/gh7771_1_definition.inc @@ -0,0 +1,5 @@ + +--EXPECTF-- +Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_2_definition.inc:6 +Stack trace: +#0 {main} + thrown in %sgh7771_2_definition.inc on line 6 diff --git a/Zend/tests/gh7771_2_definition.inc b/Zend/tests/gh7771_2_definition.inc new file mode 100644 index 0000000000000..0162a9c8bf1ed --- /dev/null +++ b/Zend/tests/gh7771_2_definition.inc @@ -0,0 +1,8 @@ +child[0]); zend_string *const_name = zend_ast_get_str(ast->child[1]); + + zend_string *previous_filename; + zend_long previous_lineno; + if (scope) { + previous_filename = EG(filename_override); + previous_lineno = EG(lineno_override); + EG(filename_override) = scope->info.user.filename; + EG(lineno_override) = zend_ast_get_lineno(ast); + } zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr); + if (scope) { + EG(filename_override) = previous_filename; + EG(lineno_override) = previous_lineno; + } if (UNEXPECTED(zv == NULL)) { ZVAL_UNDEF(result); @@ -951,6 +964,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) zend_ast *new = (zend_ast*)buf; new->kind = ast->kind; new->attr = ast->attr; + new->lineno = ast->lineno; buf = (void*)((char*)buf + zend_ast_size(children)); for (i = 0; i < children; i++) { if (ast->child[i]) { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6a34971bd8a0e..e791f986f8e74 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -192,6 +192,9 @@ void init_executor(void) /* {{{ */ EG(num_errors) = 0; EG(errors) = NULL; + EG(filename_override) = NULL; + EG(lineno_override) = -1; + zend_fiber_init(); zend_weakrefs_init(); @@ -462,6 +465,8 @@ void shutdown_executor(void) /* {{{ */ if (EG(ht_iterators) != EG(ht_iterators_slots)) { efree(EG(ht_iterators)); } + + ZEND_ASSERT(EG(filename_override) == NULL); } #if ZEND_DEBUG @@ -591,21 +596,18 @@ ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t a ZEND_API const char *zend_get_executed_filename(void) /* {{{ */ { - zend_execute_data *ex = EG(current_execute_data); - - while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { - ex = ex->prev_execute_data; - } - if (ex) { - return ZSTR_VAL(ex->func->op_array.filename); - } else { - return "[no active file]"; - } + zend_string *filename = zend_get_executed_filename_ex(); + return filename != NULL ? ZSTR_VAL(filename) : "[no active file]"; } /* }}} */ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */ { + zend_string *filename_override = EG(filename_override); + if (filename_override != NULL) { + return filename_override; + } + zend_execute_data *ex = EG(current_execute_data); while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { @@ -621,6 +623,11 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */ ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */ { + zend_long lineno_override = EG(lineno_override); + if (lineno_override != -1) { + return lineno_override; + } + zend_execute_data *ex = EG(current_execute_data); while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 1726dee9ac12a..ccee57b3fb1bd 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -266,6 +266,10 @@ struct _zend_executor_globals { uint32_t num_errors; zend_error_info **errors; + /* Override filename or line number of thrown errors and exceptions */ + zend_string *filename_override; + zend_long lineno_override; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; From 7eb972c4569332516c3f6dd8785703b95233b6ef Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 31 Dec 2021 04:55:04 +0000 Subject: [PATCH 189/227] Fix Solaris builds of ext/sockets We enable the proper ancillary data handling layout and API. Closes GH-7859. --- NEWS | 3 +++ ext/sockets/conversions.c | 4 ++++ ext/sockets/sendrecvmsg.c | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/NEWS b/NEWS index f4631f96c7d7b..1319297870136 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,9 @@ PHP NEWS - Pcntl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) +- Sockets: + . Fixed Solaris builds. (David Carlier) + - SPL: . Fixed bug GH-8121 (SplFileObject - seek and key with csv file inconsistent). (cmb) diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index ecf3fb47b508d..1b7124cae5f34 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1,3 +1,7 @@ +#ifdef __sun +/* to enable 'new' ancillary data layout instead */ +# define _XPG4_2 +#endif #include "sockaddr_conv.h" #include "conversions.h" #include "sendrecvmsg.h" /* for ancillary registry */ diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index 906e6b81007b5..f7326986cb22d 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -14,6 +14,10 @@ +----------------------------------------------------------------------+ */ +#ifdef __sun +/* to enable 'new' ancillary data layout instead */ +# define _XPG4_2 +#endif #include #include "php_sockets.h" #include "sendrecvmsg.h" From c6a53f9499ea85758d3b0fad040dbe69929e8af5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Mar 2022 10:50:31 +0300 Subject: [PATCH 190/227] Fix non-reentirant startiong or error recording from error handler Fixes oss-fuzz #45398 --- Zend/tests/record_errors_001.phpt | 15 +++++++++++++++ Zend/zend.c | 19 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/record_errors_001.phpt diff --git a/Zend/tests/record_errors_001.phpt b/Zend/tests/record_errors_001.phpt new file mode 100644 index 0000000000000..509a227a5ebe7 --- /dev/null +++ b/Zend/tests/record_errors_001.phpt @@ -0,0 +1,15 @@ +--TEST-- +Error recording in error handler +--FILE-- + +--EXPECT-- +Error: Return type of DateTime@anonymous::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice diff --git a/Zend/zend.c b/Zend/zend.c index 8566461dfb850..5f9325cb31c35 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1343,6 +1343,10 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( zend_stack loop_var_stack; zend_stack delayed_oplines_stack; int type = orig_type & E_ALL; + bool orig_record_errors; + uint32_t orig_num_errors; + zend_error_info **orig_errors; + zend_result res; /* If we're executing a function during SCCP, count any warnings that may be emitted, * but don't perform any other error handling. */ @@ -1436,7 +1440,20 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( CG(in_compilation) = 0; } - if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) { + orig_record_errors = EG(record_errors); + orig_num_errors = EG(num_errors); + orig_errors = EG(errors); + EG(record_errors) = false; + EG(num_errors) = 0; + EG(errors) = NULL; + + res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params); + + EG(record_errors) = orig_record_errors; + EG(num_errors) = orig_num_errors; + EG(errors) = orig_errors; + + if (res == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_FALSE) { zend_error_cb(orig_type, error_filename, error_lineno, message); From 151d2ac5ae73ebc0fc5613b6f821f433e6f3aac3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Mar 2022 11:32:23 +0300 Subject: [PATCH 191/227] Fixed memory leak Fixes oss-fuzz #45191 --- ext/opcache/Optimizer/sccp.c | 6 +++--- ext/opcache/tests/opt/sccp_038.phpt | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/opt/sccp_038.phpt diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 8163929b3911f..903a4122c1033 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -1545,13 +1545,13 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o dup_partial_object(&zv, op1); ct_eval_assign_obj(&zv, &tmp2, op2); - if (opline->opcode == ZEND_PRE_INC_OBJ - || opline->opcode == ZEND_PRE_DEC_OBJ) { + if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_PRE_DEC_OBJ) { SET_RESULT(result, &tmp2); - zval_ptr_dtor_nogc(&tmp1); } else { SET_RESULT(result, &tmp1); } + zval_ptr_dtor_nogc(&tmp1); + zval_ptr_dtor_nogc(&tmp2); SET_RESULT(op1, &zv); zval_ptr_dtor_nogc(&zv); break; diff --git a/ext/opcache/tests/opt/sccp_038.phpt b/ext/opcache/tests/opt/sccp_038.phpt new file mode 100644 index 0000000000000..fdf663e87c362 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_038.phpt @@ -0,0 +1,18 @@ +--TEST-- +SCCP 038: Memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +$b = ~$b = $a = '##'; + $obj->$a++; +} +foo(); +?> +DONE +--EXPECT-- +DONE From 6c3816cee555148c8ef59109dc1e49a68c961cf8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Mar 2022 12:39:10 +0300 Subject: [PATCH 192/227] Tracing JIT: Eliminate useless guards for CONCAT Fixes oss-fuzz #45285 --- ext/opcache/jit/zend_jit_trace.c | 10 ++++-- ext/opcache/tests/jit/fetch_dim_r_012.phpt | 38 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/fetch_dim_r_012.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 5244b1eaa315b..2b1f85ef23346 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1612,6 +1612,14 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin } ADD_OP1_TRACE_GUARD(); break; + case ZEND_CONCAT: + case ZEND_FAST_CONCAT: + if ((opline->op1_type == IS_CONST || orig_op1_type == IS_STRING) + && (opline->op2_type == IS_CONST || orig_op2_type == IS_STRING)) { + ADD_OP2_TRACE_GUARD(); + ADD_OP1_TRACE_GUARD(); + } + break; case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: @@ -1630,8 +1638,6 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin case ZEND_SUB: case ZEND_MUL: // case ZEND_DIV: // TODO: check for division by zero ??? - case ZEND_CONCAT: - case ZEND_FAST_CONCAT: ADD_OP2_TRACE_GUARD(); /* break missing intentionally */ case ZEND_ECHO: diff --git a/ext/opcache/tests/jit/fetch_dim_r_012.phpt b/ext/opcache/tests/jit/fetch_dim_r_012.phpt new file mode 100644 index 0000000000000..6356851290227 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_012.phpt @@ -0,0 +1,38 @@ +--TEST-- +JIT FETCH_DIM_R: 012 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECT-- +array(6) { + [0]=> + &NULL + [1]=> + &NULL + [2]=> + &NULL + [3]=> + &NULL + [4]=> + &NULL + [5]=> + &NULL +} +array(1) { + [" "]=> + int(0) +} From 770a544af4c0c3dcff115e60b607f8782a7d21d4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Mar 2022 14:30:27 +0300 Subject: [PATCH 193/227] Optimizer: Fix inorrect constant substitution in FETCH_LIST_R Fixes oss-fuzz #45429 --- Zend/Optimizer/block_pass.c | 8 +++++++- ext/opcache/tests/opt/block_pass_003.phpt | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/block_pass_003.phpt diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 18f5a98cc1571..00454d5d96fb3 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -166,7 +166,13 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } else { zval c; ZVAL_COPY(&c, &ZEND_OP1_LITERAL(src)); - if (zend_optimizer_update_op1_const(op_array, opline, &c)) { + if (opline->opcode != ZEND_CASE + && opline->opcode != ZEND_CASE_STRICT + && opline->opcode != ZEND_FETCH_LIST_R + && opline->opcode != ZEND_SWITCH_LONG + && opline->opcode != ZEND_SWITCH_STRING + && opline->opcode != ZEND_MATCH + && zend_optimizer_update_op1_const(op_array, opline, &c)) { VAR_SOURCE(op1) = NULL; literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); diff --git a/ext/opcache/tests/opt/block_pass_003.phpt b/ext/opcache/tests/opt/block_pass_003.phpt new file mode 100644 index 0000000000000..25d32e1e4d70e --- /dev/null +++ b/ext/opcache/tests/opt/block_pass_003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Block Pass 003: Inorrect constant substitution in FETCH_LIST_R +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--EXTENSIONS-- +opcache +--FILE-- + +DONE +--EXPECT-- +DONE From 2b2aeb989e4e18582b0a665a33dfd8712275dd5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 7 Mar 2022 12:04:21 +0100 Subject: [PATCH 194/227] Fix GH-8160: ZTS support on Alpine is broken We need to export `__MUSL__` so that phpize builds can see the proper macro, and also need to fix "_tsrm_ls_cache" usage for musl. Closes GH-8180. --- NEWS | 1 + TSRM/TSRM.c | 4 ++-- configure.ac | 2 +- ext/opcache/jit/zend_jit_x86.dasc | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 1319297870136..6b31ab2f7c84b 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ PHP NEWS . Fixed freeing of internal attribute arguments. (Bob) . Fixed bug GH-8070 (memory leak of internal function attribute hash). (Tim Düsterhus) + . Fixed bug GH-8160 (ZTS support on Alpine is broken). (Michael Voříšek) - Intl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 3d93accddde77..c2a9130b5d4d4 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -736,13 +736,13 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void) #if defined(__APPLE__) && defined(__x86_64__) // TODO: Implement support for fast JIT ZTS code ??? return 0; -#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) +#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" : "=r" (ret)); return ret; -#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) +#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("leal _tsrm_ls_cache@ntpoff,%0" diff --git a/configure.ac b/configure.ac index 8f83ad06c07f6..a60c3533897ca 100644 --- a/configure.ac +++ b/configure.ac @@ -260,7 +260,7 @@ AC_MSG_CHECKING([whether we are using musl libc]) if command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl then AC_MSG_RESULT(yes) - CPPFLAGS="$CPPFLAGS -D__MUSL__" + AC_DEFINE([__MUSL__], [1], [Define when using musl libc]) else AC_MSG_RESULT(no) fi diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index b0635a77029bc..bcf5459ba4212 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -2974,7 +2974,7 @@ static int zend_jit_setup(void) # elif defined(__GNUC__) && defined(__x86_64__) tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); if (tsrm_ls_cache_tcb_offset == 0) { -#if defined(__has_attribute) && __has_attribute(tls_model) && !defined(__FreeBSD__) && !defined(__OpenBSD__) +#if defined(__has_attribute) && __has_attribute(tls_model) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" @@ -2993,7 +2993,7 @@ static int zend_jit_setup(void) # elif defined(__GNUC__) && defined(__i386__) tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); if (tsrm_ls_cache_tcb_offset == 0) { -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) size_t ret; asm ("leal _tsrm_ls_cache@ntpoff,%0\n" From 0db03c4110b70e7515c98cf17d2c3c5b9ed4a034 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 10 Mar 2022 13:16:48 +0100 Subject: [PATCH 195/227] Improve sesson write failure message for user error handlers Closes GH-7787 Closes GH-8186 --- NEWS | 4 ++ ext/session/php_session.h | 1 + ext/session/session.c | 25 +++++++++- ext/session/tests/gh7787.phpt | 90 +++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 ext/session/tests/gh7787.phpt diff --git a/NEWS b/NEWS index 0bb7114961c14..dd939687ecaf6 100644 --- a/NEWS +++ b/NEWS @@ -35,4 +35,8 @@ PHP NEWS . add ZipArchive::getStreamName() method . add ZipArchive::getStreamIndex() method +- Session: + . Fixed bug GH-7787 (Improve session write failure message for user error + handlers). (ilutov) + <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/ext/session/php_session.h b/ext/session/php_session.h index bc8c3548c7059..ef139196ca900 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -176,6 +176,7 @@ typedef struct _php_ps_globals { } mod_user_names; int mod_user_implemented; int mod_user_is_open; + zend_string *mod_user_class_name; const struct ps_serializer_struct *serializer; zval http_session_vars; bool auto_start; diff --git a/ext/session/session.c b/ext/session/session.c index 32e2f33ae3028..8212ad23cd7bb 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -472,6 +472,9 @@ static void php_session_save_current_state(int write) /* {{{ */ if (write) { IF_SESSION_VARS() { + zend_string *handler_class_name = PS(mod_user_class_name); + const char *handler_function_name; + if (PS(mod_data) || PS(mod_user_implemented)) { zend_string *val; @@ -483,12 +486,15 @@ static void php_session_save_current_state(int write) /* {{{ */ && zend_string_equals(val, PS(session_vars)) ) { ret = PS(mod)->s_update_timestamp(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); + handler_function_name = handler_class_name != NULL ? "updateTimestamp" : "update_timestamp"; } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); + handler_function_name = "write"; } zend_string_release_ex(val, 0); } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), ZSTR_EMPTY_ALLOC(), PS(gc_maxlifetime)); + handler_function_name = "write"; } } @@ -499,9 +505,14 @@ static void php_session_save_current_state(int write) /* {{{ */ "is correct (%s)", PS(mod)->s_name, PS(save_path)); + } else if (handler_class_name != NULL) { + php_error_docref(NULL, E_WARNING, "Failed to write session data using user " + "defined save handler. (session.save_path: %s, handler: %s::%s)", PS(save_path), + ZSTR_VAL(handler_class_name), handler_function_name); } else { php_error_docref(NULL, E_WARNING, "Failed to write session data using user " - "defined save handler. (session.save_path: %s)", PS(save_path)); + "defined save handler. (session.save_path: %s, handler: %s)", PS(save_path), + handler_function_name); } } } @@ -2042,6 +2053,12 @@ PHP_FUNCTION(session_set_save_handler) ++i; } ZEND_HASH_FOREACH_END(); + + if (PS(mod_user_class_name)) { + zend_string_release(PS(mod_user_class_name)); + } + PS(mod_user_class_name) = zend_string_copy(Z_OBJCE_P(obj)->name); + if (register_shutdown) { /* create shutdown function */ php_shutdown_function_entry shutdown_function_entry; @@ -2095,6 +2112,11 @@ PHP_FUNCTION(session_set_save_handler) RETURN_FALSE; } + if (PS(mod_user_class_name)) { + zend_string_release(PS(mod_user_class_name)); + PS(mod_user_class_name) = NULL; + } + /* remove shutdown function */ remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") - 1); @@ -2775,6 +2797,7 @@ static PHP_GINIT_FUNCTION(ps) /* {{{ */ ps_globals->session_status = php_session_none; ps_globals->default_mod = NULL; ps_globals->mod_user_implemented = 0; + ps_globals->mod_user_class_name = NULL; ps_globals->mod_user_is_open = 0; ps_globals->session_vars = NULL; ps_globals->set_handler = 0; diff --git a/ext/session/tests/gh7787.phpt b/ext/session/tests/gh7787.phpt new file mode 100644 index 0000000000000..b38398827b087 --- /dev/null +++ b/ext/session/tests/gh7787.phpt @@ -0,0 +1,90 @@ +--TEST-- +GH-7787: Provide more SessionHandler failure information +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.use_strict_mode=0 +session.save_handler=files +--FILE-- + true, + fn() => true, + fn() => 'foo|s:3:"foo";', + fn() => false, + fn() => true, + fn() => true, + fn() => sha1(random_bytes(32)), + fn() => true, + fn() => false, +); + +session_start(); +$_SESSION['foo'] = 'bar'; +session_write_close(); + +session_start(); +session_write_close(); + +?> +--EXPECTF-- +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: MySessionHandler::write) in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: MySessionHandler::updateTimestamp) in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: write) in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: update_timestamp) in %s on line %d From d0a0518798411a39f8c0cb40567cdb3511e8ae26 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Mar 2022 17:31:38 +0100 Subject: [PATCH 196/227] Make DirectoryIterator current() / key() return types tentative Fixes GH-8192. --- NEWS | 2 ++ ext/spl/spl_directory.stub.php | 10 ++++++++-- ext/spl/spl_directory_arginfo.h | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index ea7ce8b9cd1e6..5b0966a3e96ed 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,8 @@ PHP NEWS - SPL: . Fixed bug GH-8121 (SplFileObject - seek and key with csv file inconsistent). (cmb) + . Fixed bug GH-8192 (Cannot override DirectoryIterator::current() without + return typehint in 8.1). (Nikita) - Standard: . Fixed bug GH-8048 (Force macOS to use statfs). (risner) diff --git a/ext/spl/spl_directory.stub.php b/ext/spl/spl_directory.stub.php index 97942df9f0f30..ceb4b7124b5df 100644 --- a/ext/spl/spl_directory.stub.php +++ b/ext/spl/spl_directory.stub.php @@ -123,10 +123,16 @@ public function rewind(): void {} /** @tentative-return-type */ public function valid(): bool {} - /** @return int */ + /** + * @tentative-return-type + * @return int + */ public function key(): mixed {} // TODO change return type to string - /** @return DirectoryIterator */ + /** + * @tentative-return-type + * @return DirectoryIterator + */ public function current(): mixed {} // TODO narrow return type /** @tentative-return-type */ diff --git a/ext/spl/spl_directory_arginfo.h b/ext/spl/spl_directory_arginfo.h index 03a0fd044afef..bcdb51ea54254 100644 --- a/ext/spl/spl_directory_arginfo.h +++ b/ext/spl/spl_directory_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: eab71d8a7172dba2dac3c6fa97b2064c7a99191f */ + * Stub hash: 3f2caf1c46760d8ef629ccb2e94ab0dba09f713b */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -102,7 +102,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_DirectoryIterator_valid arginfo_class_SplFileInfo_isWritable -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DirectoryIterator_key, 0, 0, IS_MIXED, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DirectoryIterator_key, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() #define arginfo_class_DirectoryIterator_current arginfo_class_DirectoryIterator_key From dd62ec065e71515234351d8b57778af1b946f7f0 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sun, 13 Mar 2022 13:48:21 +0000 Subject: [PATCH 197/227] Refactor php_next_utf8_char() to use zend_result --- ext/json/json_encoder.c | 3 +-- ext/standard/html.c | 10 +++++----- ext/standard/html.h | 2 +- ext/standard/string.c | 2 +- ext/xml/xml.c | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index b0f703041b068..cae2f80ea5d1d 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -316,7 +316,6 @@ static int php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder) /* {{{ */ { - int status; unsigned int us; size_t pos, checkpoint; char *dst; @@ -371,7 +370,7 @@ static int php_json_escape_string( } us = (unsigned char)s[0]; if (UNEXPECTED(us >= 0x80)) { - + zend_result status; us = php_next_utf8_char((unsigned char *)s, len, &pos, &status); /* check whether UTF8 character is correct */ diff --git a/ext/standard/html.c b/ext/standard/html.c index b93ce95df1900..779fe549599bf 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -95,7 +95,7 @@ static inline unsigned int get_next_char( const unsigned char *str, size_t str_len, size_t *cursor, - int *status) + zend_result *status) { size_t pos = *cursor; unsigned int this_char = 0; @@ -356,7 +356,7 @@ PHPAPI unsigned int php_next_utf8_char( const unsigned char *str, size_t str_len, size_t *cursor, - int *status) + zend_result *status) { return get_next_char(cs_utf_8, str, str_len, cursor, status); } @@ -1045,8 +1045,8 @@ static inline void find_entity_for_char( *entity_len = c->data.ent.entity_len; } else { /* peek at next char */ - size_t cursor_before = *cursor; - int status = SUCCESS; + size_t cursor_before = *cursor; + zend_result status = SUCCESS; unsigned next_char; if (!(*cursor < oldlen)) @@ -1156,7 +1156,7 @@ PHPAPI zend_string *php_escape_html_entities_ex(const unsigned char *old, size_t const unsigned char *mbsequence = NULL; size_t mbseqlen = 0, cursor_before = cursor; - int status = SUCCESS; + zend_result status = SUCCESS; unsigned int this_char = get_next_char(charset, old, oldlen, &cursor, &status); /* guarantee we have at least 40 bytes to write. diff --git a/ext/standard/html.h b/ext/standard/html.h index 2a4757062165b..e7e9486d406ac 100644 --- a/ext/standard/html.h +++ b/ext/standard/html.h @@ -47,6 +47,6 @@ void register_html_constants(INIT_FUNC_ARGS); PHPAPI zend_string *php_escape_html_entities(const unsigned char *old, size_t oldlen, int all, int flags, const char *hint_charset); PHPAPI zend_string *php_escape_html_entities_ex(const unsigned char *old, size_t oldlen, int all, int flags, const char *hint_charset, bool double_encode, bool quiet); PHPAPI zend_string *php_unescape_html_entities(zend_string *str, int all, int flags, const char *hint_charset); -PHPAPI unsigned int php_next_utf8_char(const unsigned char *str, size_t str_len, size_t *cursor, int *status); +PHPAPI unsigned int php_next_utf8_char(const unsigned char *str, size_t str_len, size_t *cursor, zend_result *status); #endif /* HTML_H */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 36e8c1a737e77..826fa338be047 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -6056,7 +6056,7 @@ static zend_string *php_utf8_decode(const char *s, size_t len) str = zend_string_alloc(len, 0); ZSTR_LEN(str) = 0; while (pos < len) { - int status = FAILURE; + zend_result status = FAILURE; c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status); /* The lower 256 codepoints of Unicode are identical to Latin-1, diff --git a/ext/xml/xml.c b/ext/xml/xml.c index be69940545cda..3753320dd0144 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -550,8 +550,8 @@ static zend_string *xml_utf8_decode(const XML_Char *s, size_t len, const XML_Cha str = zend_string_alloc(len, 0); ZSTR_LEN(str) = 0; while (pos < len) { - int status = FAILURE; - c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status); + zend_result status = FAILURE; + c = php_next_utf8_char((const unsigned char*)s, len, &pos, &status); if (status == FAILURE || c > 0xFFU) { c = '?'; From 9792f0db76c25af41fbde37265d3125996a64e71 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 14 Mar 2022 09:48:58 +0300 Subject: [PATCH 198/227] JIT: Fix type store Fixes oss-fuzz #45190 --- ext/opcache/jit/zend_jit_trace.c | 14 ++++++-------- ext/opcache/tests/jit/reg_alloc_012.phpt | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 ext/opcache/tests/jit/reg_alloc_012.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 2b1f85ef23346..8dee57147b77f 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4642,18 +4642,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } CHECK_OP2_TRACE_TYPE(); op1_info = OP1_INFO(); - if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG - || (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_DOUBLE) { - if (STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_LONG - && STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_DOUBLE) { - /* type may be not set */ - op1_info |= MAY_BE_NULL; - } - } CHECK_OP1_TRACE_TYPE(); op1_def_info = OP1_DEF_INFO(); op1_addr = OP1_REG_ADDR(); op1_def_addr = OP1_DEF_REG_ADDR(); + if (Z_MODE(op1_def_addr) != IS_REG && + STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != + STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var))) { + /* type may be not set */ + op1_info |= MAY_BE_NULL; + } if (orig_op1_type != IS_UNKNOWN) { if (orig_op1_type & IS_TRACE_REFERENCE) { if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, diff --git a/ext/opcache/tests/jit/reg_alloc_012.phpt b/ext/opcache/tests/jit/reg_alloc_012.phpt new file mode 100644 index 0000000000000..c21cd797f1963 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_012.phpt @@ -0,0 +1,22 @@ +--TEST-- +Register Alloction 012: Missed type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file From efb014dda2faa7804c77624433c07366685fd5f0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 14 Mar 2022 11:07:49 +0300 Subject: [PATCH 199/227] Reset EG(filename_override) after fatal error Fixes oss-fuzz #45492 --- Zend/tests/gh7771_3.phpt | 16 ++++++++++++++++ Zend/zend_ast.c | 11 ++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/gh7771_3.phpt diff --git a/Zend/tests/gh7771_3.phpt b/Zend/tests/gh7771_3.phpt new file mode 100644 index 0000000000000..f6780814b89b4 --- /dev/null +++ b/Zend/tests/gh7771_3.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-7771.3 (Incorrect file/line for class constant expression exceptions) +--FILE-- + 'class y{const y="$y";}', + 'D' => 'class D{const HW=space1\C::y;}' +]; +spl_autoload_register(function($class) use ($classlist) { + eval($classlist[$class]); +}); +var_dump(D::HW); +?> +--EXPECTF-- +Fatal error: Constant expression contains invalid operations in %sgh7771_3.php(7) : eval()'d code(1) : eval()'d code on line 1 + diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 624471432d2d3..f1ea28112bdde 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -789,6 +789,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast { zend_string *class_name = zend_ast_get_str(ast->child[0]); zend_string *const_name = zend_ast_get_str(ast->child[1]); + zval *zv; + bool bailout = 0; zend_string *previous_filename; zend_long previous_lineno; @@ -798,11 +800,18 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast EG(filename_override) = scope->info.user.filename; EG(lineno_override) = zend_ast_get_lineno(ast); } - zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr); + zend_try { + zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr); + } zend_catch { + bailout = 1; + } zend_end_try(); if (scope) { EG(filename_override) = previous_filename; EG(lineno_override) = previous_lineno; } + if (bailout) { + zend_bailout(); + } if (UNEXPECTED(zv == NULL)) { ZVAL_UNDEF(result); From e20f955e44bdfef974ea3b3fc3e13abc97403471 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 14 Mar 2022 11:46:45 +0300 Subject: [PATCH 200/227] JIT: Fix register allocation Fixes oss-fuzz #45487 --- ext/opcache/jit/zend_jit_x86.dasc | 1 + ext/opcache/tests/jit/reg_alloc_013.phpt | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 ext/opcache/tests/jit/reg_alloc_013.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index bcf5459ba4212..78552b5eee2a6 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -15982,6 +15982,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend !(op2_info & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)-MAY_BE_LONG))) { regset = ZEND_REGSET_EMPTY; if (opline->op2_type == IS_CONST && + opline->op1_type != IS_CONST && Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) == IS_LONG && zend_long_is_power_of_two(Z_LVAL_P(RT_CONSTANT(opline, opline->op2))) && OP1_HAS_RANGE() && diff --git a/ext/opcache/tests/jit/reg_alloc_013.phpt b/ext/opcache/tests/jit/reg_alloc_013.phpt new file mode 100644 index 0000000000000..01d4640ddc8ac --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_013.phpt @@ -0,0 +1,19 @@ +--TEST-- +Register Alloction 013: Division by zero +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $j in %sreg_alloc_013.php on line 3 +DONE \ No newline at end of file From 2b7431cf5b2157c71265616c46a455212cf949d5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 14 Mar 2022 12:57:37 +0300 Subject: [PATCH 201/227] Fix memory leak Fixed oss-fuzz #45535 --- ext/opcache/Optimizer/zend_inference.c | 14 ++++++++++++++ ext/opcache/tests/jit/assign_052.phpt | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_052.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index db8112d29445b..c7514f55e2480 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2748,6 +2748,20 @@ static zend_always_inline int _zend_update_type_info( tmp &= ~MAY_BE_REF; tmp |= MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_RC1|MAY_BE_RCN; } + if ((tmp & (MAY_BE_RC1|MAY_BE_RCN)) == MAY_BE_RCN) { + /* refcount may be indirectly decremented. Make an exception if the result is used in the next instruction */ + if (!ssa_opcodes) { + if (ssa->vars[ssa_op->result_def].use_chain < 0 + || opline + 1 != op_array->opcodes + ssa->vars[ssa_op->result_def].use_chain) { + tmp |= MAY_BE_RC1; + } + } else { + if (ssa->vars[ssa_op->result_def].use_chain < 0 + || opline + 1 != ssa_opcodes[ssa->vars[ssa_op->result_def].use_chain]) { + tmp |= MAY_BE_RC1; + } + } + } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); COPY_SSA_OBJ_TYPE(ssa_op->op2_use, ssa_op->result_def); } diff --git a/ext/opcache/tests/jit/assign_052.phpt b/ext/opcache/tests/jit/assign_052.phpt new file mode 100644 index 0000000000000..902d223b423ce --- /dev/null +++ b/ext/opcache/tests/jit/assign_052.phpt @@ -0,0 +1,20 @@ +--TEST-- +JIT ASSIGN: incorrect reference counting +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + $n[$i = $j] = $s = $a . $a = $f; + } +} +@foo(); +?> +DONE +--EXPECT-- +DONE From 33eec378308d59aaf498a37ece9cffad12d365b9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 14 Mar 2022 13:03:21 +0300 Subject: [PATCH 202/227] Skip test for preloading --- Zend/tests/record_errors_001.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Zend/tests/record_errors_001.phpt b/Zend/tests/record_errors_001.phpt index 509a227a5ebe7..dd3c0ba487ea0 100644 --- a/Zend/tests/record_errors_001.phpt +++ b/Zend/tests/record_errors_001.phpt @@ -1,5 +1,9 @@ --TEST-- Error recording in error handler +--SKIPIF-- + --FILE-- Date: Thu, 10 Mar 2022 19:21:06 +0100 Subject: [PATCH 203/227] Fix GH-8068: mysqli_fetch_object creates inaccessible properties When fetching into objects, we need to create object style hash tables, i.e. where numeric column names are stored as string keys instead of integer keys. Instead of the slightly more efficient alternative to create the desired hash table in the first place, we go for the more readable implementation and convert the array style hash table using `zend_symtable_to_proptable()`. Co-authored-by: Kamil Tekiela Closes GH-8189. --- NEWS | 4 ++++ ext/mysqli/mysqli.c | 8 +++++--- ext/mysqli/tests/gh8068.phpt | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 ext/mysqli/tests/gh8068.phpt diff --git a/NEWS b/NEWS index 6b31ab2f7c84b..f0382c538777e 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS - Intl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) +- MySQLi: + . Fixed bug GH-8068 (mysqli_fetch_object creates inaccessible properties). + (cmb) + - Pcntl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 852eb02c6bc90..165893b32f4a1 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -1198,11 +1198,13 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags ZVAL_COPY_VALUE(&dataset, return_value); object_init_ex(return_value, ce); + HashTable *prop_table = zend_symtable_to_proptable(Z_ARR(dataset)); + zval_ptr_dtor(&dataset); if (!ce->default_properties_count && !ce->__set) { - Z_OBJ_P(return_value)->properties = Z_ARR(dataset); + Z_OBJ_P(return_value)->properties = prop_table; } else { - zend_merge_properties(return_value, Z_ARRVAL(dataset)); - zval_ptr_dtor(&dataset); + zend_merge_properties(return_value, prop_table); + zend_array_release(prop_table); } if (ce->constructor) { diff --git a/ext/mysqli/tests/gh8068.phpt b/ext/mysqli/tests/gh8068.phpt new file mode 100644 index 0000000000000..db6ce230b936c --- /dev/null +++ b/ext/mysqli/tests/gh8068.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-8068 (mysqli_fetch_object creates inaccessible properties) +--SKIPIF-- + +--FILE-- +query('SELECT 42'); +$obj = $res->fetch_object(); +var_dump( + $obj, + $obj->{42} +); +?> +--EXPECT-- +object(stdClass)#4 (1) { + ["42"]=> + string(2) "42" +} +string(2) "42" From b92ae85b25142d0f8a0bdd94b7caaf98b20c9112 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 14 Mar 2022 15:14:27 +0100 Subject: [PATCH 204/227] =?UTF-8?q?Fix=20typo=20(--EXTENSION--=20=E2=86=92?= =?UTF-8?q?=20--EXTENSIONS--)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ext/mysqli/tests/gh8068.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mysqli/tests/gh8068.phpt b/ext/mysqli/tests/gh8068.phpt index 635bd66b8446b..5d7f55c9c4d40 100644 --- a/ext/mysqli/tests/gh8068.phpt +++ b/ext/mysqli/tests/gh8068.phpt @@ -1,6 +1,6 @@ --TEST-- GH-8068 (mysqli_fetch_object creates inaccessible properties) ---EXTENSION-- +--EXTENSIONS-- mysqli --SKIPIF-- Date: Wed, 16 Mar 2022 22:53:41 +0000 Subject: [PATCH 205/227] Use more appropriate types in JSON extension (#8194) Mainly zend_result --- ext/json/json.c | 8 ++++---- ext/json/json_encoder.c | 16 ++++++++-------- ext/json/php_json.h | 8 ++++---- ext/json/php_json_encoder.h | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ext/json/json.c b/ext/json/json.c index 2d7846a5dbed9..b21ed4d14b20e 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -141,10 +141,10 @@ static PHP_MINFO_FUNCTION(json) } /* }}} */ -PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth) /* {{{ */ +PHP_JSON_API zend_result php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth) /* {{{ */ { php_json_encoder encoder; - int return_code; + zend_result return_code; php_json_encode_init(&encoder); encoder.max_depth = depth; @@ -156,7 +156,7 @@ PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend } /* }}} */ -PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */ +PHP_JSON_API zend_result php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */ { return php_json_encode_ex(buf, val, options, JSON_G(encode_max_depth)); } @@ -195,7 +195,7 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ } /* }}} */ -PHP_JSON_API int php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ +PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ { php_json_parser parser; diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index cae2f80ea5d1d..13c5ed0aad683 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -31,7 +31,7 @@ static const char digits[] = "0123456789abcdef"; -static int php_json_escape_string( +static zend_result php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder); @@ -71,7 +71,7 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options, php /* }}} */ -static inline int php_json_is_valid_double(double d) /* {{{ */ +static inline bool php_json_is_valid_double(double d) /* {{{ */ { return !zend_isinf(d) && !zend_isnan(d); } @@ -107,7 +107,7 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) } \ } while (0) -static int php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ +static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { int i, r, need_comma = 0; HashTable *myht, *prop_ht; @@ -312,7 +312,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options, php_jso } /* }}} */ -static int php_json_escape_string( +static zend_result php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder) /* {{{ */ { @@ -525,12 +525,12 @@ static int php_json_escape_string( } /* }}} */ -static int php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ +static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(val); HashTable* myht = Z_OBJPROP_P(val); zval retval, fname; - int return_code; + zend_result return_code; if (myht && GC_IS_RECURSIVE(myht)) { encoder->error_code = PHP_JSON_ERROR_RECURSION; @@ -587,7 +587,7 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op } /* }}} */ -static int php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder) +static zend_result php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder) { zend_class_entry *ce = Z_OBJCE_P(val); if (ce->enum_backing_type == IS_UNDEF) { @@ -600,7 +600,7 @@ static int php_json_encode_serializable_enum(smart_str *buf, zval *val, int opti return php_json_encode_zval(buf, value_zv, options, encoder); } -int php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ +zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { again: switch (Z_TYPE_P(val)) diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 89d04ed7f4d57..d4d8ac421f886 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -97,11 +97,11 @@ PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) ZEND_TSRMLS_CACHE_EXTERN() #endif -PHP_JSON_API int php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth); -PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options); -PHP_JSON_API int php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth); +PHP_JSON_API zend_result php_json_encode_ex(smart_str *buf, zval *val, int options, zend_long depth); +PHP_JSON_API zend_result php_json_encode(smart_str *buf, zval *val, int options); +PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth); -static inline int php_json_decode(zval *return_value, const char *str, int str_len, bool assoc, zend_long depth) +static inline zend_result php_json_decode(zval *return_value, const char *str, size_t str_len, bool assoc, zend_long depth) { return php_json_decode_ex(return_value, str, str_len, assoc ? PHP_JSON_OBJECT_AS_ARRAY : 0, depth); } diff --git a/ext/json/php_json_encoder.h b/ext/json/php_json_encoder.h index 51d2d6b59ab49..e1c48e2b50922 100644 --- a/ext/json/php_json_encoder.h +++ b/ext/json/php_json_encoder.h @@ -33,6 +33,6 @@ static inline void php_json_encode_init(php_json_encoder *encoder) memset(encoder, 0, sizeof(php_json_encoder)); } -int php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder); +zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder); #endif /* PHP_JSON_ENCODER_H */ From d0417ebc937693c076a9542c39427e23c29498e8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 17 Mar 2022 12:21:02 +0100 Subject: [PATCH 206/227] Fix GH-8208: mb_encode_mimeheader: $indent functionality broken We also need to factor in the indent, when getting the encoder result. Closes GH-8213. --- NEWS | 4 ++++ ext/mbstring/libmbfl/mbfl/mbfilter.c | 2 +- ext/mbstring/tests/gh8208.phpt | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 ext/mbstring/tests/gh8208.phpt diff --git a/NEWS b/NEWS index f0382c538777e..c6af44051a431 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS - Intl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) +- MBString: + . Fixed bug GH-8208 (mb_encode_mimeheader: $indent functionality broken). + (cmb) + - MySQLi: . Fixed bug GH-8068 (mysqli_fetch_object creates inaccessible properties). (cmb) diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 793dd8e078194..e9dafbf525c2d 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -1803,7 +1803,7 @@ mime_header_encoder_result(struct mime_header_encoder_data *pe, mbfl_string *res mbfl_memory_device_strncat(&pe->outdev, "\x3f\x3d", 2); /* ?= */ } else if (pe->tmpdev.pos > 0) { if (pe->outdev.pos > 0) { - if ((pe->outdev.pos - pe->linehead + pe->tmpdev.pos) > 74) { + if ((pe->outdev.pos - pe->linehead + pe->tmpdev.pos + pe->firstindent) > 74) { mbfl_memory_device_strncat(&pe->outdev, pe->lwsp, pe->lwsplen); } else { mbfl_memory_device_output(0x20, &pe->outdev); diff --git a/ext/mbstring/tests/gh8208.phpt b/ext/mbstring/tests/gh8208.phpt new file mode 100644 index 0000000000000..c99f671894a3e --- /dev/null +++ b/ext/mbstring/tests/gh8208.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-8208 (mb_encode_mimeheader: $indent functionality broken) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(84) "Subject: [service-Aufgaben S&W-Team][#19415] VM''s aufsetzen mit + unterschiedlichen" +string(84) "Subject: [service-Aufgaben S&W-Team][#19415] VM''s aufsetzen mit + unterschiedlichen" From 3d6a7e2bd5edad4243dd3c1780dcad0ff6004f3e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Mar 2022 18:54:47 +0300 Subject: [PATCH 207/227] JIT: Fix missing exception handling Fixes oss-fuzz #45649 --- ext/opcache/jit/zend_jit_trace.c | 11 ++++++++++- ext/opcache/tests/jit/bw_not_002.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/bw_not_002.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 8dee57147b77f..4d00c14015b20 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -5843,7 +5843,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } if (opline->opcode != ZEND_NOP && opline->opcode != ZEND_JMP) { - if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) { + op1_info = OP1_INFO(); + op2_info = OP2_INFO(); + if (op1_info & MAY_BE_GUARD) { + op1_info = MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + } + if (op2_info & MAY_BE_GUARD) { + op2_info = MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + } + if (!zend_jit_trace_handler(&dasm_state, op_array, opline, + zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info), p + 1)) { goto jit_failure; } } diff --git a/ext/opcache/tests/jit/bw_not_002.phpt b/ext/opcache/tests/jit/bw_not_002.phpt new file mode 100644 index 0000000000000..034c6bc90cbdf --- /dev/null +++ b/ext/opcache/tests/jit/bw_not_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +JIT BW_NOT: 002 Exception handling +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: Cannot perform bitwise not on bool in %sbw_not_002.php:5 +Stack trace: +#0 %sbw_not_002.php(8): test() +#1 {main} + thrown in %sbw_not_002.php on line 5 From c9385ee1ad0d19e7c830f163cb91592924214ad7 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 19 Mar 2022 11:12:00 +0000 Subject: [PATCH 208/227] zend_mm_map_fixed using MAP_TRYFIXED on NetBSD.DragonFlyBSD attempts to map on addr but does not replace it if already present. Note on OpenBSD it has no effect, addr is used just as a hint. Closes GH-7923. --- Zend/zend_alloc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index d8a7b07db77fc..07f971e44df4c 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -425,12 +425,14 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) int flags = MAP_PRIVATE | MAP_ANON; #if defined(MAP_EXCL) flags |= MAP_FIXED | MAP_EXCL; +#elif defined(MAP_TRYFIXED) + flags |= MAP_TRYFIXED; #endif /* MAP_FIXED leads to discarding of the old mapping, so it can't be used. */ void *ptr = mmap(addr, size, PROT_READ | PROT_WRITE, flags /*| MAP_POPULATE | MAP_HUGETLB*/, ZEND_MM_FD, 0); if (ptr == MAP_FAILED) { -#if ZEND_MM_ERROR && !defined(MAP_EXCL) +#if ZEND_MM_ERROR && !defined(MAP_EXCL) && !defined(MAP_TRYFIXED) fprintf(stderr, "\nmmap() failed: [%d] %s\n", errno, strerror(errno)); #endif return NULL; From 82de4fcfe6c254e86d25eeca024e94697f955e87 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 19 Mar 2022 14:51:40 +0100 Subject: [PATCH 209/227] ext/opcache/ZendAccelerator: remove redundant check (#8222) The "accelerator_enabled" flag has been checked already in the previous "if". --- ext/opcache/ZendAccelerator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index b753f805394e6..b3115893029e0 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1961,8 +1961,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) ZCG(cache_opline) = NULL; ZCG(cache_persistent_script) = NULL; return file_cache_compile_file(file_handle, type); - } else if (!ZCG(accelerator_enabled) || - (ZCSG(restart_in_progress) && accel_restart_is_active())) { + } else if ((ZCSG(restart_in_progress) && accel_restart_is_active())) { if (ZCG(accel_directives).file_cache) { return file_cache_compile_file(file_handle, type); } From bf2867bc7235dfb65675ff4e9c21c8bc537726e2 Mon Sep 17 00:00:00 2001 From: istiak101 <30789544+istiak101@users.noreply.github.com> Date: Sat, 19 Mar 2022 23:25:29 +0600 Subject: [PATCH 210/227] Fix FSF address & update year to 2022 FSF mailing address was changed long time ago. This patch updates that address. Also updated year from 2021 to 2022. Closes GH-8009. --- LICENSE | 2 +- build/pkg.m4 | 4 ++-- build/shtool | 2 +- ext/oci8/LICENSE | 2 +- ext/phar/phar.1.in | 2 +- sapi/cli/php.1.in | 2 +- sapi/fpm/php-fpm.8.in | 2 +- sapi/phpdbg/phpdbg.1.in | 2 +- scripts/man1/php-config.1.in | 2 +- scripts/man1/phpize.1.in | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/LICENSE b/LICENSE index 6a15be588547f..dffd7eab225d7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2021 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2022 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/build/pkg.m4 b/build/pkg.m4 index f9075e56c87af..5bf9ba16505b7 100644 --- a/build/pkg.m4 +++ b/build/pkg.m4 @@ -16,8 +16,8 @@ dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -dnl 02111-1307, USA. +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a diff --git a/build/shtool b/build/shtool index fc6ae1e6efbbb..ea1119ac1ebea 100755 --- a/build/shtool +++ b/build/shtool @@ -23,7 +23,7 @@ ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ## USA, or contact Ralf S. Engelschall . ## ## NOTICE: Given that you include this file verbatim into your own diff --git a/ext/oci8/LICENSE b/ext/oci8/LICENSE index 6a15be588547f..dffd7eab225d7 100644 --- a/ext/oci8/LICENSE +++ b/ext/oci8/LICENSE @@ -1,6 +1,6 @@ -------------------------------------------------------------------- The PHP License, version 3.01 -Copyright (c) 1999 - 2021 The PHP Group. All rights reserved. +Copyright (c) 1999 - 2022 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/ext/phar/phar.1.in b/ext/phar/phar.1.in index 323e77b0e2a3b..75c3a354825be 100644 --- a/ext/phar/phar.1.in +++ b/ext/phar/phar.1.in @@ -1,4 +1,4 @@ -.TH PHAR 1 "2021" "The PHP Group" "User Commands" +.TH PHAR 1 "2022" "The PHP Group" "User Commands" .SH NAME phar, phar.phar \- PHAR (PHP archive) command line tool .SH SYNOPSIS diff --git a/sapi/cli/php.1.in b/sapi/cli/php.1.in index 98c8dc76f2603..e8b84ad3d12a9 100644 --- a/sapi/cli/php.1.in +++ b/sapi/cli/php.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@php 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@php 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@php \- PHP Command Line Interface 'CLI' .P diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in index 905946e70b119..6525c1eadad64 100644 --- a/sapi/fpm/php-fpm.8.in +++ b/sapi/fpm/php-fpm.8.in @@ -1,4 +1,4 @@ -.TH PHP-FPM 8 "2021" "The PHP Group" "Scripting Language" +.TH PHP-FPM 8 "2022" "The PHP Group" "Scripting Language" .SH NAME .TP 15 php-fpm \- PHP FastCGI Process Manager 'PHP-FPM' diff --git a/sapi/phpdbg/phpdbg.1.in b/sapi/phpdbg/phpdbg.1.in index 29f832407db75..926a1edcc4ed9 100644 --- a/sapi/phpdbg/phpdbg.1.in +++ b/sapi/phpdbg/phpdbg.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@phpdbg 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@phpdbg 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@phpdbg \- The interactive PHP debugger .SH SYNOPSIS diff --git a/scripts/man1/php-config.1.in b/scripts/man1/php-config.1.in index 20f09d611f114..5ed77c574cb42 100644 --- a/scripts/man1/php-config.1.in +++ b/scripts/man1/php-config.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@php\-config 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@php\-config 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@php\-config \- get information about PHP configuration and compile options .SH SYNOPSIS diff --git a/scripts/man1/phpize.1.in b/scripts/man1/phpize.1.in index 308b51e03d009..bf50aa0c1df37 100644 --- a/scripts/man1/phpize.1.in +++ b/scripts/man1/phpize.1.in @@ -1,4 +1,4 @@ -.TH @program_prefix@phpize 1 "2021" "The PHP Group" "Scripting Language" +.TH @program_prefix@phpize 1 "2022" "The PHP Group" "Scripting Language" .SH NAME @program_prefix@phpize \- prepare a PHP extension for compiling .SH SYNOPSIS From dd81dd92643e98ea61bdc9091a47c5cae0925a4b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 20 Mar 2022 00:30:15 +0100 Subject: [PATCH 211/227] build: Extend m4 to support C++20 Signed-off-by: Anatol Belski --- build/php_cxx_compile_stdcxx.m4 | 49 +++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/build/php_cxx_compile_stdcxx.m4 b/build/php_cxx_compile_stdcxx.m4 index 3c8d598e63a1d..f8e97fce708f0 100644 --- a/build/php_cxx_compile_stdcxx.m4 +++ b/build/php_cxx_compile_stdcxx.m4 @@ -6,7 +6,7 @@ dnl PHP_CXX_COMPILE_STDCXX(version, mandatory|optional, var_name_to_put_switch_i dnl dnl ARGUMENTS dnl -dnl first arg - version as 11, 14 or 17 +dnl first arg - version as 11, 14, 17 or 20 dnl second arg - if mandatory, the configure will fail when no features found. dnl Optional will make configure silently continue dnl third arg - a variable name where the corresponding switch would be put. If @@ -26,6 +26,7 @@ AC_DEFUN([PHP_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to PHP_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [ax_cxx_compile_cxx$1_required=true], [$2], [mandatory], [ax_cxx_compile_cxx$1_required=true], @@ -88,19 +89,21 @@ dnl # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. + dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) - dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], @@ -108,12 +111,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +dnl Test body for checking C++17 support + m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ @@ -909,3 +924,33 @@ namespace cxx17 #endif // __cplusplus < 201703L ]]) + + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L + +]]) From 3b9af50465c9279987c842b2f61f2f24e21c543b Mon Sep 17 00:00:00 2001 From: Shrikant Dhayje Date: Mon, 21 Mar 2022 00:58:07 +0530 Subject: [PATCH 212/227] Fixed #8228 - updated details for filling bugs to GitHub Issue (#8231) * updated details for filling bugs to GitHub Issue * Remove superfluous word in README.md * Link new issue page directly Co-authored-by: Ilija Tovilo --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a77eec1e01fb9..4d18eb2c98cbe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -58,8 +58,8 @@ and build PHP source code. We recommend to look at our ## Filing bugs -Bugs can be filed on the [PHP bug tracker](https://bugs.php.net/). If this is -the first time you've filed a bug, we suggest reading the +Bugs can be filed on [GitHub Issues](https://github.com/php/php-src/issues/new/choose). +If this is the first time you've filed a bug, we suggest reading the [guide to reporting a bug](https://bugs.php.net/how-to-report.php). Where possible, please include a self-contained reproduction case! From a83cc9d397b35aa2706791cffe8d6c0339d1d1fc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 20 Mar 2022 20:30:03 +0100 Subject: [PATCH 213/227] Zend/zend_alloc: use bool and make internal variable static (#8230) * Zend/zend_alloc: make zend_mm_use_huge_pages static This is an internal variable and it should not be exported. * Zend/zend_alloc: convert zend_mm_use_huge_pages to bool * Zend/zend_alloc: convert has_free_pages to bool * Zend/zend_alloc: convert empty to bool --- Zend/zend_alloc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 07f971e44df4c..488979d884143 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -69,6 +69,7 @@ # include "win32/winutil.h" #endif +#include #include #include #include @@ -196,7 +197,7 @@ typedef struct _zend_mm_free_slot zend_mm_free_slot; typedef struct _zend_mm_chunk zend_mm_chunk; typedef struct _zend_mm_huge_list zend_mm_huge_list; -int zend_mm_use_huge_pages = 0; +static bool zend_mm_use_huge_pages = false; /* * Memory is retrieved from OS by chunks of fixed size 2MB. @@ -1912,7 +1913,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) int page_num; zend_mm_page_info info; uint32_t i, free_counter; - int has_free_pages; + bool has_free_pages; size_t collected = 0; #if ZEND_MM_CUSTOM @@ -1922,7 +1923,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) #endif for (i = 0; i < ZEND_MM_BINS; i++) { - has_free_pages = 0; + has_free_pages = false; p = heap->free_slot[i]; while (p != NULL) { chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(p, ZEND_MM_CHUNK_SIZE); @@ -1941,7 +1942,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) ZEND_ASSERT(ZEND_MM_SRUN_BIN_NUM(info) == i); free_counter = ZEND_MM_SRUN_FREE_COUNTER(info) + 1; if (free_counter == bin_elements[i]) { - has_free_pages = 1; + has_free_pages = true; } chunk->map[page_num] = ZEND_MM_SRUN_EX(i, free_counter); p = p->next_free_slot; @@ -2025,7 +2026,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, uint32_t i, uint32_t j, zend_leak_info *leak) { - int empty = 1; + bool empty = true; zend_long count = 0; int bin_num = ZEND_MM_SRUN_BIN_NUM(p->map[i]); zend_mm_debug_info *dbg = (zend_mm_debug_info*)((char*)p + ZEND_MM_PAGE_SIZE * i + bin_data_size[bin_num] * (j + 1) - ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))); @@ -2038,7 +2039,7 @@ static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, uint32_t i, uint32_t dbg->filename = NULL; dbg->lineno = 0; } else { - empty = 0; + empty = false; } } j++; @@ -2869,7 +2870,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) tmp = getenv("USE_ZEND_ALLOC_HUGE_PAGES"); if (tmp && ZEND_ATOL(tmp)) { - zend_mm_use_huge_pages = 1; + zend_mm_use_huge_pages = true; } alloc_globals->mm_heap = zend_mm_init(); } From 373f236673dc86b22b252095a4666a580cae130a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 17 Mar 2022 19:28:34 +0100 Subject: [PATCH 214/227] ext/opcache: C++ compatibility --- Zend/zend_map_ptr.h | 4 ++++ ext/opcache/ZendAccelerator.h | 4 ++++ ext/opcache/zend_accelerator_hash.h | 4 ++++ ext/opcache/zend_accelerator_util_funcs.h | 4 ++++ ext/opcache/zend_shared_alloc.h | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h index f2fe96f19a72c..aa726e0cdd32d 100644 --- a/Zend/zend_map_ptr.h +++ b/Zend/zend_map_ptr.h @@ -69,9 +69,13 @@ # error "Unknown ZEND_MAP_PTR_KIND" #endif +BEGIN_EXTERN_C() + ZEND_API void zend_map_ptr_reset(void); ZEND_API void *zend_map_ptr_new(void); ZEND_API void zend_map_ptr_extend(size_t last); ZEND_API void zend_alloc_ce_cache(zend_string *type_name); +END_EXTERN_C() + #endif /* ZEND_MAP_PTR_H */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 9d18493c7d52a..bd692495a5282 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -311,6 +311,8 @@ extern zend_accel_globals accel_globals; extern char *zps_api_failure_reason; +BEGIN_EXTERN_C() + void accel_shutdown(void); zend_result accel_activate(INIT_FUNC_ARGS); zend_result accel_post_deactivate(void); @@ -333,6 +335,8 @@ zend_string* ZEND_FASTCALL accel_new_interned_string(zend_string *str); uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name); +END_EXTERN_C() + /* memory write protection */ #define SHM_PROTECT() \ do { \ diff --git a/ext/opcache/zend_accelerator_hash.h b/ext/opcache/zend_accelerator_hash.h index 7cf995f3175e9..755d3f13ec516 100644 --- a/ext/opcache/zend_accelerator_hash.h +++ b/ext/opcache/zend_accelerator_hash.h @@ -60,6 +60,8 @@ typedef struct _zend_accel_hash { uint32_t num_direct_entries; } zend_accel_hash; +BEGIN_EXTERN_C() + void zend_accel_hash_init(zend_accel_hash *accel_hash, uint32_t hash_size); void zend_accel_hash_clean(zend_accel_hash *accel_hash); @@ -90,4 +92,6 @@ static inline bool zend_accel_hash_is_full(zend_accel_hash *accel_hash) } } +END_EXTERN_C() + #endif /* ZEND_ACCELERATOR_HASH_H */ diff --git a/ext/opcache/zend_accelerator_util_funcs.h b/ext/opcache/zend_accelerator_util_funcs.h index 1ce661635c19a..53cc1de9effaa 100644 --- a/ext/opcache/zend_accelerator_util_funcs.h +++ b/ext/opcache/zend_accelerator_util_funcs.h @@ -25,6 +25,8 @@ #include "zend.h" #include "ZendAccelerator.h" +BEGIN_EXTERN_C() + zend_persistent_script* create_persistent_script(void); void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements); @@ -42,4 +44,6 @@ unsigned int zend_adler32(unsigned int checksum, unsigned char *buf, uint32_t le unsigned int zend_accel_script_checksum(zend_persistent_script *persistent_script); +END_EXTERN_C() + #endif /* ZEND_ACCELERATOR_UTIL_FUNCS_H */ diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 4e090b98ddadf..56c2da5e90ecb 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -125,6 +125,8 @@ extern zend_smm_shared_globals *smm_shared_globals; #define SHARED_ALLOC_REATTACHED (SUCCESS+1) +BEGIN_EXTERN_C() + int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size); void zend_shared_alloc_shutdown(void); @@ -200,4 +202,6 @@ void zend_shared_alloc_lock_win32(void); void zend_shared_alloc_unlock_win32(void); #endif +END_EXTERN_C() + #endif /* ZEND_SHARED_ALLOC_H */ From ca134f7a3e53266a6c08ed9f841b4c5a366fe663 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sun, 20 Mar 2022 20:39:21 +0100 Subject: [PATCH 215/227] Remove unused include of stdbool.h --- Zend/zend_alloc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 488979d884143..e2d06c1762dd9 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -69,7 +69,6 @@ # include "win32/winutil.h" #endif -#include #include #include #include From 63281763bf58e8b0ed62ad91854bd081a5f2c3f4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 18 Mar 2022 15:49:19 +0100 Subject: [PATCH 216/227] ext/opcache/zend_shared_alloc: add zend_shared_alloc_aligned() Eliminate some duplicate code. --- ext/opcache/ZendAccelerator.c | 10 ++-------- ext/opcache/zend_file_cache.c | 8 +------- ext/opcache/zend_shared_alloc.h | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index b3115893029e0..18dce13455329 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1538,11 +1538,9 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr memory_used = zend_accel_script_persist_calc(new_persistent_script, 1); /* Allocate shared memory */ + ZCG(mem) = zend_shared_alloc_aligned(memory_used); #if defined(__AVX__) || defined(__SSE2__) - /* Align to 64-byte boundary */ - ZCG(mem) = zend_shared_alloc(memory_used + 64); if (ZCG(mem)) { - ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L); #if defined(__x86_64__) memset(ZCG(mem), 0, memory_used); #elif defined(__AVX__) @@ -1574,7 +1572,6 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr #endif } #else - ZCG(mem) = zend_shared_alloc(memory_used); if (ZCG(mem)) { memset(ZCG(mem), 0, memory_used); } @@ -4237,11 +4234,9 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s memory_used = zend_accel_script_persist_calc(new_persistent_script, 1); /* Allocate shared memory */ + ZCG(mem) = zend_shared_alloc_aligned(memory_used); #if defined(__AVX__) || defined(__SSE2__) - /* Align to 64-byte boundary */ - ZCG(mem) = zend_shared_alloc(memory_used + 64); if (ZCG(mem)) { - ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L); #if defined(__x86_64__) memset(ZCG(mem), 0, memory_used); #elif defined(__AVX__) @@ -4273,7 +4268,6 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s #endif } #else - ZCG(mem) = zend_shared_alloc(memory_used); if (ZCG(mem)) { memset(ZCG(mem), 0, memory_used); } diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index b822f8992d4f4..bbfe3771afac6 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -1866,13 +1866,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl goto use_process_mem; } -#if defined(__AVX__) || defined(__SSE2__) - /* Align to 64-byte boundary */ - buf = zend_shared_alloc(info.mem_size + 64); - buf = (void*)(((zend_uintptr_t)buf + 63L) & ~63L); -#else - buf = zend_shared_alloc(info.mem_size); -#endif + buf = zend_shared_alloc_aligned(info.mem_size); if (!buf) { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 56c2da5e90ecb..de5012b2204ad 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -134,6 +134,20 @@ void zend_shared_alloc_shutdown(void); void *zend_shared_alloc_pages(size_t requested_size); void *zend_shared_alloc(size_t size); +/** + * Wrapper for zend_shared_alloc() which aligns at 64-byte boundary if + * AVX or SSE2 are used. + */ +static inline void *zend_shared_alloc_aligned(size_t size) { +#if defined(__AVX__) || defined(__SSE2__) + /* Align to 64-byte boundary */ + void *p = zend_shared_alloc(size + 64); + return (void *)(((zend_uintptr_t)p + 63L) & ~63L); +#else + return zend_shared_alloc(size); +#endif +} + /* copy into shared memory */ void *zend_shared_memdup_get_put_free(void *source, size_t size); void *zend_shared_memdup_put_free(void *source, size_t size); From b9b134de5c3c418bc7f05e15dd4ad412e3b62f05 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 18 Mar 2022 16:58:34 +0100 Subject: [PATCH 217/227] ext/opcache/ZendAccelerator: move duplicate code into bzero_aligned() --- ext/opcache/ZendAccelerator.c | 112 ++++++++++++---------------------- 1 file changed, 38 insertions(+), 74 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 18dce13455329..a533a074a2603 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -139,6 +139,40 @@ static void preload_restart(void); # define LOCKVAL(v) (ZCSG(v)) #endif +/** + * Clear AVX/SSE2-aligned memory. + */ +static void bzero_aligned(void *mem, size_t size) +{ +#if defined(__x86_64__) + memset(mem, 0, size); +#elif defined(__AVX__) + char *p = (char*)mem; + char *end = p + size; + __m256i ymm0 = _mm256_setzero_si256(); + + while (p < end) { + _mm256_store_si256((__m256i*)p, ymm0); + _mm256_store_si256((__m256i*)(p+32), ymm0); + p += 64; + } +#elif defined(__SSE2__) + char *p = (char*)mem; + char *end = p + size; + __m128i xmm0 = _mm_setzero_si128(); + + while (p < end) { + _mm_store_si128((__m128i*)p, xmm0); + _mm_store_si128((__m128i*)(p+16), xmm0); + _mm_store_si128((__m128i*)(p+32), xmm0); + _mm_store_si128((__m128i*)(p+48), xmm0); + p += 64; + } +#else + memset(mem, 0, size); +#endif +} + #ifdef ZEND_WIN32 static time_t zend_accel_get_time(void) { @@ -1539,43 +1573,6 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr /* Allocate shared memory */ ZCG(mem) = zend_shared_alloc_aligned(memory_used); -#if defined(__AVX__) || defined(__SSE2__) - if (ZCG(mem)) { -#if defined(__x86_64__) - memset(ZCG(mem), 0, memory_used); -#elif defined(__AVX__) - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m256i ymm0 = _mm256_setzero_si256(); - - while (p < end) { - _mm256_store_si256((__m256i*)p, ymm0); - _mm256_store_si256((__m256i*)(p+32), ymm0); - p += 64; - } - } -#else - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m128i xmm0 = _mm_setzero_si128(); - - while (p < end) { - _mm_store_si128((__m128i*)p, xmm0); - _mm_store_si128((__m128i*)(p+16), xmm0); - _mm_store_si128((__m128i*)(p+32), xmm0); - _mm_store_si128((__m128i*)(p+48), xmm0); - p += 64; - } - } -#endif - } -#else - if (ZCG(mem)) { - memset(ZCG(mem), 0, memory_used); - } -#endif if (!ZCG(mem)) { zend_shared_alloc_destroy_xlat_table(); zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); @@ -1587,6 +1584,8 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr return new_persistent_script; } + bzero_aligned(ZCG(mem), memory_used); + zend_shared_alloc_clear_xlat_table(); /* Copy into shared memory */ @@ -4235,48 +4234,13 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s /* Allocate shared memory */ ZCG(mem) = zend_shared_alloc_aligned(memory_used); -#if defined(__AVX__) || defined(__SSE2__) - if (ZCG(mem)) { -#if defined(__x86_64__) - memset(ZCG(mem), 0, memory_used); -#elif defined(__AVX__) - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m256i ymm0 = _mm256_setzero_si256(); - - while (p < end) { - _mm256_store_si256((__m256i*)p, ymm0); - _mm256_store_si256((__m256i*)(p+32), ymm0); - p += 64; - } - } -#else - { - char *p = (char*)ZCG(mem); - char *end = p + memory_used; - __m128i xmm0 = _mm_setzero_si128(); - - while (p < end) { - _mm_store_si128((__m128i*)p, xmm0); - _mm_store_si128((__m128i*)(p+16), xmm0); - _mm_store_si128((__m128i*)(p+32), xmm0); - _mm_store_si128((__m128i*)(p+48), xmm0); - p += 64; - } - } -#endif - } -#else - if (ZCG(mem)) { - memset(ZCG(mem), 0, memory_used); - } -#endif if (!ZCG(mem)) { zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Not enough shared memory for preloading. Consider increasing the value for the opcache.memory_consumption directive in php.ini."); return NULL; } + bzero_aligned(ZCG(mem), memory_used); + zend_shared_alloc_restore_xlat_table(checkpoint); /* Copy into shared memory */ From 733023b2e3099485a67baa18f33a19074740d4f1 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 10 Mar 2022 14:41:07 +0100 Subject: [PATCH 218/227] Improve error message class type Refer to interfaces/enums instead of classes in more places. Closes GH-7792 Closes GH-8187 --- NEWS | 1 + Zend/tests/class_alias_009.phpt | 2 +- .../final_constants/final_const12.phpt | 2 +- .../enum/no-enum-implements-backed-enum.phpt | 2 +- .../enum/no-enum-implements-unit-enum.phpt | 2 +- Zend/tests/gh7792_1.phpt | 14 ++++++++++++++ Zend/tests/gh7792_2.phpt | 10 ++++++++++ Zend/tests/gh7792_3.phpt | 18 ++++++++++++++++++ Zend/tests/gh7792_4.phpt | 12 ++++++++++++ Zend/tests/gh7792_5.phpt | 10 ++++++++++ Zend/tests/objects_014.phpt | 2 +- Zend/zend_API.c | 12 +++++++----- Zend/zend_API.h | 12 +++++++++++- Zend/zend_exceptions.c | 7 ++++++- Zend/zend_inheritance.c | 18 ++++++++++++------ Zend/zend_interfaces.c | 3 ++- 16 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 Zend/tests/gh7792_1.phpt create mode 100644 Zend/tests/gh7792_2.phpt create mode 100644 Zend/tests/gh7792_3.phpt create mode 100644 Zend/tests/gh7792_4.phpt create mode 100644 Zend/tests/gh7792_5.phpt diff --git a/NEWS b/NEWS index dd939687ecaf6..75e3600f5480a 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ PHP NEWS - Core: . Fixed bug #81380 (Observer may not be initialized properly). (krakjoe) . Fixed bug GH-7771 (Fix filename/lineno of constant expressions). (ilutov) + . Fixed bug GH-7792 (Improve class type in error messages). (ilutov) - Intl: . Update all grandfathered language tags with preferred values diff --git a/Zend/tests/class_alias_009.phpt b/Zend/tests/class_alias_009.phpt index f17769e1f4213..bb72312577aff 100644 --- a/Zend/tests/class_alias_009.phpt +++ b/Zend/tests/class_alias_009.phpt @@ -11,4 +11,4 @@ interface c extends a, b { } ?> --EXPECTF-- -Fatal error: Class c cannot implement previously implemented interface a in %s on line %d +Fatal error: Interface c cannot implement previously implemented interface a in %s on line %d diff --git a/Zend/tests/constants/final_constants/final_const12.phpt b/Zend/tests/constants/final_constants/final_const12.phpt index 300239f6a630e..3130af11da8bd 100644 --- a/Zend/tests/constants/final_constants/final_const12.phpt +++ b/Zend/tests/constants/final_constants/final_const12.phpt @@ -19,4 +19,4 @@ interface I3 extends I1, I2 ?> --EXPECTF-- -Fatal error: Class I3 inherits both I1::C and I2::C, which is ambiguous in %s on line %d +Fatal error: Interface I3 inherits both I1::C and I2::C, which is ambiguous in %s on line %d diff --git a/Zend/tests/enum/no-enum-implements-backed-enum.phpt b/Zend/tests/enum/no-enum-implements-backed-enum.phpt index 69922c13a8f51..c93994ad8bf58 100644 --- a/Zend/tests/enum/no-enum-implements-backed-enum.phpt +++ b/Zend/tests/enum/no-enum-implements-backed-enum.phpt @@ -7,4 +7,4 @@ enum Foo: int implements BackedEnum {} ?> --EXPECTF-- -Fatal error: Class Foo cannot implement previously implemented interface BackedEnum in %s on line %d +Fatal error: Enum Foo cannot implement previously implemented interface BackedEnum in %s on line %d diff --git a/Zend/tests/enum/no-enum-implements-unit-enum.phpt b/Zend/tests/enum/no-enum-implements-unit-enum.phpt index 458efbb67cdfa..ae1890c430518 100644 --- a/Zend/tests/enum/no-enum-implements-unit-enum.phpt +++ b/Zend/tests/enum/no-enum-implements-unit-enum.phpt @@ -7,4 +7,4 @@ enum Foo implements UnitEnum {} ?> --EXPECTF-- -Fatal error: Class Foo cannot implement previously implemented interface UnitEnum in %s on line %d +Fatal error: Enum Foo cannot implement previously implemented interface UnitEnum in %s on line %d diff --git a/Zend/tests/gh7792_1.phpt b/Zend/tests/gh7792_1.phpt new file mode 100644 index 0000000000000..a342f169d937c --- /dev/null +++ b/Zend/tests/gh7792_1.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum B must implement 1 abstract private method (A::a) in %s on line %d diff --git a/Zend/tests/gh7792_2.phpt b/Zend/tests/gh7792_2.phpt new file mode 100644 index 0000000000000..41f47a6e870ac --- /dev/null +++ b/Zend/tests/gh7792_2.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum Foo cannot implement interface Throwable in %s on line %d diff --git a/Zend/tests/gh7792_3.phpt b/Zend/tests/gh7792_3.phpt new file mode 100644 index 0000000000000..67e2c1c99dda1 --- /dev/null +++ b/Zend/tests/gh7792_3.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum Foo inherits both A::FOO and B::FOO, which is ambiguous in %s on line %d diff --git a/Zend/tests/gh7792_4.phpt b/Zend/tests/gh7792_4.phpt new file mode 100644 index 0000000000000..0d09835d7ee3a --- /dev/null +++ b/Zend/tests/gh7792_4.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECTF-- +Fatal error: Enum Foo cannot implement previously implemented interface A in %s on line %d diff --git a/Zend/tests/gh7792_5.phpt b/Zend/tests/gh7792_5.phpt new file mode 100644 index 0000000000000..824ed9ed1810d --- /dev/null +++ b/Zend/tests/gh7792_5.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-7792 (Refer to enum as enum instead of class) +--FILE-- + +--EXPECT-- +Fatal error: Enum Foo must implement interface Traversable as part of either Iterator or IteratorAggregate in Unknown on line 0 diff --git a/Zend/tests/objects_014.phpt b/Zend/tests/objects_014.phpt index 138fd4f294660..858de748b8e2e 100644 --- a/Zend/tests/objects_014.phpt +++ b/Zend/tests/objects_014.phpt @@ -12,4 +12,4 @@ interface bar extends foo, foo { echo "Done\n"; ?> --EXPECTF-- -Fatal error: Class bar cannot implement previously implemented interface foo in %s on line %d +Fatal error: Interface bar cannot implement previously implemented interface foo in %s on line %d diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3ef291c315596..6ce9f593e17dd 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4783,14 +4783,16 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved) /* {{{ */ } /* }}} */ -ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce) /* {{{ */ +ZEND_API ZEND_COLD const char *zend_get_object_type_case(const zend_class_entry *ce, bool upper_case) /* {{{ */ { - if(ce->ce_flags & ZEND_ACC_TRAIT) { - return "trait"; + if (ce->ce_flags & ZEND_ACC_TRAIT) { + return upper_case ? "Trait" : "trait"; } else if (ce->ce_flags & ZEND_ACC_INTERFACE) { - return "interface"; + return upper_case ? "Interface" : "interface"; + } else if (ce->ce_flags & ZEND_ACC_ENUM) { + return upper_case ? "Enum" : "enum"; } else { - return "class"; + return upper_case ? "Class" : "class"; } } /* }}} */ diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ecb6e8296befb..705fe25e7665a 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -721,7 +721,17 @@ static zend_always_inline zend_result zend_forbid_dynamic_call(void) return SUCCESS; } -ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce); +ZEND_API ZEND_COLD const char *zend_get_object_type_case(const zend_class_entry *ce, bool upper_case); + +static zend_always_inline const char *zend_get_object_type(const zend_class_entry *ce) +{ + return zend_get_object_type_case(ce, false); +} + +static zend_always_inline const char *zend_get_object_type_uc(const zend_class_entry *ce) +{ + return zend_get_object_type_case(ce, true); +} ZEND_API bool zend_is_iterable(zval *iterable); diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 7138713510120..85e21c64a037b 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -67,8 +67,13 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr return SUCCESS; } + bool can_extend = (class_type->ce_flags & ZEND_ACC_ENUM) == 0; + zend_error_noreturn(E_ERROR, - "Class %s cannot implement interface %s, extend Exception or Error instead", + can_extend + ? "%s %s cannot implement interface %s, extend Exception or Error instead" + : "%s %s cannot implement interface %s", + zend_get_object_type_uc(class_type), ZSTR_VAL(class_type->name), ZSTR_VAL(interface->name)); return FAILURE; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 82af3d8afa75a..2709fb5639186 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1285,7 +1285,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface) /* {{{ */ { if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce) == FAILURE) { - zend_error_noreturn(E_CORE_ERROR, "Class %s could not implement interface %s", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); + zend_error_noreturn(E_CORE_ERROR, "%s %s could not implement interface %s", zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); } /* This should be prevented by the class lookup logic. */ ZEND_ASSERT(ce != iface); @@ -1610,7 +1610,8 @@ static bool do_inherit_constant_check( if (old_constant->ce != parent_constant->ce && old_constant->ce != ce) { zend_error_noreturn(E_COMPILE_ERROR, - "Class %s inherits both %s::%s and %s::%s, which is ambiguous", + "%s %s inherits both %s::%s and %s::%s, which is ambiguous", + zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ZSTR_VAL(old_constant->ce->name), ZSTR_VAL(name), ZSTR_VAL(parent_constant->ce->name), ZSTR_VAL(name)); @@ -1729,7 +1730,10 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry if (interfaces[j] == iface) { if (j >= num_parent_interfaces) { efree(interfaces); - zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name)); + zend_error_noreturn(E_COMPILE_ERROR, "%s %s cannot implement previously implemented interface %s", + zend_get_object_type_uc(ce), + ZSTR_VAL(ce->name), + ZSTR_VAL(iface->name)); return; } /* skip duplications */ @@ -2311,6 +2315,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */ zend_function *func; zend_abstract_info ai; bool is_explicit_abstract = (ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) != 0; + bool can_be_abstract = (ce->ce_flags & ZEND_ACC_ENUM) == 0; memset(&ai, 0, sizeof(ai)); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, func) { @@ -2324,9 +2329,10 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */ } ZEND_HASH_FOREACH_END(); if (ai.cnt) { - zend_error_noreturn(E_ERROR, !is_explicit_abstract - ? "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")" - : "Class %s must implement %d abstract private method%s (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", + zend_error_noreturn(E_ERROR, !is_explicit_abstract && can_be_abstract + ? "%s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")" + : "%s %s must implement %d abstract private method%s (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", + zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ai.cnt, ai.cnt > 1 ? "s" : "", DISPLAY_ABSTRACT_FN(0), diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 3defb97d2ec0e..1fa2493f17af5 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -266,7 +266,8 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en } } } - zend_error_noreturn(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s", + zend_error_noreturn(E_CORE_ERROR, "%s %s must implement interface %s as part of either %s or %s", + zend_get_object_type_uc(class_type), ZSTR_VAL(class_type->name), ZSTR_VAL(zend_ce_traversable->name), ZSTR_VAL(zend_ce_iterator->name), From 7051dc33729503a8814ed3dfe8492cb6ed081594 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 21 Mar 2022 12:50:30 +0300 Subject: [PATCH 219/227] JIT: Fix memory leak Fixes oss-fuzz #45658 --- ext/opcache/jit/zend_jit_helpers.c | 4 ++++ ext/opcache/tests/jit/assign_dim_014.phpt | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_014.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index dd01532b5b705..713ee5ff64b05 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -860,6 +860,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim ZVAL_NULL(EX_VAR(opline->result.var)); } } + if (opline->opcode == ZEND_ASSIGN_DIM + && ((opline+1)->op1_type & (IS_VAR | IS_TMP_VAR))) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } return NULL; } /* break missing intentionally */ diff --git a/ext/opcache/tests/jit/assign_dim_014.phpt b/ext/opcache/tests/jit/assign_dim_014.phpt new file mode 100644 index 0000000000000..d5680a4b60764 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_014.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ASSIGN_DIM: 014 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +Error: Undefined variable $y +DONE From e9fc81a2f8553a4add48933c7c935912bad9f6fb Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 21 Mar 2022 13:34:46 +0300 Subject: [PATCH 220/227] JIT: Fix missing type store Fixes oss-fuzz #45604 --- ext/opcache/jit/zend_jit_trace.c | 9 ++++++- ext/opcache/tests/jit/qm_assign_003.phpt | 31 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/qm_assign_003.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 4d00c14015b20..adfcb6fa403be 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4760,9 +4760,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par #else res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE; #endif + res_addr = RES_REG_ADDR(); + if (Z_MODE(res_addr) != IS_REG && + STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var)) != + STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) { + /* type may be not set */ + res_use_info |= MAY_BE_NULL; + } if (!zend_jit_qm_assign(&dasm_state, opline, op1_info, op1_addr, op1_def_addr, - res_use_info, res_info, RES_REG_ADDR())) { + res_use_info, res_info, res_addr)) { goto jit_failure; } if (opline->op1_type == IS_CV diff --git a/ext/opcache/tests/jit/qm_assign_003.phpt b/ext/opcache/tests/jit/qm_assign_003.phpt new file mode 100644 index 0000000000000..5d88d9116d965 --- /dev/null +++ b/ext/opcache/tests/jit/qm_assign_003.phpt @@ -0,0 +1,31 @@ +--TEST-- +JIT QM_ASSIGN: 003 missing type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $cnt in %sqm_assign_003.php on line 3 + +Warning: Undefined variable $a in %sqm_assign_003.php on line 4 + +Warning: Undefined variable $cnt in %sqm_assign_003.php on line 3 +DONE \ No newline at end of file From cf83bdd925bc039ea81a2ccddec6547d51b841dc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 21 Mar 2022 16:08:52 +0300 Subject: [PATCH 221/227] JIT: Fix register clobbering Fixes oss-fuzz #45590 --- ext/opcache/jit/zend_jit_x86.dasc | 3 +++ ext/opcache/tests/jit/reg_alloc_014.phpt | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 ext/opcache/tests/jit/reg_alloc_014.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 78552b5eee2a6..b30a9952ca34b 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -15877,6 +15877,9 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend if (op1_info & MAY_BE_DOUBLE) { regset = ZEND_REGSET(ZREG_XMM0); } + if (opline->result_type != IS_UNUSED && (op1_info & MAY_BE_LONG)) { + ZEND_REGSET_INCL(regset, ZREG_R1); + } } break; case ZEND_ADD: diff --git a/ext/opcache/tests/jit/reg_alloc_014.phpt b/ext/opcache/tests/jit/reg_alloc_014.phpt new file mode 100644 index 0000000000000..03b7ae0667c1f --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_014.phpt @@ -0,0 +1,21 @@ +--TEST-- +Register Alloction 014: Register clobbering +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $a in %sreg_alloc_014.php on line 4 +DONE \ No newline at end of file From 69ea2d8600462ba046e76a697cbad89706b858a5 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 16 Mar 2022 23:39:55 +0000 Subject: [PATCH 222/227] Convert check + exception to assertion Move the inside the __unserialize() method as that's the only one which now needs this check Closes GH-8207 --- ext/spl/spl_array.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 8a429fdf3f8bc..80a3a51dee881 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -993,11 +993,9 @@ static HashTable *spl_array_it_get_gc(zend_object_iterator *iter, zval **table, } /* {{{ spl_array_set_array */ -static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, int just_array) { - if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) { - zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object", 0); - return; - } +static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, bool just_array) { + /* Handled by ZPP prior to this, or for __unserialize() before passing to here */ + ZEND_ASSERT(Z_TYPE_P(array) == IS_ARRAY || Z_TYPE_P(array) == IS_OBJECT); if (Z_TYPE_P(array) == IS_ARRAY) { zval_ptr_dtor(&intern->array); if (Z_REFCOUNT_P(array) == 1) { @@ -1739,6 +1737,11 @@ PHP_METHOD(ArrayObject, __unserialize) zval_ptr_dtor(&intern->array); ZVAL_UNDEF(&intern->array); } else { + if (Z_TYPE_P(storage_zv) != IS_OBJECT && Z_TYPE_P(storage_zv) != IS_ARRAY) { + /* TODO Use UnexpectedValueException instead? And better error message? */ + zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object", 0); + RETURN_THROWS(); + } spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1); } From 2fa33d1defcab4c2d646587d041a5091b3f88e1a Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 23 Mar 2022 22:13:08 +0000 Subject: [PATCH 223/227] Use ZEND_THROWS() where applicable in spl_array.c --- ext/spl/spl_array.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 80a3a51dee881..e07a08a71ed74 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1574,7 +1574,7 @@ PHP_METHOD(ArrayObject, unserialize) if (intern->nApplyCount > 0) { zend_throw_error(NULL, "Modification of ArrayObject during sorting is prohibited"); - return; + RETURN_THROWS(); } /* storage */ @@ -1773,7 +1773,7 @@ PHP_METHOD(ArrayObject, __unserialize) PHP_METHOD(ArrayObject, __debugInfo) { if (zend_parse_parameters_none() == FAILURE) { - return; + RETURN_THROWS(); } RETURN_ARR(spl_array_get_debug_info(Z_OBJ_P(ZEND_THIS))); From db0db2204f59f57be29e43721b569b876a31bc3a Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 23 Mar 2022 22:21:04 +0000 Subject: [PATCH 224/227] Use zend_result/bool in spl_array.c --- ext/spl/spl_array.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index e07a08a71ed74..f6a11e7231da1 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -115,7 +115,7 @@ static inline bool spl_array_is_object(spl_array_object *intern) /* {{{ */ } /* }}} */ -static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht); +static zend_result spl_array_skip_protected(spl_array_object *intern, HashTable *aht); static zend_never_inline void spl_array_create_ht_iter(HashTable *ht, spl_array_object* intern) /* {{{ */ { @@ -552,7 +552,10 @@ static void spl_array_unset_dimension(zend_object *object, zval *offset) /* {{{ spl_array_unset_dimension_ex(1, object, offset); } /* }}} */ -static int spl_array_has_dimension_ex(bool check_inherited, zend_object *object, zval *offset, int check_empty) /* {{{ */ +/* check_empty can take value 0, 1, or 2 + * 0/1 are used as normal boolean, but 2 is used for the case when this function is called from + * the offsetExists() method, in which case it needs to report the offset exist even if the value is null */ +static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object, zval *offset, int check_empty) /* {{{ */ { spl_array_object *intern = spl_array_from_obj(object); zval rv, *value = NULL, *tmp; @@ -873,7 +876,7 @@ static int spl_array_compare_objects(zval *o1, zval *o2) /* {{{ */ return result; } /* }}} */ -static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht) /* {{{ */ +static zend_result spl_array_skip_protected(spl_array_object *intern, HashTable *aht) /* {{{ */ { zend_string *string_key; zend_ulong num_key; @@ -903,7 +906,7 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht) /* return FAILURE; } /* }}} */ -static int spl_array_next_ex(spl_array_object *intern, HashTable *aht) /* {{{ */ +static zend_result spl_array_next_ex(spl_array_object *intern, HashTable *aht) /* {{{ */ { uint32_t *pos_ptr = spl_array_get_pos_ptr(aht, intern); @@ -915,7 +918,7 @@ static int spl_array_next_ex(spl_array_object *intern, HashTable *aht) /* {{{ */ } } /* }}} */ -static int spl_array_next(spl_array_object *intern) /* {{{ */ +static zend_result spl_array_next(spl_array_object *intern) /* {{{ */ { HashTable *aht = spl_array_get_hash_table(intern); From 71a110fcaab2e641f4cc5194867e7038a3ccbe9a Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sun, 13 Mar 2022 15:15:57 +0000 Subject: [PATCH 225/227] Remove strnatcmp_ex() wrappers These APIs always returned SUCCESS. Closes GH-8195 --- UPGRADING.INTERNALS | 6 ++++++ ext/standard/php_string.h | 4 ---- ext/standard/string.c | 26 -------------------------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index cec9356406556..28fcb5e5a9540 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -29,6 +29,12 @@ PHP 8.2 INTERNALS UPGRADE NOTES 3. Module changes ======================== + a. ext/standard + - The PHP APIs string_natural_compare_function_ex(), + string_natural_case_compare_function(), and string_natural_compare_function() + have been removed. They always returned SUCCESS and were a wrapper around + strnatcmp_ex(). Use strnatcmp_ex() directly instead. + ======================== 4. OpCode changes ======================== diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index f795e4e2b69f6..0f31ff1e42827 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -59,10 +59,6 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return PHPAPI size_t php_strspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); PHPAPI size_t php_strcspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end); -PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, bool case_insensitive); -PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2); -PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2); - #if defined(_REENTRANT) # ifdef PHP_WIN32 # include diff --git a/ext/standard/string.c b/ext/standard/string.c index 826fa338be047..ce461cab21249 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -5406,32 +5406,6 @@ static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS, int fold_case) } /* }}} */ -PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, bool case_insensitive) /* {{{ */ -{ - zend_string *tmp_str1, *tmp_str2; - zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); - zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); - - ZVAL_LONG(result, strnatcmp_ex(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2), case_insensitive)); - - zend_tmp_string_release(tmp_str1); - zend_tmp_string_release(tmp_str2); - return SUCCESS; -} -/* }}} */ - -PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */ -{ - return string_natural_compare_function_ex(result, op1, op2, 1); -} -/* }}} */ - -PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */ -{ - return string_natural_compare_function_ex(result, op1, op2, 0); -} -/* }}} */ - /* {{{ Returns the result of string comparison using 'natural' algorithm */ PHP_FUNCTION(strnatcmp) { From e948d3c9c83231491b7b1e3fe1d8faa12efd0123 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 23 Mar 2022 23:59:41 +0000 Subject: [PATCH 226/227] Use zend_string_to(upper|lower)() API directly --- ext/standard/array.c | 4 ++-- ext/standard/string.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index aa89e3755b123..a3ce0d6c80cf7 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4529,9 +4529,9 @@ PHP_FUNCTION(array_change_key_case) entry = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); } else { if (change_to_upper) { - new_key = php_string_toupper(string_key); + new_key = zend_string_toupper(string_key); } else { - new_key = php_string_tolower(string_key); + new_key = zend_string_tolower(string_key); } entry = zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); zend_string_release_ex(new_key, 0); diff --git a/ext/standard/string.c b/ext/standard/string.c index ce461cab21249..593c67cb32248 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -3120,7 +3120,7 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha char *e; if (ZSTR_LEN(needle) == str_len) { - lc_needle = php_string_tolower(needle); + lc_needle = zend_string_tolower(needle); end = lc_haystack + ZSTR_LEN(haystack); for (p = lc_haystack; (r = (char*)php_memnstr(p, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle), end)); p = r + ZSTR_LEN(lc_needle)) { if (!new_str) { @@ -3141,7 +3141,7 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha const char *n; const char *endp = o + ZSTR_LEN(haystack); - lc_needle = php_string_tolower(needle); + lc_needle = zend_string_tolower(needle); n = ZSTR_VAL(lc_needle); while ((o = (char*)php_memnstr(o, n, ZSTR_LEN(lc_needle), endp))) { @@ -3185,7 +3185,7 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha nothing_todo: return zend_string_copy(haystack); } else { - lc_needle = php_string_tolower(needle); + lc_needle = zend_string_tolower(needle); if (memcmp(lc_haystack, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle))) { zend_string_release_ex(lc_needle, 0); From 814374faa1fe68dcf88dd1fe8b78685c27a8ab35 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Thu, 24 Mar 2022 00:13:51 +0000 Subject: [PATCH 227/227] fpm zlog_stream_buf_alloc_ex little simplifications. (#8224) --- sapi/fpm/fpm/zlog.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sapi/fpm/fpm/zlog.c b/sapi/fpm/fpm/zlog.c index 0938f08e89de4..350d75d1952e6 100644 --- a/sapi/fpm/fpm/zlog.c +++ b/sapi/fpm/fpm/zlog.c @@ -286,14 +286,8 @@ static zlog_bool zlog_stream_buf_alloc_ex(struct zlog_stream *stream, size_t nee { char *buf; size_t size = stream->buf.size ?: stream->buf_init_size; - - if (stream->buf.data) { - size = MIN(zlog_limit, MAX(size * 2, needed)); - buf = realloc(stream->buf.data, size); - } else { - size = MIN(zlog_limit, MAX(size, needed)); - buf = malloc(size); - } + size = MIN(zlog_limit, MAX((stream->buf.data ? (size << 1) : size), needed)); + buf = realloc(stream->buf.data, size); if (buf == NULL) { return 0;