This is an alternative implementation for GH-10406 that resets the
has_buffered_data flag after finishing stream read so it does not impact
other ops->read use like for example php_stream_get_line.
Closes GH-11421
This adds support for the completed event. Since the read handler could
be entered twice towards the end of the stream we remember what the eof
flag was before reading so we can emit the completed event when the flag
changes to true.
Closes GH-10505.
On some filesystems, the copy operation fails if we specify a size
larger than the file size in certain circumstances and configurations.
In those cases EIO will be returned as errno and we will therefore fall
back to other methods.
copy_file_range can return early without copying all the data. This is
legal behaviour and worked properly, unless the mmap fallback was used.
The mmap fallback would read too much data into the destination,
corrupting the destination file. Furthermore, if the mmap fallback would
fail and have to fallback to the regular file copying mechanism, a
similar issue would occur because both maxlen and haveread are modified.
Furthermore, there was a mmap-resource in one of the failure paths of
the mmap fallback code.
This patch fixes these issues. This also adds regression tests using the
new copy_file_range early-return simulation added in the previous
commit.
copy_file_range() is a Linux-specific system call which allows
efficient copying between two file descriptors, eliminating the need
to transfer data from the kernel to userspace and back. For
networking file systems like NFS and Ceph, it even eliminates copying
data to the client, and local filesystems like Btrfs and XFS can
create shared extents.
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.
On x86_64 glibc memrchr() uses SSE/AVX CPU extensions and works much
faster then naive loop. On x86 32-bit we still use inlined version.
memrchr() is a GNU extension. Its prototype becomes available when
<string.h> is included with defined _GNU_SOURCE macro. Previously, we
defined it in "php_config.h", but some sources may include <string.h>
befire it. To avod mess we also pass -D_GNU_SOURCE to C compiler.
Use ASCII case conversion instead of locale-dependent case conversion in
the following places:
* grapheme_stripos() and grapheme_strripos() in the "fast" path
* ldap_get_entries()
* oci_pconnect() for case folding of parameters when constructing a key
into the connection or session pool
* SoapClient: case folding of function names
* get_meta_tags(): case conversion of property names
* http stream wrapper: header names
* phpinfo(): anchor names
* php_verror(): docref URLs
* rfc1867.c: Content-Type boundary parameter name
* streams.c: stream protocol names
Using locale-dependent case folding for these cases is either
unnecessary or actively incorrect. These functions could have
misbehaved when used with certain locales (e.g. Turkish).
Closes GH-7511.
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.
1. Update: http://www.php.net/license/3_01.txt to https, as there is anyway server header "Location:" to https.
2. Update few license 3.0 to 3.01 as 3.0 states "php 5.1.1, 4.1.1, and earlier".
3. In some license comments is "at through the world-wide-web" while most is without "at", so deleted.
4. fixed indentation in some files before |
fsync is a straightforward wrapper around the same C function
(implemented on Windows API as _commit() with identical signature).
From the man pages:
fsync() transfers ("flushes") all modified in-core data of (i.e.,
modified buffer cache pages for) the file referred to by the file
descriptor fd to the disk device (or other permanent storage
device) so that all changed information can be retrieved even if
the system crashes or is rebooted. This includes writing through
or flushing a disk cache if present. The call blocks until the
device reports that the transfer has completed.
RFC: https://wiki.php.net/rfc/fsync_function
Closes GH-6650.
This PR corrects misspellings identified by the check-spelling action.
The misspellings have been reported at jsoref@b6ba3e2#commitcomment-48946465
The action reports that the changes in this PR would make it happy: jsoref@602417c
Closes GH-6822.
This doesn't seem to serve a purpose anymore. Stats are expensive,
so doing an unnecessary stat just to short-circuit the zero size
case is rather dubious. It can also break with stream wrappers
that return inaccurate sizes (symfony/symfony#40574) and probably
can also break with stream filters.
Drop the special case and adjust code to make it more obvious that
it will still be handled correctly.
Closes GH-6807.
First, the `bzip2.compress` filter has the same issue as `zlib.deflate`
so we port the respective fix[1] to ext/bz2.
Second, there is still an issue, if a stream with an attached
compression filter is flushed before it is closed, without any writes
in between. In that case, the compression is never finalized. We fix
this by enforcing a `_php_stream_flush()` with the `closing` flag set
in `_php_stream_free()`, whenever a write filter is attached. This
call is superfluous for most write filters, but does not hurt, even
when it is unnecessary.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=20e75329f2adb11dd231852c061926d0e4080929>
Closes GH-6703.
In the case of a stream with no filters, php_stream_fill_read_buffer
only reads stream->chunk_size into the read buffer. If the stream has
filters attached, it could unnecessarily buffer a large amount of data.
With this change, php_stream_fill_read_buffer only proceeds until either
the requested size or stream->chunk_size is available in the read buffer.
Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>
Closes GH-6444.
Reading from a stream may return greater than zero, but nonetheless the
stream's EOF flag may have been set. We have to cater to this
condition by setting the close flag for filters.
We also have to cater to that change in the zlib.inflate filter:
If `inflate()` is called with flush mode `Z_FINISH`, but the output
buffer is not large enough to inflate all available data, it fails with
`Z_BUF_ERROR`. However, `Z_BUF_ERROR` is not fatal; in fact, the zlib
manual states: "If deflate returns with Z_OK or Z_BUF_ERROR, this
function must be called again with Z_FINISH and more output space
(updated avail_out) but no more input data, until it returns with
Z_STREAM_END or an error." Hence, we do so.
Closes GH-6001.
Instead of attempting to map large files into memory at once, we map
chunks of at most `PHP_STREAM_MMAP_MAX` bytes, and repeat that until we
hit the point where `php_stream_seek()` fails (see bug 54902), and copy
the rest of the file by reading and writing small chunks.
We also fix the mapping behavior for zero bytes on Windows, which did
not error (as with `mmap()`), but would have mapped the remaining file.