Bug #76502 [NEW]: Chain of mixed exceptions and errors does not serialize properly

From: Date: Wed, 20 Jun 2018 07:52:16 +0000
Subject: Bug #76502 [NEW]: Chain of mixed exceptions and errors does not serialize properly
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-215803@lists.php.net to get a copy of this message
From: benjamin dot zikarsky at jaumo dot com Operating system: Linux 4.16 PHP version: 7.2.6 Package: *General Issues Bug Type: Bug Bug description:Chain of mixed exceptions and errors does not serialize properly Description: ------------ In some error-cases we try to send serialized exceptions from our background worker infrastructure to our webservers, where those get deserialized and rethrown. This usually works fine but recently we came around strange, cut-off exception-chains. When we debugged the problem, we realized that if an Error gets thrown, and later is wrapped into an Exception, this Error is lost in the serialization/deserialization process. Further analysis showed that while the error/exception chain gets serialized properly, the __wakeup implementation replaces Error-objects in Exception-objects with NULL and vice-versa. See: https://github.com/php/php-src/blob/d04917c7b361fd07e098fe29ae931fb6fac1d9e0/Zend/zend_exceptions.c#L327-L331 https://github.com/php/php-src/blob/d04917c7b361fd07e098fe29ae931fb6fac1d9e0/Zend/zend_exceptions.c#L63-L66 While an Error wrapping an Exception may be uncommon, the Error wrapped in an Exception is a common pattern in our codebase. With $previous being defined as Throwable, the problem is unexpected. Proposition: Replace `instanceof_function(Z_OBJCE_P(pvalue), i_get_exception_base(object)` with instanceof_function(Z_OBJCE_P(pvalue), THROWABLE. my understanding of php-src is not good enough to fix this, but THROWABLE should be replaced with a reference to the Throwable interface. Test script: --------------- <?php $examples = [ "Exception(Exception())" => new Exception("outer", 0, new Exception("inner")), "Error(Error())" => new Error("outer", 0, new Error("inner")), "Error(Exception())" => new Error("outer", 0, new Exception("inner")), "Exception(Error())" => new Exception("outer", 0, new Error("inner")) ]; foreach ($examples as $name => $example) { $processed = unserialize(serialize($example)); $processedPrev = $processed->getPrevious(); echo "---- $name ----\n"; echo "before: ", get_class($example), ".previous == ", get_class($example->getPrevious()), "\n"; echo "after : ", get_class($processed), ".previous == ", $processedPrev ? get_class($processedPrev) : "null", "\n"; } Expected result: ---------------- ---- Exception(Exception()) ---- before: Exception.previous == Exception after : Exception.previous == Exception ---- Error(Error()) ---- before: Error.previous == Error after : Error.previous == Error ---- Error(Exception()) ---- before: Error.previous == Exception after : Error.previous == Error ---- Exception(Error()) ---- before: Exception.previous == Error after : Exception.previous == Exception Actual result: -------------- ---- Exception(Exception()) ---- before: Exception.previous == Exception after : Exception.previous == Exception ---- Error(Error()) ---- before: Error.previous == Error after : Error.previous == Error ---- Error(Exception()) ---- before: Error.previous == Exception after : Error.previous == null ---- Exception(Error()) ---- before: Exception.previous == Error after : Exception.previous == null -- Edit bug report at https://bugs.php.net/bug.php?id=76502&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=76502&r=trysnapshot54 Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=76502&r=trysnapshot55 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=76502&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=76502&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=76502&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=76502&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=76502&r=needscript Try newer version: https://bugs.php.net/fix.php?id=76502&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=76502&r=support Expected behavior: https://bugs.php.net/fix.php?id=76502&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=76502&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=76502&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=76502&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=76502&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=76502&r=dst IIS Stability: https://bugs.php.net/fix.php?id=76502&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=76502&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=76502&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=76502&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=76502&r=mysqlcfg

« previous php.bugs (#215803) next »