Skip to content

Commit d836046

Browse files
committedJul 30, 2021
Perform preloading attempt on copied class
It is very hard to determine in advance whether class linking will fail due to missing dependencies in variance checks (php#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 phpGH-7319.
1 parent 6b1337b commit d836046

File tree

5 files changed

+116
-168
lines changed

5 files changed

+116
-168
lines changed
 

‎Zend/zend_inheritance.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ static zend_class_entry *lookup_class_ex(
248248
ce = zend_lookup_class_ex(
249249
name, NULL, ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
250250

251-
if (!CG(in_compilation)) {
251+
if (!CG(in_compilation) || (CG(compiler_options) & ZEND_COMPILE_PRELOAD)) {
252252
if (ce) {
253253
return ce;
254254
}
@@ -2593,7 +2593,6 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
25932593
ce->ce_flags &= ~ZEND_ACC_IMMUTABLE;
25942594
ce->refcount = 1;
25952595
ce->inheritance_cache = NULL;
2596-
ZEND_MAP_PTR_INIT(ce->mutable_data, NULL);
25972596

25982597
/* properties */
25992598
if (ce->default_properties_table) {
@@ -2817,6 +2816,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
28172816
}
28182817
#endif
28192818

2819+
bool orig_record_errors = EG(record_errors);
28202820
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
28212821
if (is_cacheable) {
28222822
if (zend_inheritance_cache_get && zend_inheritance_cache_add) {
@@ -2902,7 +2902,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
29022902
}
29032903

29042904
zend_build_properties_info_table(ce);
2905-
EG(record_errors) = false;
2905+
EG(record_errors) = orig_record_errors;
29062906

29072907
if (!(ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE)) {
29082908
ce->ce_flags |= ZEND_ACC_LINKED;
@@ -2948,7 +2948,9 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
29482948
}
29492949
}
29502950

2951-
zend_free_recorded_errors();
2951+
if (!orig_record_errors) {
2952+
zend_free_recorded_errors();
2953+
}
29522954
if (traits_and_interfaces) {
29532955
free_alloca(traits_and_interfaces, use_heap);
29542956
}

0 commit comments

Comments
 (0)
Please sign in to comment.