Skip to content
10 changes: 10 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,24 @@ PHP NEWS
emits a warning. (Girgias)
. Fixed bug GH-19637 (Incorrect Closure scope for FCC in constant
expression). (timwolla)
. Fixed bug GH-19613 (Stale array iterator pointer). (ilutov)

- Date:
. Fixed date_sunrise() and date_sunset() with partial-hour UTC offset.
(ilutov)

- EXIF:
. Added support to retrieve Exif from HEIF file. (Benstone Zhang)

- FPM:
. Fixed failed debug assertion when php_admin_value setting fails. (ilutov)

- Opcache:
. Fixed bug GH-19486 (Incorrect opline after deoptimization). (Arnaud)
. Fixed bug GH-19601 (Wrong JIT stack setup on aarch64/clang). (Arnaud)
. Fixed bug GH-19388 (Broken opcache.huge_code_pages). (Arnaud)
. Fixed bug GH-19657 (Build fails on non-glibc/musl/freebsd/macos/win
platforms). (Arnaud)

- PCRE:
. Upgraded to pcre2lib from 10.45 to 10.46. (nielsdos)
Expand Down
22 changes: 22 additions & 0 deletions Zend/tests/gh19613.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GH-19613: Invalidated array iterator pointer after array separation
--FILE--
<?php

$a = [1];
$i = 0;

foreach ($a as &$v) {
$a[0] = $a;
foreach ($v as &$w) {
$w = $a;

if ($i++ == 64) {
die("===DONE===\n");
}
}
}

?>
--EXPECT--
===DONE===
11 changes: 9 additions & 2 deletions Zend/zend_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,15 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval
&& EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
HT_DEC_ITERATORS_COUNT(iter->ht);
}
SEPARATE_ARRAY(array);
ht = Z_ARRVAL_P(array);

/* Inlined SEPARATE_ARRAY() with updating of iterator when EG(ht_iterators) grows. */
if (UNEXPECTED(GC_REFCOUNT(ht) > 1)) {
ZVAL_ARR(array, zend_array_dup(ht));
GC_TRY_DELREF(ht);
iter = EG(ht_iterators) + idx;
ht = Z_ARRVAL_P(array);
}

if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
HT_INC_ITERATORS_COUNT(ht);
}
Expand Down
2 changes: 1 addition & 1 deletion ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -5493,7 +5493,7 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, bool calc_s
t->zone_type = TIMELIB_ZONETYPE_ID;

if (gmt_offset_is_null) {
gmt_offset = timelib_get_current_offset(t) / 3600;
gmt_offset = timelib_get_current_offset(t) / 3600.0;
}

timelib_unixtime2local(t, time);
Expand Down
18 changes: 18 additions & 0 deletions ext/date/tests/sunfuncts_partial_hour_utc_offset.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
Incorrect timezone detection in date_sunrise() for partial-hour UTC offsets
--FILE--
<?php
date_default_timezone_set('Asia/Kolkata');
$timestamp = mktime(0, 0, 0, 2, 9, 2025);
$longitude = 22.57;
$latitude = 88.36;

echo @date_sunrise($timestamp, SUNFUNCS_RET_STRING, $longitude, $latitude), "\n";

$dt = new DateTime();
$dt->setTimestamp(date_sun_info($timestamp, $longitude, $latitude)['sunrise']);
echo $dt->format('H:i'), "\n";
?>
--EXPECT--
06:10
06:11
2 changes: 2 additions & 0 deletions ext/opcache/jit/tls/zend_jit_tls_aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ void *zend_jit_tsrm_ls_cache_address(
size_t module_index,
size_t module_offset
) {
#ifndef USE_FALLBACK
char *thread_pointer;
__asm__ __volatile__(
"mrs %0, tpidr_el0\n"
Expand All @@ -251,5 +252,6 @@ void *zend_jit_tsrm_ls_cache_address(
dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET);
return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset);
}
#endif
return NULL;
}
2 changes: 2 additions & 0 deletions ext/opcache/jit/tls/zend_jit_tls_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ void *zend_jit_tsrm_ls_cache_address(
size_t module_index,
size_t module_offset
) {
#ifndef USE_FALLBACK
char *thread_pointer;
__asm__ __volatile__(
"movl %%gs:0, %0\n"
Expand All @@ -235,5 +236,6 @@ void *zend_jit_tsrm_ls_cache_address(
dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET);
return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset);
}
#endif
return NULL;
}
2 changes: 2 additions & 0 deletions ext/opcache/jit/tls/zend_jit_tls_x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ void *zend_jit_tsrm_ls_cache_address(
size_t module_index,
size_t module_offset
) {
#ifndef USE_FALLBACK
char *thread_pointer;
__asm__ __volatile__(
"movq %%fs:0, %0\n"
Expand All @@ -218,5 +219,6 @@ void *zend_jit_tsrm_ls_cache_address(
dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET);
return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset);
}
#endif
return NULL;
}
2 changes: 2 additions & 0 deletions sapi/fpm/fpm/fpm_php.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ static int fpm_php_zend_ini_alter_master(char *name, int name_length, char *new_
ini_entry->modifiable = mode;
}
} else {
/* The string wasn't installed and won't be shared, it's safe to drop. */
GC_MAKE_PERSISTENT_LOCAL(duplicate);
zend_string_release_ex(duplicate, 1);
}

Expand Down
48 changes: 48 additions & 0 deletions sapi/fpm/tests/php_admin_value-failure.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
--TEST--
RC violation on failed php_admin_value
--SKIPIF--
<?php include "skipif.inc"; ?>
--FILE--
<?php

require_once "tester.inc";

$cfg = <<<EOT
[global]
error_log = {{FILE:LOG}}
[unconfined]
listen = {{ADDR}}
pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 3
php_admin_value[precision]=-2
EOT;

$code = <<<EOT
<?php
var_dump(ini_get('precision'));
EOT;

$ini = <<<EOT
precision=14
EOT;

$tester = new FPM\Tester($cfg, $code);
$tester->setUserIni($ini);
$tester->start();
$tester->expectLogStartNotices();
$tester->request()->expectBody(['string(2) "14"']);
$tester->terminate();
$tester->close();

?>
Done
--EXPECT--
Done
--CLEAN--
<?php
require_once "tester.inc";
FPM\Tester::clean();
?>
4 changes: 2 additions & 2 deletions sapi/phpdbg/phpdbg_bp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1206,14 +1206,14 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num) /* {{{ */
name = estrdup(brake->name);
name_len = strlen(name);
if (zend_hash_num_elements(&PHPDBG_G(bp)[type]) == 1) {
PHPDBG_G(flags) &= ~(1<<(brake->type+1));
PHPDBG_G(flags) &= ~(1ull<<(brake->type+1));
}
}
break;

default: {
if (zend_hash_num_elements(table) == 1) {
PHPDBG_G(flags) &= ~(1<<(brake->type+1));
PHPDBG_G(flags) &= ~(1ull<<(brake->type+1));
}
}
}
Expand Down