Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle engine limitations for var_export/debug_zval_dump/json_encode where containers hold objects/arrays #147

Open
TysonAndre opened this issue Feb 15, 2022 · 1 comment

Comments

@TysonAndre
Copy link
Owner

var_export is designed to export the object's properties, it doesn't decrease the refcount of the table when it's done.

An alternate approach is tracking if any changes were made to avoid assertion errors, with a bit flag/boolean.

Problems:

  • Extra memory usage
  • Extra overhead for operations - this needs to track modifications just in case debugging functions are called, to avoid debug notices
  • __destruct and freeing is delayed until Collection is freed or var_export/debug_zval_dump is called again.

Solution:

  • Create an empty hash table for infinite recursion detection like regular objects (for json_encode)
  • Only override ZEND_PROP_PURPOSE_ARRAY_CAST and ZEND_PROP_PURPOSE_SERIALIZE and ZEND_PROP_PURPOSE_JSON in get_properties_for

  • json_encode requires that the object have a distinct HashTable (zend_std_get_properties) in the result of Z_OBJPROP_P, but will call jsonSerialize for the actual data to encode
  • Problematically, var_export/debug_zval_dump do infinite recursion detection on the HashTable itself (ZEND_PROP_PURPOSE_DEBUG/ZEND_PROP_PURPOSE_VAR_EXPORT)
  • var_dump correctly (1) first checks if there's recursion on the object, and (2) frees the hash table after it's done. Unfortunately, though, ZEND_PROP_PURPOSE_DEBUG is used both for var_dump and debug_zval_dump
  • serialize works by adding get_properties_for. It will check if the object was seen before getting properties, obviously.
  • array casts will clone the hash table
@TysonAndre
Copy link
Owner Author

The change for var_export/debug_zval_dump cycle recursion detection was merged in php 8.2. In that version, the properties table doesn't need to be reused, so a temporary array can be returned to conserve memory and to keep object lifetimes (of elements in the container) short even if var_export is called

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant