Skip to content

Fix GH-24743: var_export() ignores exception from lazy object init - #24746

Open
lazerg wants to merge 1 commit into
php:PHP-8.4from
lazerg:fix/gh-24743-var-export-exception
Open

lazerg wants to merge 1 commit into
php:PHP-8.4from
lazerg:fix/gh-24743-var-export-exception

Conversation

@lazerg

@lazerg lazerg commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

var_export() printed partial output when a lazy object's initializer threw. The exception comes from zend_get_properties_for(), and php_var_export_ex() kept exporting after it. Now it releases the recursion guard and the properties and returns FAILURE.

The nested-object part (a property hook throwing inside a nested object) is already fixed on PHP-8.4 by afe5635. gh24743_1.phpt keeps that case covered, and gh24743_2.phpt covers the lazy object case.

Fixes #24743

@Sjord

Sjord commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Thanks. Looks good to me.

@iliaal iliaal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase onto the current PHP-8.4 branch to resolve the merge conflict in ext/standard/var.c. The nested-export failure handling already landed in afe5635, including UNEXPECTED(result == FAILURE). Retain that check when resolving the overlap; the lazy-initialization exception check and regression tests remain useful.

Comment thread ext/standard/var.c Outdated
}
ZEND_GUARD_OR_GC_PROTECT_RECURSION(guard, EXPORT, zobj);
myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_VAR_EXPORT);
if (EG(exception)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using if (UNEXPECTED(EG(exception))) here to mark the exceptional exit. This is an optional branch-prediction hint; no performance improvement has been measured.

Comment thread ext/standard/var.c Outdated
if (val == &tmp) {
zval_ptr_dtor(val);
}
if (result == FAILURE) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using if (UNEXPECTED(result == FAILURE)) for this exceptional exit. Current PHP-8.4 already contains this failure handling with that wrapper, so please retain the upstream version when resolving the rebase conflict.

@lazerg
lazerg force-pushed the fix/gh-24743-var-export-exception branch from 8ebc153 to 41ff2db Compare October 27, 2026 12:28
@lazerg lazerg changed the title Fix GH-24743: var_export() ignores exception from nested object export Fix GH-24743: var_export() ignores exception from lazy object init Oct 27, 2026
@lazerg

lazerg commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto PHP-8.4 in 41ff2db. I kept the upstream failure check and added UNEXPECTED() to the lazy init check. I also dropped the NEWS change. Both tests are still there: gh24743_1 covers the hook case from the issue, and gh24743_2 fails without the lazy init check.

@iliaal iliaal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants