1939 Commits
Author SHA1 Message Date
Ilija Tovilo 9705fda1bb Merge branch 'PHP-8.6' into master
* PHP-8.6:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:34:56 +02:00
Ilija Tovilo d6373dfe15 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:33:23 +02:00
Ilija Tovilo c7273b9ba8 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:30:04 +02:00
Ilija Tovilo 8a94bb3822 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:27:03 +02:00
Ilija Tovilo c1a5f468d0 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:12:35 +02:00
3584a98bda Avoid state corruption via bailout
- Replace bailout on OOM with UnwindExit
- Properly reset various globals that may be accessed during startup

Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
Co-authored-by: Jakub Zelenka <bukka@php.net>
Co-authored-by: Nora Dossche <7771979+ndossche@users.noreply.github.com>
Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
2026-10-21 16:06:22 +02:00
Jorg Adam Sowa 6e4082b2eb ext/session: Open session files with O_CLOEXEC (#24376)
Set close-on-exec atomically when opening the session file instead of
issuing a separate fcntl(F_SETFD) call afterwards. This saves one
syscall per request and closes the window in which the descriptor could
leak into a child process forked by another thread. The fcntl() fallback
is kept for platforms without O_CLOEXEC.
2026-10-16 21:55:36 +02:00
Ilia Alshanetsky 9603591b91 Merge branch 'PHP-8.6'
* PHP-8.6:
  ext/session: Truncate session file after successful write
2026-10-15 13:49:39 -04:00
Ilia Alshanetsky 1fa14b029a Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  ext/session: Truncate session file after successful write
2026-10-15 13:47:35 -04:00
Ilia Alshanetsky 0f6efebf96 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/session: Truncate session file after successful write
2026-10-15 13:44:56 -04:00
Ilia Alshanetsky c2b02f24df ext/session: Truncate session file after successful write
Truncating before a shorter write discards the old session data even when
the write fails without storing any bytes. Truncate only after the full
write and update the cached size for subsequent writes.

Closes GH-23653
2026-10-15 13:42:08 -04:00
Jorg Adam Sowa 89561c83ef ext/session: simplify temp directory handling in tests (#24312)
Drop the pre-emptive rmdir() before mkdir(), move cleanup into --CLEAN--
sections, stop bug61470 from writing session files into the tests
directory, and remove a --CLEAN-- section in rfc1867_sid_invalid that
deleted a file nothing creates.
2026-10-14 20:46:59 +02:00
Jorg Adam Sowa cb491daca3 ext/session: remove test made unreachable by cookie attribute validation (#24325)
session_start_cookie_header_rejected.phpt injected a newline through
session.cookie_path to make the SAPI reject the Set-Cookie header.
Since b9a0228bd8 session.cookie_path and session.cookie_domain reject
CR/LF up front, so no userland input can reach that branch any more
and the test failed.
2026-10-14 16:24:50 +01:00
Ilia Alshanetsky b9a0228bd8 ext/session: reject cookie separators in cookie_path and cookie_domain (#22925)
php_session_send_cookie() appends session.cookie_path and
session.cookie_domain to the Set-Cookie header verbatim, and neither
setting rejected the separators that terminate a cookie attribute. An
application could therefore append its own Domain, Path, HttpOnly,
Secure, or SameSite attribute through either value. cookie_path now
rejects ";" and CR/LF, which RFC 6265 path-value excludes, while keeping
the comma it allows; cookie_domain takes the set setcookie() enforces on
$domain.

Closes GH-22925
2026-10-14 06:28:08 -04:00
Ilia Alshanetsky c65321c70f session: close the save handler before session_reset() reopens it (#23597)
php_session_reset() called php_session_initialize() on an already active
session, so the save handler's open() and read() ran a second time with no
intervening close(). Abort the session first, pairing every open() with a
close().

Closes GH-23597
2026-10-13 15:35:12 -04:00
Ilia Alshanetsky be2ece9a4f Merge branch 'PHP-8.6'
* PHP-8.6:
  ext/session: do not reuse session state a save handler tore down
2026-10-13 14:39:11 -04:00
Ilia Alshanetsky 5ede5b163e Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  ext/session: do not reuse session state a save handler tore down
2026-10-13 14:39:10 -04:00
Ilia Alshanetsky f2a7cb81a6 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/session: do not reuse session state a save handler tore down
2026-10-13 14:33:23 -04:00
Ilia Alshanetsky 751190d8e0 ext/session: do not reuse session state a save handler tore down
session_regenerate_id() runs the userland write or destroy handler and
then the close handler, and keeps operating on PS(id) afterwards. Any of
them may call session_destroy(): php_session_destroy() runs
php_rshutdown_session_globals() even when the recursive call was
rejected, releasing PS(id) and setting it to NULL, so the following
zend_string_release_ex() dereferences NULL. Check that the session is
still active once every handler has run.

Closes GH-22926
2026-10-13 14:31:07 -04:00
Jorg Adam Sowa 59b790a54a ext/session: remove dead !O_NOFOLLOW fallback (#24291) 2026-10-13 16:52:59 +02:00
Ilia Alshanetsky 80d2b99719 Merge branch 'PHP-8.6'
* PHP-8.6:
  ext/session: Close save handler when session encoding fails
2026-10-12 06:43:29 -04:00
Ilia Alshanetsky ae27423c33 ext/session: Close save handler when session encoding fails
Since 86b4921157, php_session_save_current_state() returns without calling
the save handler's close callback when the serializer returns NULL, e.g. for
a $_SESSION key containing '|'. session_write_close() still returns true, but
the files handler keeps its LOCK_EX on the session file until request
shutdown, blocking concurrent requests for the same session, and a user
handler extending SessionHandler has its close() run at shutdown after the
session is gone. Close the handler on that return as the rest of the function
and session_regenerate_id() do; with an exception pending the engine already
refuses to call a user close() callback.

Closes GH-24022
2026-10-12 06:43:28 -04:00
Daniel Scherzer 4c594ca8ef Merge branch 'PHP-8.6'
* PHP-8.6:
  [`%pS` migration] Use `%pS` in ext/session (#23168)
2026-10-05 11:22:51 -07:00
Daniel Scherzer 464c95a78e [%pS migration] Use %pS in ext/session (#23168) 2026-10-05 11:22:18 -07:00
Kamil Tekiela 4ab0ffb5d1 Zend: Remove returns after zend_error_noreturn (#23285) 2026-10-01 17:53:54 +01:00
Kamil Tekiela 94db015809 Remove redundant parentheses in session tests (#23609) 2026-09-29 12:31:51 +01:00
Gina Peter Banyard 814ade8880 session: clean-up code relating to calling user functions (#23909) 2026-09-26 00:57:18 +01:00
Noah Webber 5a9d50dc61 Fix typos, grammatical errors, and refactor misspelled local identifiers (#23803)
Correct typographical and grammatical mistakes across docs, comments, and build tools. Refactor local identifiers childrens to children in RecursiveFilterIterator and sav to saved_char in sapi_header_add_op.
2026-09-24 15:56:13 +02:00
Ilia Alshanetsky 6da7eabab4 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  ext/session: Preserve exceptions thrown by create_sid()
2026-09-23 12:28:08 -04:00
Ilia Alshanetsky 28e41a9c47 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/session: Preserve exceptions thrown by create_sid()
2026-09-23 12:21:54 -04:00
Ilia Alshanetsky eacd1576ad ext/session: Preserve exceptions thrown by create_sid()
Do not replace pending exceptions with return-value validation errors in
the user handler adapter, including exceptions raised while destroying
invalid return values. This preserves the original exception for
session_start(), session_create_id(), and session_regenerate_id().

Closes GH-23854
2026-09-23 12:21:26 -04:00
Ilia Alshanetsky 30ae72d529 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  ext/session: Abort strict-mode re-creation when create_sid() fails
2026-09-22 20:51:39 -04:00
Ilia Alshanetsky 495c4947c6 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/session: Abort strict-mode re-creation when create_sid() fails
2026-09-22 20:51:19 -04:00
Ilia Alshanetsky 4868dd4e02 ext/session: Abort strict-mode re-creation when create_sid() fails
When a save handler rejects the session ID under session.use_strict_mode,
php_session_initialize() papered over a failing s_create_sid() by generating
an internal ID and carrying on, so reset_id()'s Set-Cookie and SID side
effects ran for a session that never started, and a second failure left
PS(id) NULL. Mirror the primary no-ID branch: abort the session, throw when
no exception is pending, and return FAILURE. Sibling sites audited,
session_regenerate_id() and session_create_id() already NULL-check with
their own error paths.

Closes GH-23847
2026-09-22 20:36:57 -04:00
Jorg Sowa b117d8edf1 Merge branch 'PHP-8.5' 2026-09-07 23:08:55 +02:00
Jorg Sowa 9af8bc4655 Merge branch 'PHP-8.4' into PHP-8.5 2026-09-07 23:08:14 +02:00
Michael Orlitzky e8c1e3a8b3 ext/session: allow session.save_path to be nonempty in this test
commit 33b13ae5de
Author: Michael Orlitzky <michael@orlitzky.com>
Date:   Tue Sep 1 17:58:13 2026 -0400

    ext/session/.../gh23043.phpt: session.save_path can be nonempty

    Allow session.save_path to be nonempty in this test, as the test
    itself does not empty it, and in automated setups it is common to
    force all "temporary stuff" to a dedicated location.

Closes GH-23537
2026-09-07 23:06:39 +02:00
Dmytro Kulyk 67135cb97b gen_stub: Conditionally include zend_attributes.h to arginfo based on usage (#21570)
Headers required by the generated code (zend_attributes.h, zend_constants.h, zend_enum.h) are collected during generation and emitted as includes at the top of the arginfo file, with the same preprocessor conditions and PHP version guards as the code that needs them.

Removes the manual zend_attributes.h and zend_enum.h includes from sources that only needed them for the arginfo file they include.
2026-09-06 21:25:20 +02:00
Ilia Alshanetsky c96900ee74 Merge branch 'PHP-8.5'
* PHP-8.5:
  ext/session: report a rejected session cookie header
2026-08-23 13:03:35 -04:00
Ilia Alshanetsky 0990de7a55 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/session: report a rejected session cookie header
2026-08-23 13:00:28 -04:00
Ilia Alshanetsky 0870487b62 ext/session: report a rejected session cookie header
php_session_send_cookie() discarded the result of sapi_add_header_ex()
and always returned SUCCESS. When the SAPI refuses a Set-Cookie header
carrying CR or LF, the warning it emits can reach a userland error
handler that calls session_destroy(), and php_session_reset_id() then
appends the released PS(id). Return what sapi_add_header_ex() reports so
the caller stops before touching session state again.

Closes GH-22923
2026-08-23 12:57:11 -04:00
Ilia Alshanetsky 66d496061c Document and test SessionHandler::validateId() (#23071)
The method landed in 6901c87aea with no NEWS or UPGRADING entry. Add
both, and a test pinning that an unknown ID is regenerated rather than
adopted when the built-in handler runs with session.use_strict_mode=1.

Closes GH-23071
2026-08-18 21:41:16 -04:00
Jorg Sowa 1e4b1d41d7 Merge branch 'PHP-8.4' into PHP-8.5 2026-08-18 22:58:31 +02:00
Jorg Sowa d974c64303 Fix NULL pointer dereference in SessionHandler::create_sid()
s_create_sid() can return NULL when php_random_bytes_throw() fails
(e.g. CSPRNG exhaustion), but RETURN_STR() dereferences the string
unconditionally. Every other internal caller of s_create_sid() in
session.c (php_session_initialize, session_regenerate_id) already
NULL-checks the result; this PHP-facing method, reachable from any
userland SessionHandler subclass via create_sid(), did not.

No dedicated regression test is added: forcing php_random_bytes_throw()
to fail is not portably reproducible from a .phpt test (it's a raw
getrandom() syscall on Linux and CCRandomGenerateBytes on macOS, neither
of which can be faulted from userland), which is also why the existing
NULL-checks this mirrors in session.c have none either.
2026-08-18 22:58:03 +02:00
Lazizbek Ergashev 90b43f04bf Fix GH-23056: missing handler name in session write warning (#23059)
Closes GH-23056
2026-08-18 20:47:59 +01:00
Lazizbek Ergashev 52767e6ee7 session: fix create_sid()/validateId() check depending on interface order (#23329)
Closes GH-23328
2026-08-18 19:50:33 +01:00
Gina Peter Banyard 6901c87aea session: deprecate passing save handlers without create_sid() and validateId() methods
RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_passing_a_sessionhandler_object_to_session_set_save_handler_which_does_not_contain_the_create_sid_and_validateid_methods
2026-08-16 22:16:17 +01:00
Gina Peter Banyard 00f90287a1 session: add create_sid and validateId methods to some tests 2026-08-16 22:16:17 +01:00
Gina Peter Banyard 61c2b72eec session: fix some expectations for C session handlers (#23297)
We *explicitly* say that mod_data will be not NULL for create_sid hooks and we violate this invariant if SessionHandler::open() is overwridden without calling the parent method.

At the same time add comments explaining the situation and fix some other potential footguns.
2026-08-15 16:54:05 +01:00
Weilin Du 600e4a8445 tree-wide: Refactor with zend_string_ends_with* (#23216) 2026-08-14 17:01:16 +08:00