We don't need to duplicate these strings from the resource, we can just
use them with an offset.
To prove this was safe, I had to make the arguments const and then
propagate that everywhere, so this patch also introduces some more
constness.
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.
These were introduced in 6747068c, but they don't seem to be in upstream
(anymore). For the entry in rpm it may have even been a mixup with the
two sections in the rpm file: there's a "10 string" entry but only in
the delta part.
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.
The `$module_name` of `com::__construct()` can be a ProgID, ClassID or
moniker. We first try `CLSIDFromString()`, and if that fails, we go
ahead and try to treat the `$module_name` as a moniker. If that also
fails, we throw an exception with the result of `MkParseDisplayName()`
what would just be `MK_E_SYNTAX` if given a ProgID. This result is
highly confusing for the common case where a ProgID is given, which is
not registered (e.g. due to a typo). In this case, we use the original
`HRESULT` (`CO_E_CLASSSTRING`) instead.
The 32bit implementation seems to be okay, but we rather should avoid
falling back to the double (pun intended) calculation for non `__GNUC__`
systems. We use the intsafe.h intrinsics instead for MSVC and
compatible compilers.
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.
- Removed unused variable from getHeaders function.
- Simplified regex by removing unnecessary lazy quantifiers ().
- Removed unnecessary flag from regex patterns.
This improves readability and reduces redundant code without altering functionality.
When the `zend_class_entry` has a `zend_function` entry for `clone`, the logic
is the same regardless of if the `reflection_object` entry has an object or
not; the determination is based solely on the flags of the `zend_function`.
Second pass through `Zend/tests/bug*` to organize the tests.
Move tests to existing sub directories, and create some new sub directories:
* `ArrayAccess`
* `autoload`
* `clone`
* `serialize` (also covers `unserialize()`)
* `switch`
Work towards GH-15631