diff --git a/ext/intl/collator/collator_sort.cpp b/ext/intl/collator/collator_sort.cpp index 2b1122cb747a..b7c2b8736596 100644 --- a/ext/intl/collator/collator_sort.cpp +++ b/ext/intl/collator/collator_sort.cpp @@ -262,12 +262,13 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) UCollator* saved_collator; zval* array = nullptr; HashTable* hash = nullptr; + zend_array* sorted = nullptr; zend_long sort_flags = COLLATOR_SORT_REGULAR; COLLATOR_METHOD_INIT_VARS /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa/|l", + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa|l", &object, Collator_ce_ptr, &array, &sort_flags ) == FAILURE ) { RETURN_THROWS(); @@ -286,8 +287,14 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) hash = Z_ARRVAL_P( array ); + /* Copy array, so the in-place modifications will not be visible to the callback function */ + sorted = zend_array_dup( hash ); + /* Convert strings in the specified array from UTF-8 to UTF-16. */ - collator_convert_hash_from_utf8_to_utf16( hash, COLLATOR_ERROR_CODE_P( co ) ); + collator_convert_hash_from_utf8_to_utf16( sorted, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) { + zend_array_destroy( sorted ); + } COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-8 to UTF-16" ); /* Save specified collator in the request-global (?) variable. */ @@ -295,15 +302,23 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) INTL_G( current_collator ) = co->ucoll; /* Sort specified array. */ - zend_hash_sort(hash, collator_compare_func, renumber); + zend_hash_sort( sorted, collator_compare_func, renumber ); /* Restore saved collator. */ INTL_G( current_collator ) = saved_collator; /* Convert strings in the specified array back to UTF-8. */ - collator_convert_hash_from_utf16_to_utf8( hash, COLLATOR_ERROR_CODE_P( co ) ); + collator_convert_hash_from_utf16_to_utf8( sorted, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) { + zend_array_destroy( sorted ); + } COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-16 to UTF-8" ); + zval garbage; + ZVAL_COPY_VALUE( &garbage, array ); + ZVAL_ARR( array, sorted ); + zval_ptr_dtor( &garbage ); + RETURN_TRUE; } /* }}} */ diff --git a/ext/intl/tests/collator_sort_modify_during_compare.phpt b/ext/intl/tests/collator_sort_modify_during_compare.phpt new file mode 100644 index 000000000000..427f5833f1fc --- /dev/null +++ b/ext/intl/tests/collator_sort_modify_during_compare.phpt @@ -0,0 +1,36 @@ +--TEST-- +Collator::sort(): mutating the array from __toString() during comparison must not corrupt the sort +--EXTENSIONS-- +intl +--FILE-- +sort($arr)); +var_dump($arr); +?> +--EXPECT-- +bool(true) +array(4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + object(Grow)#2 (0) { + } + [3]=> + string(1) "z" +} diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 14174bd5dc26..65a3d3b90eed 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -134,7 +134,6 @@ if test "$PHP_LDAP" != "no"; then dnl nor ldap_start_tls_s() AC_CHECK_FUNCS(m4_normalize([ ldap_control_find - ldap_extended_operation ldap_extended_operation_s ldap_parse_extended_result ldap_parse_reference diff --git a/ext/ldap/config.w32 b/ext/ldap/config.w32 index c6a7049aa1c6..1fa1fe3f777c 100644 --- a/ext/ldap/config.w32 +++ b/ext/ldap/config.w32 @@ -23,7 +23,6 @@ if (PHP_LDAP != "no") { AC_DEFINE('HAVE_LDAP_PASSWD', 1); AC_DEFINE('HAVE_LDAP_WHOAMI_S', 1); AC_DEFINE('HAVE_LDAP_REFRESH_S', 1); - AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION', 1); AC_DEFINE('HAVE_3ARG_SETREBINDPROC', 1); } else { WARNING("ldap not enabled; libraries and headers not found"); diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 224f6f7237eb..2fe0b1896a92 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -10242,10 +10242,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen && ZEND_MAP_PTR_IS_OFFSET(func->op_array.run_time_cache)) { run_time_cache = ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_CG(map_ptr_base)), (uintptr_t)ZEND_MAP_PTR(func->op_array.run_time_cache))); - } else if ((func && (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) || - (JIT_G(current_frame) && - JIT_G(current_frame)->call && - TRACE_FRAME_IS_CLOSURE_CALL(JIT_G(current_frame)->call))) { + } else if (func && (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { /* Closures always use direct pointers */ ir_ref local_func_ref = func_ref ? func_ref : ir_LOAD_A(jit_CALL(rx, func)); diff --git a/ext/opcache/tests/jit/gh22443.phpt b/ext/opcache/tests/jit/gh22443.phpt new file mode 100644 index 000000000000..869329b79b5c --- /dev/null +++ b/ext/opcache/tests/jit/gh22443.phpt @@ -0,0 +1,57 @@ +--TEST-- +GH-22443 (SIGSEGV in tracing JIT: run_time_cache offset stored without map_ptr dereference) +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_max_polymorphic_calls=0 +--FILE-- +helper((int) array_sum($a)); } + private function helper(int $x): int { return $x + 1; } +} + +function makeListener($listener): Closure { + return function ($event, $payload) use ($listener) { + return $listener(...array_values($payload)); + }; +} + +function invokeListeners(array $listeners, string $event, array $payload): int { + $r = 0; + foreach ($listeners as $l) { + $r += $l($event, $payload); + } + return $r; +} + +$svc = new Svc(); +$warm = []; +for ($k = 0; $k < 8; $k++) { + $warm[] = makeListener([$svc, 'm' . $k]); +} +$cold = [makeListener([$svc, 'coldMethod'])]; + +$s = 0; +for ($i = 0; $i < 4000000; $i++) { + $s += invokeListeners($warm, 'e', [$i & 7, ($i >> 2) & 7]); +} +for ($j = 0; $j < 5; $j++) { + $s += invokeListeners($cold, 'e', [$j, $j + 1]); +} +echo "done\n"; +?> +--EXPECT-- +done diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 index 1409f879b52c..63e996fe06da 100644 --- a/ext/pgsql/config.m4 +++ b/ext/pgsql/config.m4 @@ -38,7 +38,7 @@ if test "$PHP_PGSQL" != "no"; then old_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $PGSQL_CFLAGS" - AC_CHECK_DECLS([PGRES_TUPLES_CHUNK], + AC_CHECK_DECL([PGRES_TUPLES_CHUNK], PHP_CHECK_LIBRARY([pq], [PQsetChunkedRowsMode], [AC_DEFINE([HAVE_PG_SET_CHUNKED_ROWS_SIZE], [1], [Define to 1 if libpq has the 'PQsetChunkedRowsMode' function (PostgreSQL diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c index 645ce172fdcd..7903a294a037 100644 --- a/ext/shmop/shmop.c +++ b/ext/shmop/shmop.c @@ -224,7 +224,6 @@ PHP_FUNCTION(shmop_read) zend_long start, count; php_shmop *shmop; char *startaddr; - int bytes; zend_string *return_string; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oll", &shmid, shmop_ce, &start, &count) == FAILURE) { @@ -244,7 +243,7 @@ PHP_FUNCTION(shmop_read) } startaddr = shmop->addr + start; - bytes = count ? count : shmop->size - start; + zend_long bytes = count ? count : shmop->size - start; return_string = zend_string_init(startaddr, bytes, 0);