Two issues:
1) The check happened before ZPP checks
2) The `return;` statement caused NULL to be returned while this
function can only return booleans. An exception seems not acceptable
in stable versions, but a warning may do.
Closes GH-16386.
This partially reverts 0956267c08, which
introduced a type incompatibility where an `int` function is assigned
to a `zend_result` function. That yields a level 1 C4133 warning on
MSVC, and usually (e.g. in CI) level 1 warnings are elevated to errors,
so the build fails.[1]
The PHP-8.3 branch and up are uneffected by this, so the upward merges
should be empty.
[1] <0956267c08 (r144587696)>
This fixes -Winline errors where the functions are not ever inlined.
Also fixes some signature mismatches which were fixed previously but
for whatever reason were not ported to all maintained branches:
/usr/local/src/php/ext/session/session.c:1299:20:
warning:conflicting types for 'php_session_send_cookie' due to enum/integer mismatch;
have 'zend_result(void)' {aka 'ZEND_RESULT_CODE(void)'} [-Wenum-int-mismatch]
1299 | static zend_result php_session_send_cookie(void) /* {{{ */
| ^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/src/php/ext/session/session.c:100:12:
note: previous declaration of 'php_session_send_cookie' with type 'int(void)'
100 | static int php_session_send_cookie(void);
| ^~~~~~~~~~~~~~~~~~~~~~~
The hash tables used are allocated via the persistent allocator.
When using ini_set, the allocation happens via the non-persistent
allocator. When the table is then freed in GSHUTDOWN, we get a crash
because the allocators are mismatched.
As a side note, it is strange that this is designed this way, because it
means that ini_sets persist between requests...
Co-authored-by: Kamil Tekiela <tekiela246@gmail.com>
It's illegal to return from a bailout because that doesn't restore the
original bailout data. Return outside of it.
Test by YuanchengJiang
Closes GH-13689.
Several session tests incidentally check the values of INI variables
like session.name and session.save_path. This isn't the point of the
tests, and it can cause spurious failures if (for example) you want to
override your temporary directory while testing. So here, we make the
expected output patterns more lenient.
In an MPM worker scenario we have 1 module, N threads. Each thread must
have their globals initialised. If we only initialise the filename
fields in MINIT, then the threads have an uninitialized value. If the
uninitialized value is not NULL, this leads to segfaults upon access.
Closes GH-11530.
* Note where a session was already started
Duplicated session starts can be annoying to debug. The error that
occurs when a session is already active doesn't tell you where it
was initialized, so figuring out the callsite involves manual
debugging to find it out.
This keeps track of the call site of session_start as a request
global, and frees at the end of the request. It should make it
easier to find these instances for PHP users.
The resulting message can look like:
Notice: session_start(): Ignoring session_start() because a session is already active (started from /home/calvin/src/php-src/inc.php on line 4) in /home/calvin/src/php-src/index.php on line 9
Fixes GH-10721
* Convert to using zend_string for session start location
* Fix leak with session start callsite filename
If this was already initialized, we'd forget it. Have shared free
between session_start and RSHUTDOWN.
* For sessions that are automatically started, note that
Easy to forget that you have this set, in which case, session start
is done at RINIT outside of user code. Because this config option
can't change at runtime, we can check for it and make the error
more specific if that's the case.
* sid can never be NULL because it was NULL-checked earlier
* Change namelen to size_t because it is always unsigned and less in size than size_t
* Remove redundant check on ser
It can't be NULL, and even if it could, the ser++ would be UB.
In SessionHandler::gc, we use a virtual call to PS(default_mod)->s_gc to
call the gc implementation. That return value is checked against
FAILURE (-1).
One of the call targets of PS(default_mod)->s_gc is ps_gc_files().
ps_gc_files() calls to ps_files_cleanup_dir(). The latter function has
some error checks and outputs a notice if something goes wrong. In cases
of errors, the function returns 0. This means that the check in
SessionHandler::gc will misinterpret this as a success and report that 0
files have been *successfully* cleaned up. Fix it by returning -1 to
indicate something *did* go wrong.
Closes GH-10644.
This was introduced in 3467526a65 and the
corresponding RFC gives some reasoning. However the CSPRNG being “not secure
enough” is not a thing and reading these extra bytes is just security theater:
If the CSPRNG would hypothetically be broken, then PHP’s session IDs are the
least of one’s concerns, because we already trust it in `random_bytes()` and
might generate long-term secrets using that.
* Unserialize: Migrate "Unexpected end of serialized data" to E_WARNING
* Unserialize: Migrate "Error at offset %d of %d bytes" to E_WARNING
* Unserialize: Migrate "%s is returned from __sleep() multiple times" to E_WARNING
* Add NEWS for “Promote unserialize() notices to warning”