This change primarily splits SAPI deactivation to module and destroy
parts. The reason is that currently some SAPIs might bail out
on deactivation. One of those SAPI is PHP-FPM that can bail out on
request end if for example the connection is closed by the client
(web sever). The problem is that in such case the resources are not
freed and some values reset. The most visible impact can have not
resetting the PG(headers_sent) which can cause erorrs in the next
request. One such issue is described in #77780 bug which this fixes
and is also cover by a test in this commit. It seems reasonable
to separate deactivation and destroying of the resource which means
that the bail out will not impact it.
This fix is another solution to replace d0527427be, use zend_try and zend_catch to make sure persistent stream will be released when error occurred.
Closes GH-9332.
On Windows, closing a file which is locked may not immediately remove
the lock. The `LockFileEx()` documentation states:
| Therefore, it is recommended that your process explicitly unlock all
| files it has locked when it terminates.
We comply, and also use the macro `LOCK_EX` instead of the magic number
`2`.
Closes GH-8925.
This issue might happen if there is change of the fcgi stream when
the buffer is full. Then the empty record is created which signals
end of stream which is incorrect.
The actual fix without a test was contributed by GitHub user @loveharmful
in GH-3198.
Apparently, this has been forgotten when PHP 8.0.17RC1 and 8.0.18RC1
had been tagged.
We also fix the version of the fix for GH-8253, which didn't make it
into PHP 8.0.18RC1.
This is achieved by tracking the observers on the run_time_cache (with a fixed amount of slots, 2 for each observer).
That way round, if the run_time_cache is freed all associated observer data is as well.
This approach has been chosen, as to avoid any ABI or API breakage.
Future versions may for example choose to provide a hookable API for run_time_cache freeing or similar.
When bug 77574[1] has been fixed, the fix only catered to variables
retrieved via `getenv()` with a `$varname` passed, but neither to
`getenv()` without arguments nor to the general import of environment
variables into `$_ENV` and `$_SERVER`. We catch up on this by using
`GetEnvironmentStringsW()` in `_php_import_environment_variables()` and
converting the encoding to whatever had been chosen by the user.
[1] <https://bugs.php.net/bug.php?id=75574>
Closes GH-7928.
Since we're going to read from the current stream position anyway, the
`max_len` should be the size of the file minus the current position
(still catering to potentially filtered streams). We must, however,
make sure to cater to the file position being beyond the actual file
size.
While we're at, we also fix the step size in the comment, which is 8K.
A further optimization could be done for unfiltered streams, thus
saving that step size, but 8K might not be worth it.
Closes GH-7693.
The stream position is not related to the buffer, and needs to be
updated for non-seekable streams as well. The erroneous condition
around the position update is a relict of an old commit[1].
The unexpected test expectation is due to bug #81345.
[1] <088e2692c3>
Closes GH-7356.
When flushing the stream filters actually causes data to be written to
the stream, we need to update its position, because that is not done by
the streams' write methods.
Closes GH-7354.
When the time limit for a script is changed, when the script ends,
its INI value will be reset. This calls the event handler for the
timeout change, which will unset then reset the timeout. However,
this is done even if the script is done executing, and say, the CGI
or CLI web server process is idle.
This is probably incorrect, but isn't a problem on most platforms,
because PHP uses a timer that only ticks when the process is active
(that is, executing code). Since when it's idle, it's blocking on
listen/read, it won't tick because nothing executes. However, on
platforms where only the real-time timer is supported, (Cygwin/PASE)
it ticks regardless of if PHP is even executing. This means that the
idle processes are subject to timeouts from the INI reset on script
end.
This makes it so the timer is never set if the state is deactivating.
Testing with the CLI web server indicates the timer no longer
spuriously activates under PASE.
Closes GH-6683.
When mapping the file, we need to pass the proper `dwFileOffsetHigh`
instead of `0`.
Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
Closes GH-7158.