To detect errors in conversion from Unicode to another text encoding, each
mbstring conversion filter object maintains a count of 'bad' characters. After
a conversion operation finishes, this count is checked to see if there was any
error.
The problem with CP50220 was that mbstring used a chain of two conversion filter
objects. The 'bad character count' would be incremented on the second object in
the chain, but this didn't do anything, as only the count on the first such
object is ever checked.
Fix this by implementing the conversion using a single conversion filter object,
rather than a chain of two. This is possible because of the recent refactoring,
which pulled out the needed logic for CP50220 conversion into a helper function.
There's no need to dynamically allocate a struct to hold the 'mode' parameter;
just store it directly in `filt->opaque`. Some other things were also being done
in an unnecessarily roundabout way.
Also, the 'copy' function for CP50220 conversion filters was *both* broken
and unnecessary. Broken, because it malloc'd memory which was never freed by
anything. Unnecessary, because the point of the copy is so that various
algorithms can try running bytes through a conversion filter and see how many
output bytes or characters result, and then back out by restoring the filters
to their previous state. But here's the thing; CP50220 conversion filters don't
hold cached bytes, which is the main thing which would need to be restored to a
previous state.
This function pointer is only called when initializing the struct. After that
nothing is done with it. Therefore, there is no need to keep it in the struct.
This constructor function doesn't do anything different than the generic one.
There's no need to invoke it, either, when initializing a CP50220 conversion
filter.
As debug_print_backtrace() is not performance-critical, this
implements it by formatting the zend_fetch_backtrace() result.
This means there is only one place implementing the backtrace
construction logic, and they cannot go out of sync.
zend_fetch_backtrace() has much better test coverage, because
it is used by exceptions.
Closes GH-6869.
Now similar "fake" frames now materialized when fetching debug
backtraces. The patch also fixes few incorrect backtraces for generators
in *.phpt tests.
Handle this in the implementation of get_current_key of user_it,
so that the callers may assume that the key is not a reference.
Fixes oss-fuzz #33018.
shell_exec() can return null both when an error occurs or the program produces no output, or return false when popen failed, and treating null/false as an empty string has no effect on the behavior of phar here.
Now that the value is coerced to the correct type, we should be
treating this as a boolean, not an integer (treating it as an
integer was already incorrect before -- if people used the
property as documented they'd likely get garbage).
`buf` may contain NUL bytes, so we must not use `strcspn()` but rather
a binary safe variant. However, we also must not detect a stray CR as
line ending, and since we only need to check line endings at the end
of the buffer, we can nicely optimize.
Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
Closes GH-6836.
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.
PDO implement half of this, but this functionality is generally
useful. Provide these as zend_u64_to_str and zend_i64_to_str to
complement zend_long_to_str.
Previously this just assumed that the value was of a certain type.
I'm doing this in a generic way that checks against the declared
property type -- the handler function can then assume the value
to be of the correct type.