Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a8bdfa6
ext/session: remove mod_user_class_name global
Girgias Feb 5, 2026
a9496bd
ext/session: refactor session_abort()
Girgias Feb 6, 2026
8926dc0
ext/session: refactor session_reset()
Girgias Feb 6, 2026
a0de1ac
ext/session: refactor session_write_close()
Girgias Feb 6, 2026
1041a47
ext/standard: throw ValueError if argument contains null byte in sess…
Girgias Feb 6, 2026
f6088f5
ext/session: remove session_adapt_url() function
Girgias Feb 6, 2026
ba17532
ext/session: use known 1 char zend_string to update boolean INI setting
Girgias Feb 6, 2026
71096cd
ext/session: use zend_strings for open handler
Girgias Feb 6, 2026
888b393
ext/session: fix typo in comment
Girgias Feb 9, 2026
9026396
ext/session: simplify php_session_reset()
Girgias Feb 9, 2026
ca08e5f
ext/session: reduce scope of variables
Girgias Feb 9, 2026
cc304d1
ext/session: refactor bin_to_readable()
Girgias Feb 9, 2026
8af0562
ext/session: add const qualifiers
Girgias Feb 9, 2026
e1b2f1f
ext/session: move variable initialization out of if condition
Girgias Feb 9, 2026
fcff846
Fix borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization (GH-21121)
iluuu1994 Feb 9, 2026
7c6f089
Improve shared_alloc_shm.c strategy to support OPcache JIT on Solaris
psumbera Dec 16, 2025
81de7b9
Merge branch 'PHP-8.4' into PHP-8.5
iluuu1994 Feb 9, 2026
8bb2312
Merge branch 'PHP-8.5'
iluuu1994 Feb 9, 2026
29cd577
ci: Add fork protection to workflow verify-bundled-files (GH-21171)
jorgsowa Feb 9, 2026
95fb174
[skip ci] Remove dead code in Zend/zend_multiply.h after zend_error_n…
arshidkv12 Feb 9, 2026
19ee3e6
Fix GH-21161: socket_set_option() crash with array 'addr' entry as null.
devnexen Feb 8, 2026
1ff5eb4
Merge branch 'PHP-8.4' into PHP-8.5
devnexen Feb 9, 2026
f037d49
Merge branch 'PHP-8.5'
devnexen Feb 9, 2026
d1ffe6a
Fix extension order in UPGRADING.INTERNALS
TimWolla Feb 9, 2026
ad83353
Fix line wrapping in NEWS/UPGRADING/UPGRADING.INTERNALS
TimWolla Feb 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/verify-bundled-files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ permissions:

jobs:
VERIFY_BUNDLED_FILES:
if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch'
name: Verify Bundled Files
runs-on: ubuntu-24.04
steps:
Expand Down
15 changes: 8 additions & 7 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,24 @@ PHP NEWS

- Posix:
. Added validity check to the flags argument for posix_access(). (arshidkv12)
. Added validity check to the permissions argument for posix_mkfifo(). (arshidkv12)
. Added validity check to the permissions argument for posix_mkfifo().
(arshidkv12)

- Reflection:
. Fixed bug GH-20217 (ReflectionClass::isIterable() incorrectly returns true
for classes with property hooks). (alexandre-daubois)

- Soap:
. Soap::__setCookie() when cookie name is a digit is now not stored and represented
as a string anymore but a int. (David Carlier)
. Soap::__setCookie() when cookie name is a digit is now not stored and
represented as a string anymore but a int. (David Carlier)

- Sockets:
. Added the TCP_USER_TIMEOUT constant for Linux to set the maximum time in milliseconds
transmitted data can remain unacknowledged. (James Lucas)
. Added the TCP_USER_TIMEOUT constant for Linux to set the maximum time in
milliseconds transmitted data can remain unacknowledged. (James Lucas)
. Added AF_UNSPEC support for sock_addrinfo_lookup() as a sole umbrella for
AF_INET* family only. (David Carlier)
. Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new optional
parameter). (David Carlier)
. Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new
optional parameter). (David Carlier)

- SPL:
. DirectoryIterator key can now work better with filesystem supporting larger
Expand Down
21 changes: 16 additions & 5 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ PHP 8.6 UPGRADE NOTES
. Invalid values now throw in Phar::mungServer() instead of being silently
ignored.

- Session:
. A ValueError is not thrown if $name is a string containing null bytes in
session_module_name().

- Standard:
. Invalid mode values now throw in array_filter() instead of being silently
defaulted to 0.
Expand All @@ -39,8 +43,14 @@ PHP 8.6 UPGRADE NOTES
. finfo_file() now works with remote streams.

- Intl:
. Added IntlNumberRangeFormatter class to format an interval of two numbers with a given skeleton, locale, IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, IntlNumberRangeFormatter::COLLAPSE_ALL collapse and
IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY and
. Added IntlNumberRangeFormatter class to format an interval of two numbers
with a given skeleton, locale, IntlNumberRangeFormatter::COLLAPSE_AUTO,
IntlNumberRangeFormatter::COLLAPSE_NONE,
IntlNumberRangeFormatter::COLLAPSE_UNIT,
IntlNumberRangeFormatter::COLLAPSE_ALL collapse and
IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE,
IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE,
IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY and
IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE identity fallbacks.
It is supported from icu 63.

Expand Down Expand Up @@ -102,7 +112,8 @@ PHP 8.6 UPGRADE NOTES
========================================

- Standard:
. `clamp()` returns the given value if in range, else return the nearest bound.
. `clamp()` returns the given value if in range, else return the nearest
bound.
RFC: https://wiki.php.net/rfc/clamp_v2

========================================
Expand Down Expand Up @@ -185,8 +196,8 @@ PHP 8.6 UPGRADE NOTES

- Core:
. `printf()` using only `%s` and `%d` will be compiled into the equivalent
string interpolation, avoiding the overhead of a function call and repeatedly
parsing the format string.
string interpolation, avoiding the overhead of a function call and
repeatedly parsing the format string.
. Arguments are now passed more efficiently to known constructors (e.g. when
using new self()).
. array_map() using a first-class callable or partial function application
Expand Down
28 changes: 19 additions & 9 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -77,32 +77,42 @@ PHP 8.6 INTERNALS UPGRADE NOTES

. build/gen_stub.php may now generate a _decl.h file in addition to
the _arginfo.h file, if the stub declares enums and is annotated with
@generate-c-enums. For each enum the file will contain a C enum. Enum values
can be compared to the result of zend_enum_fetch_case_id(zend_object*).
@generate-c-enums. For each enum the file will contain a C enum. Enum
values can be compared to the result of
zend_enum_fetch_case_id(zend_object*).

========================
3. Module changes
========================

- ext/xml:
. Removed the XML_ExpatVersion() libxml compatibility wrapper,
as it was unused.
. Removed the XML_GetCurrentByteCount() libxml compatibility wrapper,
as it was unused and could return the wrong result.

- ext/mbstring:
. Added GB18030-2022 to default encoding list for zh-CN.

- ext/mysqlnd:
. Dropped session_options parameter from all methods in mysqlnd_auth.
The same information is present in conn->options and should be used instead.
The same information is present in conn->options and should be used
instead.

- ext/session:
. php_session_flush() now returns a bool rather than a zend_result.
. Removed session_adapt_url().
. PS_OPEN_ARGS is now defined as
`void **mod_data, zend_string *save_path, zend_string *session_name`
rather than
`void **mod_data, const char *save_path, const char *session_name`

- ext/standard:
. _php_error_log() now has a formal return type of zend_result.
. _php_error_log() now accepts zend_string* values instead of char*.
. _php_error_log_ex() has been removed.
. php_mail()'s extra_cmd parameter is now a zend_string*.

- ext/xml:
. Removed the XML_ExpatVersion() libxml compatibility wrapper,
as it was unused.
. Removed the XML_GetCurrentByteCount() libxml compatibility wrapper,
as it was unused and could return the wrong result.

========================
4. OpCode changes
========================
Expand Down
4 changes: 3 additions & 1 deletion Zend/Optimizer/block_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
&& zend_optimizer_update_op1_const(op_array, opline, &c)) {
VAR_SOURCE(op1) = NULL;
if (opline->opcode != ZEND_JMP_NULL
&& !zend_bitset_in(used_ext, VAR_NUM(src->result.var))) {
&& !zend_bitset_in(used_ext, VAR_NUM(src->result.var))
/* FETCH_W with ZEND_FETCH_GLOBAL_LOCK does not free op1, which will be used again. */
&& !(opline->opcode == ZEND_FETCH_W && (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK))) {
literal_dtor(&ZEND_OP1_LITERAL(src));
MAKE_NOP(src);
}
Expand Down
2 changes: 0 additions & 2 deletions Zend/zend_multiply.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t

if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return ret;
}
Expand All @@ -355,7 +354,6 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si

if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
return 0;
}
return ret;
}
Expand Down
43 changes: 22 additions & 21 deletions ext/opcache/shared_alloc_shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
# define MIN(x, y) ((x) > (y)? (y) : (x))
#endif

#define SEG_ALLOC_SIZE_MAX 32*1024*1024
#define SEG_ALLOC_SIZE_MIN 2*1024*1024

typedef struct {
Expand All @@ -53,36 +52,38 @@ typedef struct {
static int create_segments(size_t requested_size, zend_shared_segment_shm ***shared_segments_p, int *shared_segments_count, const char **error_in)
{
int i;
size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size;
size_t allocate_size = 0, remaining_bytes, seg_allocate_size;
int first_segment_id = -1;
key_t first_segment_key = -1;
struct shmid_ds sds;
int shmget_flags;
zend_shared_segment_shm *shared_segments;

seg_allocate_size = SEG_ALLOC_SIZE_MAX;
/* determine segment size we _really_ need:
* no more than to include requested_size
*/
while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN) {
seg_allocate_size >>= 1;
}

shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;

/* try allocating this much, if not - try shrinking */
while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) {
allocate_size = MIN(requested_size, seg_allocate_size);
first_segment_id = shmget(first_segment_key, allocate_size, shmget_flags);
if (first_segment_id != -1) {
break;
/* Try contiguous allocation first. */
seg_allocate_size = requested_size;
first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags);
if (UNEXPECTED(first_segment_id == -1)) {
/* Search for biggest n^2 < requested_size. */
seg_allocate_size = SEG_ALLOC_SIZE_MIN;
while (seg_allocate_size < requested_size / 2) {
seg_allocate_size *= 2;
}
seg_allocate_size >>= 1; /* shrink the allocated block */
}

if (first_segment_id == -1) {
*error_in = "shmget";
return ALLOC_FAILURE;
/* try allocating this much, if not - try shrinking */
while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) {
first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags);
if (first_segment_id != -1) {
break;
}
seg_allocate_size >>= 1; /* shrink the allocated block */
}

if (first_segment_id == -1) {
*error_in = "shmget";
return ALLOC_FAILURE;
}
}

*shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1;
Expand Down
27 changes: 27 additions & 0 deletions ext/opcache/tests/oss-fuzz-481014628.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
OSS-Fuzz #481014628: Borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization
--EXTENSIONS--
opcache
--INI--
opcache.enable=1
opcache.enable_cli=1
--FILE--
<?php

function f() {
return 'foo';
}

function test() {
global ${f()};
var_dump($foo);
}

test();
$foo = 42;
test();

?>
--EXPECT--
NULL
int(42)
17 changes: 10 additions & 7 deletions ext/session/mod_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,19 +369,22 @@ PS_OPEN_FUNC(files)
int argc = 0;
size_t dirdepth = 0;
int filemode = 0600;
const char *used_save_path;

if (*save_path == '\0') {
if (ZSTR_LEN(save_path) == 0) {
/* if save path is an empty string, determine the temporary dir */
save_path = php_get_temporary_directory();
used_save_path = php_get_temporary_directory();

if (php_check_open_basedir(save_path)) {
if (php_check_open_basedir(used_save_path)) {
return FAILURE;
}
} else {
used_save_path = ZSTR_VAL(save_path);
}

/* split up input parameter */
last = save_path;
p = strchr(save_path, ';');
last = used_save_path;
p = strchr(used_save_path, ';');
while (p) {
argv[argc++] = last;
last = ++p;
Expand All @@ -407,14 +410,14 @@ PS_OPEN_FUNC(files)
return FAILURE;
}
}
save_path = argv[argc - 1];
used_save_path = argv[argc - 1];

data = ecalloc(1, sizeof(*data));

data->fd = -1;
data->dirdepth = dirdepth;
data->filemode = filemode;
data->basedir = zend_string_init(save_path, strlen(save_path), /* persistent */ false);
data->basedir = zend_string_init(used_save_path, strlen(used_save_path), /* persistent */ false);

if (PS_GET_MOD_DATA()) {
ps_close_files(mod_data);
Expand Down
7 changes: 3 additions & 4 deletions ext/session/mod_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,11 @@ PS_OPEN_FUNC(user)
{
zval args[2];
zval retval;
zend_result ret = FAILURE;

ZEND_ASSERT(!Z_ISUNDEF(PSF(open)));

ZVAL_STRING(&args[0], (char*)save_path);
ZVAL_STRING(&args[1], (char*)session_name);
ZVAL_STR(&args[0], zend_string_dup(save_path, false));
ZVAL_STR(&args[1], zend_string_dup(session_name, false));

zend_try {
ps_call_handler(&PSF(open), 2, args, &retval);
Expand All @@ -102,7 +101,7 @@ PS_OPEN_FUNC(user)

PS(mod_user_implemented) = true;

ret = verify_bool_return_type_userland_calls(&retval);
zend_result ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}
Expand Down
5 changes: 2 additions & 3 deletions ext/session/mod_user_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@

PHP_METHOD(SessionHandler, open)
{
char *save_path = NULL, *session_name = NULL;
size_t save_path_len, session_name_len;
zend_string *save_path, *session_name;
zend_result ret;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &save_path, &save_path_len, &session_name, &session_name_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &save_path, &session_name) == FAILURE) {
RETURN_THROWS();
}

Expand Down
7 changes: 2 additions & 5 deletions ext/session/php_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#define PHP_SESSION_VERSION PHP_VERSION

/* save handler macros */
#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name
#define PS_OPEN_ARGS void **mod_data, zend_string *save_path, zend_string *session_name
#define PS_CLOSE_ARGS void **mod_data
#define PS_READ_ARGS void **mod_data, zend_string *key, zend_string **val, zend_long maxlifetime
#define PS_WRITE_ARGS void **mod_data, zend_string *key, zend_string *val, zend_long maxlifetime
Expand Down Expand Up @@ -174,7 +174,6 @@ typedef struct _php_ps_globals {
zval ps_validate_sid;
zval ps_update_timestamp;
} mod_user_names;
zend_string *mod_user_class_name;
bool mod_user_implemented;
bool mod_user_is_open;
bool auto_start;
Expand Down Expand Up @@ -249,8 +248,6 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS);
PHPAPI zend_result php_session_validate_sid(PS_VALIDATE_SID_ARGS);
PHPAPI zend_result php_session_update_timestamp(PS_UPDATE_TIMESTAMP_ARGS);

PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, size_t *new_len);

PHPAPI zend_result php_session_destroy(void);
PHPAPI void php_add_session_var(zend_string *name);
PHPAPI zval *php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash);
Expand All @@ -264,7 +261,7 @@ PHPAPI zend_result php_session_register_serializer(const char *name,
zend_result (*decode)(PS_SERIALIZER_DECODE_ARGS));

PHPAPI zend_result php_session_start(void);
PHPAPI zend_result php_session_flush(bool write);
PHPAPI bool php_session_flush(bool write);
PHPAPI php_session_status php_get_session_status(void);

PHPAPI const ps_module *_php_find_ps_module(const char *name);
Expand Down
Loading
Loading