This adds more aggressive clearing of stat cache. It is added to the
filestat as well as plain wrapper operations which covers stream file
accessing as well as exec functions (using pipes). It should hopefully
fix the most visible issues with the stat cache.
Closes GH-17681
dom_xinclude_strip_fallback_references() now also takes into account
xi:include nodes children. This now subsumes all work done normally by
the old start/end node removal, so we can remove that code and start
using XML_PARSE_NOXINCNODE.
Closes GH-17878.
We must define `CURL_STATICLIB` only when building against a static
libcurl. The detection relies on our usual naming conventions, what
should be revised in the future (possibly using pkg-config, or
switching to CMake).
Closes GH-17857.
When a property default is based on a global constant, show the type of the
default. Previously, `format_default_value()` assumed that non-scalar and
non-array defaults were always going to be `IS_CONSTANT_AST` pointers, and when
the AST expression had been evaluated and produced an object, depending on when
the `ReflectionClass` or `ReflectionProperty` instance had been created, the
default was shown as one of `callable` or `__CLASS__`.
Instead, if the default value is an object (`IS_OBJECT`), show the type of that
object.
Add test cases for both of the `callable` and `__CLASS__` cases to confirm that
they now properly show the type of the constant.
Closes GH-15902.
Closes GH-17781.
We cannot properly get the column meta data of a statement which has
been prepared, but has not yet been executed. As such we bail out
early, reporting failure.
Closes GH-17850.
PharFileInfo just takes a pointer from the manifest without refcounting
anything. If the entry is then removed from the manifest while the
PharFileInfo object still exists, we get a UAF.
We fix this by using the fp_refcount field. This is technically a
behaviour change as the unlinking is now blocked, and potentially file
modifications can be blocked as well. The alternative would be to have a
field that indicates whether deletion is blocked, but similar corruption
bugs may occur as well with file overwrites, so we increment fp_refcount
instead.
This also fixes an issue where a destructor called multiple times
resulted in a UAF as well, by moving the NULL'ing of the entry field out
of the if.
Closes GH-17811.
gzread() and gzwrite() have effectively a 4GiB limit at the moment
because the APIs of the zlib library use unsigned ints.
For example, this means that the count argument of gzread() and gzwrite()
& co effectively are modulo 2**32.
Fix this by adding a loop to handle all bytes.
As for automated testing, I didn't find an easy way to write a phpt for
this that wouldn't use a lot of memory or requires a large file.
For instance, the gzread() test that I manually ran requires a 4MiB
input file (and I can't shrink it because zlib has a max window size).
Here are the testing instructions, run on 64-bit:
To test for gzwrite():
```php
$f = gzopen("out.txt.gz", "w");
gzwrite($f, str_repeat('a', 4*1024*1024*1024+64)); // 4GiB + 64 bytes
```
Then use `zcat out.txt.gz|wc -c` to check that all bytes were written
(should be 4294967360).
To test for gzread():
Create a file containing all a's for example that is 4GiB + 64 bytes.
Then compress it into out.txt.gz using the gzip command.
Then run:
```php
$f = gzopen("out.txt.gz", "r");
$str = gzread($f, 4*1024*1024*1024+64);
var_dump(strlen($str)); // 4294967360
var_dump(substr($str, -3)); // string (3) "aaa"
```
Closes GH-17775.
It seems like n === undefined must have worked on older versions of
jscript, but currently it just causes the insertion to silently fail.
This sets n to an empty string, allowing phpize to include the local
config.w32 files.
zlib_create_dictionary_string() allocates memory, so we can leak memory
if there's an early exit before the assignment to the return value.
Solve this by moving all validation upwards.
Closes GH-17788.
Because of the "H" modifier in ZPP, there are two bugs:
1) The stub is wrong and will cause a crash in debug mode.
2) Non-dynamic properties are not read correctly because they are not
DEINDIRECTed.
Closes GH-17750.
If the returned buffer string is of length 0, then a realloc can happen
with length 0. However, the behaviour is implementation-defined.
From 7.20.3.1 of C11 spec:
> If the size of the space requested is zero, the behavior is
> implementation-defined: either a null pointer is returned,
> or the behavior is as if the size were some nonzero value,
> except that the returned pointer shall not be used to access an object
This is problematic for the test case on my system as it returns NULL,
causing a memleak and later using it in memcpy causing UB.
The bucket code is not prepared to handle a NULL pointer.
To solve this, we use MAX to clamp the size to 1 at the least.
Closes GH-17656.
Conversion of floating point to integer values is undefined if the
integral part of the float value cannot be represented by the integer
type. We need to cater to that explicitly (in a manner similar to
`zend_dval_to_lval_cap()`).
Closes GH-17689.
This was asked to be checked in https://github.com/php/php-src/pull/17472#issuecomment-2591325036
There are 2 issues:
1) The UB in the if can overflow, and can be fixed by using zend_ulong
for the sum/sub.
2) fast_long_sub_function() has a problem when result aliases.
This is fixed in the same way as fast_long_add_function() works.
Closes GH-17666.
When a guard check is created for a variable to check if it's a packed array,
it is possible that there was no prior type check for that variable.
This happens in the global scope for example when the variable aliases.
In the test, this causes a dereference of address 8 because the integer
element in `$a` is interpreted as an array address.
This patch adds a check to see if the guard is handled.
If we were not able to determine or guard the type then we also cannot know the array is packed.
Closes GH-17584.
This test has two classes that use the same trait. In function JIT mode
the same cache slot will be used. This causes problems because it is
primed for the first class and then reused for the second class,
resulting in an incorrect type check failure.
The current check for a megamorphic trait call requires current_frame to
not be NULL, but this is only set in tracing mode and not in function
mode.
This patch corrects the check.
Closes GH-17660.
As explained by Snape3058: On 64-bit machines, we typically have 7 bytes
of padding between the zend_string.val[0] char and the following char[].
This means that zend_string.val[1-7] write to and read from the struct
padding, which is a bad idea.
Allocate the given string separately instead.
Fixes GH-17564
Closes GH-17576
The check for `!fbc || (fbc->common.fn_flags & ZEND_ACC_VARIADIC)` is
performed after `fbc` is set to NULL, so this always returns true.
This results in `ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS` always being
set for unpack sends. Fix it by moving the flag updates to the point
before setting `fbc` to NULL.
Closes GH-17534.
`zend_test_create_throwing_resource` sets the exception in the `test`
call frame and unwinds to `main`. It then throws for the `resource`
variable and verifies that the exception opline is set. However, it
wasn't set in `main`, it was set at the `test` call frame and rethrown later.
The assertion is too conservative, but the end result is right, so drop
the assertion.
Closes GH-17533.
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
If `path_len` is zero, we must not access `path`, let alone try to
subtract `-1` from it.
Since `path` and `path_len` are supposed to come from a `zend_string`,
this is not a security issue.
Closes GH-17471.