return 0;
}
- /* use bitwise OR to make only one conditional jump */
- if (UNEXPECTED(GC_IS_RECURSIVE(ht1) | GC_IS_RECURSIVE(ht2))) {
+ /* It's enough to protect only one of the arrays.
+ * The second one may be referenced from the first and this may cause
+ * false recursion detection.
+ */
+ if (UNEXPECTED(GC_IS_RECURSIVE(ht1))) {
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
}
if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) {
GC_PROTECT_RECURSION(ht1);
}
- if (!(GC_FLAGS(ht2) & GC_IMMUTABLE)) {
- GC_PROTECT_RECURSION(ht2);
- }
result = zend_hash_compare_impl(ht1, ht2, compar, ordered);
if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(ht1);
}
- if (!(GC_FLAGS(ht2) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(ht2);
- }
return result;
}
p2 = zobj2->properties_table;
end = p1 + zobj1->ce->default_properties_count;
+ /* It's enough to protect only one of the objects.
+ * The second one may be referenced from the first and this may cause
+ * false recursion detection.
+ */
/* use bitwise OR to make only one conditional jump */
- if (UNEXPECTED(Z_IS_RECURSIVE_P(o1) | Z_IS_RECURSIVE_P(o2))) {
+ if (UNEXPECTED(Z_IS_RECURSIVE_P(o1))) {
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
}
Z_PROTECT_RECURSION_P(o1);
- Z_PROTECT_RECURSION_P(o2);
do {
if (Z_TYPE_P(p1) != IS_UNDEF) {
if (Z_TYPE_P(p2) != IS_UNDEF) {
if (compare_function(&result, p1, p2)==FAILURE) {
Z_UNPROTECT_RECURSION_P(o1);
- Z_UNPROTECT_RECURSION_P(o2);
return 1;
}
if (Z_LVAL(result) != 0) {
Z_UNPROTECT_RECURSION_P(o1);
- Z_UNPROTECT_RECURSION_P(o2);
return Z_LVAL(result);
}
} else {
Z_UNPROTECT_RECURSION_P(o1);
- Z_UNPROTECT_RECURSION_P(o2);
return 1;
}
} else {
if (Z_TYPE_P(p2) != IS_UNDEF) {
Z_UNPROTECT_RECURSION_P(o1);
- Z_UNPROTECT_RECURSION_P(o2);
return 1;
}
}
p2++;
} while (p1 != end);
Z_UNPROTECT_RECURSION_P(o1);
- Z_UNPROTECT_RECURSION_P(o2);
return 0;
} else {
if (!zobj1->properties) {