Skip to content

Commit

Permalink
Perform preloading attempt on copied class
Browse files Browse the repository at this point in the history
It is very hard to determine in advance whether class linking will
fail due to missing dependencies in variance checks (#7314 attempts
this). This patch takes an alternative approach where we try to
perform inheritance on a copy of the class (zend_lazy_class_load)
and then restore the original class if inheritance fails. The fatal
error in that case is recorded and thrown as a warning later.

Closes GH-7319.
  • Loading branch information
nikic committed Jul 30, 2021
1 parent 6b1337b commit d836046
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 168 deletions.
10 changes: 6 additions & 4 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static zend_class_entry *lookup_class_ex(
ce = zend_lookup_class_ex(
name, NULL, ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);

if (!CG(in_compilation)) {
if (!CG(in_compilation) || (CG(compiler_options) & ZEND_COMPILE_PRELOAD)) {
if (ce) {
return ce;
}
Expand Down Expand Up @@ -2593,7 +2593,6 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
ce->ce_flags &= ~ZEND_ACC_IMMUTABLE;
ce->refcount = 1;
ce->inheritance_cache = NULL;
ZEND_MAP_PTR_INIT(ce->mutable_data, NULL);

/* properties */
if (ce->default_properties_table) {
Expand Down Expand Up @@ -2817,6 +2816,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
}
#endif

bool orig_record_errors = EG(record_errors);
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
if (is_cacheable) {
if (zend_inheritance_cache_get && zend_inheritance_cache_add) {
Expand Down Expand Up @@ -2902,7 +2902,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
}

zend_build_properties_info_table(ce);
EG(record_errors) = false;
EG(record_errors) = orig_record_errors;

if (!(ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE)) {
ce->ce_flags |= ZEND_ACC_LINKED;
Expand Down Expand Up @@ -2948,7 +2948,9 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
}
}

zend_free_recorded_errors();
if (!orig_record_errors) {
zend_free_recorded_errors();
}
if (traits_and_interfaces) {
free_alloca(traits_and_interfaces, use_heap);
}
Expand Down

0 comments on commit d836046

Please sign in to comment.