The FFI call return values follow widening rules.
We must widen to `ffi_arg` in the case we're handling a return value for types shorter than the machine width.
From http://www.chiark.greenend.org.uk/doc/libffi-dev/html/The-Closure-API.html:
> In most cases, ret points to an object of exactly the size of the type specified when cif was constructed.
> However, integral types narrower than the system register size are widened.
> In these cases your program may assume that ret points to an ffi_arg object.
If we don't do this, we get wrong values when reading the return values.
Closes GH-17255.
Co-authored-by: Dmitry Stogov <dmitry@zend.com>
The directives for FFI should be first in the file, which is fine,
however sometimes there can be comments or whitespace before or between
these defines. One practical example is for license information or when
a user adds newlines "by accident". In these cases, it's quite confusing
that the directives do not work properly.
To solve this, make the zend_ffi_parse_directives() aware of comments.
Closes GH-17082.
For top-level anonymous type definition we never store the declaration anywhere
else nor the type anywhere else.
The declaration keeps owning the type and it goes out of scope.
For anonymous fields this gets handled by the add_anonymous_field code that
removes the type from the declaration.
This patch does something similar in the parsing code when it is
detected we're dealing with an anonymous enum in a top-level declaration.
Closes GH-14839.
is_zend_ptr() expected zend_mm_heap.huge_list to be circular, but it's in fact NULL-terminated. It could crash when at least one huge block exists and the ptr did not belong to any block.
Some modules may reset _fmode, which causes mangling of line endings.
Always be explicit like we do in other places where the native open call
is used.
Closes GH-14218.
Because these functions are copied and not properly registered (which we
can't), the observer code doesn't add the temporaries on startup.
Add them via a callback during startup.
Closes GH-12906.
Previously, FFI_G(symbols) and FFI_G(tags) were never cleaned up when calling
new on an existing object. However, if cdef() is called without parameters these
globals are NULL and might be created when new() creates new definitions. These
would then be discarded without freeing them.
Closes GH-11751
(And any PECLs returning `zend_empty_array` in the handler->get_properties
overrides)
Closes GH-9697
This is similar to the fix used in d9651a9419
for array_walk.
This should make it safer for php-src (and PECLs, long-term) to return
the empty immutable array in `handler->get_properties` to avoid wasting memory.
See https://github.com/php/php-src/issues/9697#issuecomment-1273613175
The only possible internal iterator position for the empty array is at the end
of the empty array (nInternalPointer=0).
The `zend_hash*del*` helpers will always set nInternalPointer to 0 when an
array becomes empty,
regardless of previous insertions/deletions/updates to the array.
When a uint8_t is bitshifted to the left, it is actually promoted to an
int. For the current code this has the effect of a wrong sign-extension,
and the result will also wrongly become zero when insert_pos >= 32.
Fix this by adding an explicit cast.
Furthermore, the partial prefix byte mask was computed incorrectly: the
byte is already shifted so the mask should not account for the shift.