php_array_data_shuffle() first compacts the holes of a packed array and
only then updates nNumUsed. When the engine threw in between, the stale
tail slots were still counted, so the moved values were released twice
when the copied array was destroyed. Update nNumUsed right after the
compaction.
Closes GH-24553.
Correct typographical and grammatical mistakes across docs, comments, and build tools. Refactor local identifiers childrens to children in RecursiveFilterIterator and sav to saved_char in sapi_header_add_op.
* zend_API: Verify property types in `object_properties_load()`
Fixesphp/php-src#9708.
* zend_API: Fix various issues in `object_properties_load()`
Fixes Fixesphp/php-src#9707.
Co-authored-by: Tim Düsterhus <tim@tideways-gmbh.com>
* NEWS
* random: Remove now-obsolete manual `$engine` type check in `Randomizer::__unserialize()`
* zend_API: Make `object_properties_load()` use `strict_types=1`
This is consistent with regular unserialization, which also performs strict
type checking.
Co-authored-by: Gina Peter Banyard <girgias@php.net>
* Block creation of readonly reference properties
Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com>
---------
Co-authored-by: Nora Dossche <7771979+ndossche@users.noreply.github.com>
Co-authored-by: Gina Peter Banyard <girgias@php.net>
Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com>
Headers required by the generated code (zend_attributes.h, zend_constants.h, zend_enum.h) are collected during generation and emitted as includes at the top of the arginfo file, with the same preprocessor conditions and PHP version guards as the code that needs them.
Removes the manual zend_attributes.h and zend_enum.h includes from sources that only needed them for the arginfo file they include.
* ext/*: Make `X_from_obj(zend_object *obj)` functions macros
With the introduction of the `ZEND_CONTAINER_OF()` macro we can now preserve
whether or not the `zend_object *` is `const` when extracting the
class-specific struct. This change will allow to use `const zend_object *` in
more locations.
Changes performed with Coccinelle followed by some manual cleanup for comment
and whitespace formatting:
@a@
attribute name zend_always_inline;
type T;
identifier obj;
identifier f;
typedef zend_object;
@@
T* f(zend_object *obj) { return ZEND_CONTAINER_OF(obj, T, std); }
+ #define f(obj) ZEND_CONTAINER_OF(obj, T, std)
@@
identifier a.f;
@@
- f(...) { ... }
@b@
attribute name zend_always_inline;
type T;
identifier obj;
identifier f;
typedef zend_object;
@@
T* f(zend_object *obj) { return ZEND_CONTAINER_OF(obj, T, zo); }
+ #define f(obj) ZEND_CONTAINER_OF(obj, T, zo)
@@
identifier b.f;
@@
- f(...) { ... }
* sockets: Fix build
* odbc: Fix build
* zend_portability: Add `ZEND_CONTAINER_OF()`
* tree-wide: Use `ZEND_CONTAINER_OF()`
Changes made with Coccinelle:
@@
type T_container;
identifier member;
expression e;
@@
- (T_container *)(((char *)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
@@
type T_container;
identifier member;
expression e;
typedef uintptr_t;
@@
- (T_container *)(((uintptr_t)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
@@
type T_container;
identifier member;
expression e;
@@
- (const T_container *)(((char *)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
@@
type T_container;
identifier member;
expression e;
typedef uintptr_t;
@@
- (const T_container *)(((uintptr_t)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
* bcmath: Fix `get_bcmath_number_from_obj()` const-correctness
A follow-up change to the new `ZEND_CONTAINER_OF()` macro will preserve the
`const`-ness of the input pointer. By wrapping this macro inside a macro rather
an an inline function we can preserve the `const`-ness across all layers.
* zend_portability: Keep `const`-ness in `ZEND_CONTAINER_OF()`
* zend_portability: Add C++ version to `ZEND_CONTAINER_OF()`
The constructor rejects a seed that would leave the internal state
all zero, because xoshiro256** with zero state produces 0 on every
call forever. The unserialize callback didn't check the same
invariant. A caller feeding a crafted serialized payload through
__unserialize() ended up with a live engine that returned 0 from
every operation.
Match the constructor: reject the all-zero state from the unserialize
callback too. The Mt19937-aliased __unserialize() wrapper turns the
false return into the standard "Invalid serialization data" exception.
Closes GH-21731
Mt19937::__debugInfo() allocates a temporary HashTable with
array_init(&t), calls the engine's serialize callback, and then
inserts t into the return value. If the callback returns false, the
method throws and hits RETURN_THROWS() before inserting t, so the
HashTable leaks. PcgOneseq128XslRr64 and Xoshiro256StarStar alias
the same method and share the leak.
Niels Dossche fixed the same pattern in __serialize() via GH-20383
(720e006982). That cleanup didn't touch __debugInfo(). Apply the
same reordering here: insert t into return_value first, then let
the callback populate it. RETURN_THROWS() then unwinds the return
value cleanly.
The path is latent in stock PHP because the three built-in serialize
callbacks (mt19937, pcg, xoshiro) all return true, so no user code
reaches the leak today. I'm fixing it for symmetry with GH-20383 and
to keep the pattern from regressing if a future engine grows a
failing serialize path.
Closes GH-21730
Update gen_stubs.php to generate C enums from internal enums, when the stub is annotated with @generate-c-enums. Enum values can be compared to the result of zend_enum_fetch_case_id(zend_object*).
The generated enums are added to separate files named {$extensionName}_decl.h, so that it's possible to include these from anywhere. _arginfo.h files would generate warnings if we tried to include them in a compilation unit that doesn't call the register_{$class} functions, for instance.
Introduce Z_PARAM_ENUM().
* Make ZEND_AST_CONST_ENUM_INIT a 4-children node
* Store enum case id in ZEND_AST_CONST_ENUM_INIT
* Store enum case id in instance
* Expose enum case_id internally
* Generate C enum for internal enums
* Introduce Z_PARAM_ENUM()
* Port extensions
* Reduce code bloat in arginfo by using specialised string releases
Comparing this patch to master (c7da728574),
with a plain configure command without any options:
```
text data bss dec hex filename
20683738 1592400 137712 22413850 156021a sapi/cli/php
20688522 1592400 137712 22418634 15614ca sapi/cli/php_old
```
We see a minor reduction of 0.023% in code size.
* Also use true for the other initialization line
* Also use specialized code for consts
Instead of
* adding a zval on the stack
* initializing it
* copying the value to the attribute
Just initialize the value directly in the zend_attribute_arg
Have each of the specialized methods for registering a constant return a
pointer to the registered constant the same way that the generic
`zend_register_constant()` function does, and use those in the generated
arginfo files to avoid needing to search for a constant that was just
registered in order to add attributes to it.
Only covers constants declared via stub files, others will be handled
separately in a later commit.
Does not include the intl extension, since that had some errors relating to the
cpp code; that extension will be updated separately.