Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 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
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
4 changes: 4 additions & 0 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 Down
8 changes: 8 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ PHP 8.6 INTERNALS UPGRADE NOTES
. Dropped session_options parameter from all methods in mysqlnd_auth.
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*.
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