Commit Graph

190 Commits

Author SHA1 Message Date
Dmitry Stogov
c0d49b7c7d Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix memory leak
2022-09-19 13:04:09 +03:00
Dmitry Stogov
8a1f7fa721 Fix memory leak
Fixes oss-fuzz #51451
2022-09-19 13:03:24 +03:00
Bob Weinand
5a0b68bed7 Revert "Store default object handlers alongside the class entry"
This reverts commit 9e6eab3c13.

Reverted along a01dd9feda.
2022-09-14 11:18:14 +02:00
Bob Weinand
9e6eab3c13 Store default object handlers alongside the class entry
Object handlers being separate from class entries is a legacy inherited from PHP 5. Today it has little benefit to keep them separate: in fact, accessing object handlers usually requires not-so-safe hacks.
While it is possible to swap handlers in a custom installed create_object handler, this mostly is tedious, as well as it requires allocating the object handlers struct at runtime, possibly caching it etc..

This allows extensions, which intend to observe other classes to install their own class handlers.
The life cycle of internal classes may now be simply observed by swapping the class handlers in post_startup stage.
The life cycle of userland classes may be observed by iterating over the new classes in zend_compile_file and zend_compile_string and then swapping their handlers.

In general, this would also be a first step in directly tying the object handlers to classes. Especially given that I am not aware of any case where the object handlers would be different between various instances of a given class.

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
2022-08-31 16:45:27 +02:00
Ilija Tovilo
733023b2e3
Improve error message class type
Refer to interfaces/enums instead of classes in more places.

Closes GH-7792
Closes GH-8187
2022-03-20 20:54:36 +01:00
Christoph M. Becker
18f158723b
Merge branch 'PHP-8.1'
* PHP-8.1:
  Fix GH-7958: Nested CallbackFilterIterator is leaking memory
2022-02-21 12:39:59 +01:00
Christoph M. Becker
fb70460d8e
Fix GH-7958: Nested CallbackFilterIterator is leaking memory
We implement `zend_object_iterator_funcs.get_gc` for user iterators to
avoid the memory leak.

Closes GH-8107.
2022-02-21 12:39:07 +01:00
Tyson Andre
024d5f4b63 Cache method overrides of ArrayAccess in zend_class_entry
Previously, code such as subclasses of SplFixedArray would check for method
overrides when instantiating the objects.

This optimization was mentioned as a followup to GH-6552
2021-12-04 11:35:38 -05:00
Nikita Popov
d5b97362bb Always initialize iterator_funcs_ptr
The behavior here depending on the order in which the class entry
was initialized: If get_iterator was set first and Iterator or
IteratorAggregate implemented later, we would not initialize
iterator_funcs_ptr. If Iterator/IteratorAggregate were implemented
first, we would initialize it. After the migration to stub-based
class declarations, we always follow the latter order, but 3rd-party
extension may not. To ensure that behavior is order-independent,
always initialize iterator_funcs_ptr, as we have code (at least the
MultipleIterator implementation) that depends on it being
initialized for iterators with custom get_iterator as well.
2021-11-04 10:46:43 +01:00
Nikita Popov
15bbf6f337 Automatically determine whether to reuse get_iterator()
Same as with the IteratorAggregate case, allow reusing get_iterator
if none of the Iterator methods are overridden. Drop the
REUSE_GET_ITERATOR flag that previously allowed ArrayIterator to
opt-in to unconditional get_iterator reuse, and drop the override
handling it did, in favor of the automated approach.
2021-09-24 15:11:26 +02:00
Nikita Popov
d0dbf7296b Initialize iterator_funcs_ptr upfront
Same as we do for the IteratorAggregate case, initialize the
Iterator methods upfront. This is preparation for an upcoming
change to automatically determine whether get_iterator can be
reused in a child class, in the same way we already do for
IteratorAggregate.
2021-09-24 14:57:13 +02:00
Jeremy Mikola
858d0c0916 Include class name in Serializable deprecation message
The deprecation message was originally introduced in 3e6b447 (#6494).

I first encountered this notice when testing the MongoDB extension
with PHP 8.1, which produced many duplicate messages that provided
no detail about the particular class that needed to be fixed.

Closes GH-7346.
2021-08-11 10:35:47 +02:00
Nikita Popov
6d505d4445 Add RETURN/RETVAL_COPY_DEREF() macros
These were missing from the set...

I think quite a few of these usages don't actually need the DEREF,
but I've just kept things as is for now.
2021-07-22 09:44:19 +02:00
Joe Watkins
322864b569
Drop serial denier functions 2021-07-20 13:11:11 +02:00
Nikita Popov
3e6b447979 Partially deprecate Serializable
If Serializable is implemented, require that __serialize() and
__unserialize() are implemented as well, else issue a deprecation
warning.

Also deprecate use of PDO::FETCH_SERIALIZE.

RFC: https://wiki.php.net/rfc/phase_out_serializable

Closes GH-6494.
2021-04-28 16:55:14 +02:00
Nikita Popov
7af3a392f1 Merge branch 'PHP-8.0'
* PHP-8.0:
  Handle ref return from Iterator::key()
2021-04-15 13:06:04 +02:00
Nikita Popov
46f9fed0d8 Handle ref return from Iterator::key()
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.
2021-04-15 13:05:48 +02:00
Máté Kocsis
6ce70447ac
Generate zend class entries based on stubs
Closes GH-6685
2021-02-14 23:18:28 +01:00
Nikita Popov
3e01f5afb1 Replace zend_bool uses with bool
We're starting to see a mix between uses of zend_bool and bool.
Replace all usages with the standard bool type everywhere.

Of course, zend_bool is retained as an alias.
2021-01-15 12:33:06 +01:00
Nikita Popov
3642592a12 Remove unnecessary check
We should only produce IS_UNDEF if an exception is thrown, this
check is not needed.
2020-09-21 14:56:14 +02:00
George Peter Banyard
fa8d9b1183 Improve type declarations for Zend APIs
Voidification of Zend API which always succeeded
Use bool argument types instead of int for boolean arguments
Use bool return type for functions which return true/false (1/0)
Use zend_result return type for functions which return SUCCESS/FAILURE as they don't follow normal boolean semantics

Closes GH-6002
2020-08-28 15:41:27 +02:00
Nikita Popov
55798e0e39 Lowercase method name in zend_call_method() 2020-08-26 15:19:23 +02:00
Nikita Popov
d92229d8c7 Implement named parameters
From an engine perspective, named parameters mainly add three
concepts:

 * The SEND_* opcodes now accept a CONST op2, which is the
   argument name. For now, it is looked up by linear scan and
   runtime cached.
 * This may leave UNDEF arguments on the stack. To avoid having
   to deal with them in other places, a CHECK_UNDEF_ARGS opcode
   is used to either replace them with defaults, or error.
 * For variadic functions, EX(extra_named_params) are collected
   and need to be freed based on ZEND_CALL_HAS_EXTRA_NAMED_PARAMS.

RFC: https://wiki.php.net/rfc/named_params

Closes GH-5357.
2020-07-31 15:53:36 +02:00
Nikita Popov
70501b81a7 Fixed bug #79852 2020-07-14 12:31:06 +02:00
Nikita Popov
312201dce4 Add get_gc handle for object iterators
Optional handler with the same semantics as the object handler.
2020-07-01 15:17:22 +02:00
Nikita Popov
1314ccbf8c Cache __unserialize() instead of unserialize()
We should use these cache slots for the new object serialization
mechanism rather than the old one.
2020-06-26 10:54:40 +02:00
Nikita Popov
f37138d2c5 Don't use iterator_funcs_ptr if it is null
This avoids ubsan warnings. Alternatively we could always initialize
iterator_funcs_ptr for aggregates, instead of doing so only for
non-internal ones.
2020-06-25 10:30:40 +02:00
Nikita Popov
ff19ec2df3 Introduce InternalIterator
Userland classes that implement Traversable must do so either
through Iterator or IteratorAggregate. The same requirement does
not exist for internal classes: They can implement the internal
get_iterator mechanism, without exposing either the Iterator or
IteratorAggregate APIs. This makes them usable in get_iterator(),
but incompatible with any Iterator based APIs.

A lot of internal classes do this, because exposing the userland
APIs is simply a lot of work. This patch alleviates this issue by
providing a generic InternalIterator class, which acts as an
adapater between get_iterator and Iterator, and can be easily
used by many internal classes. At the same time, we extend the
requirement that Traversable implies Iterator or IteratorAggregate
to internal classes as well.

Closes GH-5216.
2020-06-24 15:31:41 +02:00
Nikita Popov
15846ff115 Add ZVAL_OBJ_COPY macro
For the common ZVAL_OBJ + GC_ADDREF pattern.
This mirrors the existing ZVAL_STR_COPY API.
2020-06-17 16:36:56 +02:00
Nikita Popov
c23edd2acf Remove called_scope inheritance in zend_call_method()
Similar to 097043db2a, but for the
zend_call_method() API. I don't think we ever use this for
static methods, but this logic shouldn't be there. If you want
to inherit the active LSB scope for some reason, do so explicitly.
2020-06-10 10:04:37 +02:00
Nikita Popov
257dbb0450 Add zend_call_known_function() API family
This adds the following APIs:

void zend_call_known_function(
    zend_function *fn, zend_object *object, zend_class_entry *called_scope,
    zval *retval_ptr, int param_count, zval *params);

void zend_call_known_instance_method(
    zend_function *fn, zend_object *object, zval *retval_ptr, int param_count, zval *params);
void zend_call_known_instance_method_with_0_params(
    zend_function *fn, zend_object *object, zval *retval_ptr);
void zend_call_known_instance_method_with_1_params(
    zend_function *fn, zend_object *object, zval *retval_ptr, zval *param);
void zend_call_known_instance_method_with_2_params(
    zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2);

These are used to perform a call if you already have the
zend_function you want to call. zend_call_known_function()
is the base API, the rest are just really thin wrappers around
it for the common case of instance method calls.

Closes GH-5692.
2020-06-09 16:21:54 +02:00
Nikita Popov
be540b35d2 Remove some special-casing in zend_call_method()
Don't treat the !fn_proxy && !obj_ce case differently. There doesn't
seem to be any need for it, and it will result in subtly different
behavior (e.g. it will accept "Foo::bar" syntax, but break as soon
as you pass in an fn_proxy cache).
2020-06-09 10:10:58 +02:00
Máté Kocsis
33c3691c33
Generate method entries from stubs for Zend classes
Closes GH-5459
2020-04-26 11:13:14 +02:00
Nikita Popov
e9ae581f02 Fixed bug #62609: Allow implementing Traversable in abstract class
Master only, as this depends on fixes to calling order of
interface implementation handlers.
2020-03-06 11:12:43 +01:00
Nikita Popov
c05a9c3dcd Implement interfaces after all methods available
The place where interface implementation handlers is called is
currently ill-defined: If the class implements interfaces itself,
the handlers for both the parent interfaces and the new interfaces
will be called after all methods are registered (post trait use).
If the class does not implement interfaces, then the parent
interface handlers are called early during inheritance (before
methods are inherited).

This commit moves the calls to always occur after all methods are
available. For userland classes this will be post trait import,
at the time where interfaces get implemented (whether the class
itself defines additional interfaces or not). For internal classes
it will be at the end of inheritance, as internal class declarations
do not have proper finalization.

This allows us to simplify the logic for implementing the magic
Iterator / IteratorAggregate interfaces. In particularly we can
now also automatically detect whether an extension of
IteratorAggregate can safely reuse a custom get_iterator handler,
or whether it needs to switch to the userland mechanism. The
Iterator case continues to rely on ZEND_ACC_REUSE_GET_ITERATOR
for this purpose, as a wholesale replacement is not possible there.
2020-03-04 10:29:21 +01:00
Nikita Popov
f15f3272cf Remove empty "interface gets implemented" handlers 2020-03-03 17:06:38 +01:00
Nicolas Grekas
9e775db025 Define Stringable with __toString():string method 2020-03-02 15:25:32 +01:00
Nikita Popov
6811222422 Eliminate uses of ZVAL_ZVAL and friends
Instead add RETURN_COPY(_VALUE) macros will the expected behavior.

RETURN_ZVAL doesn't make any sense since PHP 7, but has stuck
around, probably because the alternative was to write directly to
the return_value variable.
2020-01-20 10:34:17 +01:00
Nikita Popov
c858d17f06 Optimize instanceof_function
Split out the simple equality check into an inline function --
this is one of the common cases.

Replace instanceof_function_ex with zend_class_implements_interface.
There are a few more places where it may be used.
2019-10-25 10:51:17 +02:00
Christoph M. Becker
273731fb76 Add Zend class/interface arginfo stubs
We also change `Generator::throw()` to expect a `Throwable` in the
first place, and we now throw a TypeError instead of returning `false`
from `Exception::getTraceAsString()`.
2019-10-15 16:21:00 +02:00
Nikita Popov
e4fae9c061 Merge branch 'PHP-7.4' 2019-06-11 13:16:38 +02:00
Nikita Popov
8f8fcbbd39 Support full variance if autoloading is used
Keep track of delayed variance obligations and check them after
linking a class is otherwise finished. Obligations may either be
unresolved method compatibility (because the necessecary classes
aren't available yet) or open parent/interface dependencies. The
latter occur because we allow the use of not fully linked classes
as parents/interfaces now.

An important aspect of the implementation is we do not require
classes involved in variance checks to be fully linked in order for
the class to be fully linked. Because the involved types do have to
exist in the class table (as partially linked classes) and we do
check these for correct variance, we have the guarantee that either
those classes will successfully link lateron or generate an error,
but there is no way to actually use them until that point and as
such no possibility of violating the variance contract. This is
important because it ensures that a class declaration always either
errors or will produce an immediately usable class afterwards --
there are no cases where the finalization of the class declaration
has to be delayed until a later time, as earlier variants of this
patch did.

Because variance checks deal with classes in various stages of
linking, we need to use a special instanceof implementation that
supports this, and also introduce finer-grained flags that tell us
which parts have been linked already and which haven't.

Class autoloading for variance checks is delayed into a separate
stage after the class is otherwise linked and before delayed
variance obligations are processed. This separation is needed to
handle cases like A extends B extends C, where B is the autoload
root, but C is required to check variance. This could end up
loading C while the class structure of B is in an inconsistent
state.
2019-06-11 13:09:33 +02:00
Dmitry Stogov
b2cdde0826 Merge branch 'PHP-7.4'
* PHP-7.4:
  Replace ZVAL_COPY() and ZVAL_COPY_VALUE() for IS_OBJECT by cheaper macros
2019-05-28 20:19:15 +03:00
Dmitry Stogov
83804519df Replace ZVAL_COPY() and ZVAL_COPY_VALUE() for IS_OBJECT by cheaper macros 2019-05-28 20:10:02 +03:00
Nikita Popov
c3ee12e786 Merge branch 'PHP-7.4' 2019-05-23 10:41:27 +02:00
Nikita Popov
64918c7702 Forbid use of not fully linked classes 2019-05-23 10:41:10 +02:00
Nikita Popov
e517cffd92 Merge branch 'PHP-7.4' 2019-02-18 13:58:40 +01:00
Dmitry Stogov
c9ffae1bec Fixed bug #77633
Add a new class flag to inherit get_iterator() when implementing
the Iterator/IteratorAggregate interfaces and use it for
ArrayIterator.
2019-02-18 13:47:44 +01:00
Dmitry Stogov
91ef4124e5 Refactor zend_object_handlers API to pass zend_object* and zend_string* insted of zval(s). 2019-02-04 13:20:25 +03:00
Peter Kokot
92ac598aab Remove local variables
This patch removes the so called local variables defined per
file basis for certain editors to properly show tab width, and
similar settings. These are mainly used by Vim and Emacs editors
yet with recent changes the once working definitions don't work
anymore in Vim without custom plugins or additional configuration.
Neither are these settings synced across the PHP code base.

A simpler and better approach is EditorConfig and fixing code
using some code style fixing tools in the future instead.

This patch also removes the so called modelines for Vim. Modelines
allow Vim editor specifically to set some editor configuration such as
syntax highlighting, indentation style and tab width to be set in the
first line or the last 5 lines per file basis. Since the php test
files have syntax highlighting already set in most editors properly and
EditorConfig takes care of the indentation settings, this patch removes
these as well for the Vim 6.0 and newer versions.

With the removal of local variables for certain editors such as
Emacs and Vim, the footer is also probably not needed anymore when
creating extensions using ext_skel.php script.

Additionally, Vim modelines for setting php syntax and some editor
settings has been removed from some *.phpt files.  All these are
mostly not relevant for phpt files neither work properly in the
middle of the file.
2019-02-03 21:03:00 +01:00