PATH:
opt
/
alt
/
tests
/
alt-php83-pecl-igbinary_3.2.15-1.el8
/
tests
--TEST-- issue when serializing/deserializing nested objects with __serialize --SKIPIF-- <?php if (PHP_VERSION_ID < 70100) { echo "skip uses php 7.1 syntax\n"; } ?> --FILE-- <?php // Based on bug report seen in a Symfony codebase - https://github.com/igbinary/igbinary/issues/287 // NOTE: This test would also pass in older php versions, where igbinary doesn't call __serialize, // just because we're returning the same data we fetch. // (However, the serialized data generated before/after 7.4 would be incompatible if saved to memcache, etc.) class Event { } class MessageEvents { private $events = []; private $transports = []; public function add(MessageEvent $event): void { $this->events[] = $event; $this->transports[$event->getTransport()] = true; } public function getEvents(string $name = null): array { return $this->events; } } final class MessageEvent extends Event { private $propagationStopped = false; private $message; private $envelope; private $transport; private $queued; public function __construct(RawMessage $message, Envelope $envelope, string $transport, bool $queued = false) { $this->message = $message; $this->envelope = $envelope; $this->transport = $transport; $this->queued = $queued; } public function getTransport(): string { return $this->transport; } public function getMessage(): RawMessage { return $this->message; } } class Envelope { protected $sender; protected $recipients = []; protected $senderSet = false; protected $recipientsSet = false; protected $message; public function __construct(Address $sender, array $recipients) { $this->setSender($sender); $this->setRecipients($recipients); } public static function create(RawMessage $message): self { return new DelayedEnvelope($message); } public function setSender(Address $sender): void { $this->sender = $sender; } public function setRecipients(array $recipients): void { $this->recipients = []; foreach ($recipients as $recipient) { $this->recipients[] = new Address($recipient->getAddress()); } } public function getRecipients(): array { return $this->recipients; } } final class DelayedEnvelope extends Envelope { public function __construct(Message $message) { $this->message = $message; } public function setSender(Address $sender): void { parent::setSender($sender); $this->senderSet = true; } public function setRecipients(array $recipients): void { parent::setRecipients($recipients); $this->recipientsSet = parent::getRecipients(); } } final class Address { private $address; private $name; public function __construct(string $address, string $name = '') { $this->address = trim($address); $this->name = trim(str_replace(["\n", "\r"], '', $name)); } /** * @param Address|string $address */ public static function create($address): self { if ($address instanceof self) { return $address; } if (\is_string($address)) { if (false === strpos($address, '<')) { return new self($address); } return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"')); } throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s" given).', get_debug_type($address))); } public static function createArray(array $addresses): array { $addrs = []; foreach ($addresses as $address) { $addrs[] = self::create($address); } return $addrs; } } abstract class AbstractHeader { private static $encoder; private $name; private $lineLength = 76; private $lang; private $charset = 'utf-8'; protected $addresses = []; public function __construct(string $name) { $this->name = $name; } public function getName() { return $this->name; } } final class Headers { private $headers = []; private $lineLength = 76; public function __construct(...$headers) { foreach ($headers as $header) { $this->add($header); } } public function __clone() { foreach ($this->headers as $name => $collection) { foreach ($collection as $i => $header) { $this->headers[$name][$i] = clone $header; } } } public function addMailboxListHeader(string $name, array $addresses): self { return $this->add(new MailboxListHeader($name, Address::createArray($addresses))); } public function add($header): self { self::checkHeaderClass($header); $name = strtolower($header->getName()); $this->headers[$name][] = $header; return $this; } public function get(string $name) { $name = strtolower($name); if (!isset($this->headers[$name])) { return null; } $values = array_values($this->headers[$name]); return array_shift($values); } public function all(string $name = null): iterable { if (null === $name) { foreach ($this->headers as $name => $collection) { foreach ($collection as $header) { yield $name => $header; } } } elseif (isset($this->headers[strtolower($name)])) { foreach ($this->headers[strtolower($name)] as $header) { yield $header; } } } public static function checkHeaderClass($header): void { $name = strtolower($header->getName()); } } final class MailboxListHeader extends AbstractHeader { public function __construct(string $name, array $addresses) { parent::__construct($name); $this->addAddresses($addresses); } public function addAddresses(array $addresses) { foreach ($addresses as $address) { $this->addAddress($address); } } /** * @throws RfcComplianceException */ public function addAddress(Address $address) { $this->addresses[] = $address; } } class RawMessage { protected $message; protected $headers; protected $body; protected $text; protected $textCharset; protected $html; protected $htmlCharset; protected $attachments = []; public function __construct($message) { $this->message = $message; } public function __serialize(): array { return [$this->message]; } public function __unserialize(array $data): void { [$this->message] = $data; } } class Message extends RawMessage { public function __construct(Headers $headers = null, AbstractPart $body = null) { $this->headers = $headers ? clone $headers : new Headers(); $this->body = $body; } public function __clone() { $this->headers = clone $this->headers; if (null !== $this->body) { $this->body = clone $this->body; } } public function getHeaders(): Headers { return $this->headers; } public function __serialize(): array { return [$this->headers]; } public function __unserialize(array $data): void { [$this->headers] = $data; } } class Email extends Message { public function to(...$addresses) { return $this->setListAddressHeaderBody('To', $addresses); } private function setListAddressHeaderBody(string $name, array $addresses) { $addresses = Address::createArray($addresses); $headers = $this->getHeaders(); $headers->addMailboxListHeader($name, $addresses); return $this; } /** * @internal */ public function __serialize(): array { return [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, parent::__serialize()]; } /** * @internal */ public function __unserialize(array $data): void { [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, $parentData] = $data; parent::__unserialize($parentData); } } $messageEvents = new MessageEvents(); $messageEvents->add(new MessageEvent($message1 = (new Email())->to('alice@example.com'), Envelope::create($message1), 'null://null')); $messageEvents->add(new MessageEvent($message2 = (new Email())->to('bob@example.com'), Envelope::create($message2), 'null://null')); var_dump($messageEvents); // Comment/uncomment to trigger the bug var_dump('headers_before', $messageEvents->getEvents()[0]->getMessage()->getHeaders() === $messageEvents->getEvents()[1]->getMessage()->getHeaders()); $ser = igbinary_serialize($messageEvents); $messageEvents = igbinary_unserialize($ser); // should dump "false", but dumps "true" the "var_dump($messageEvents)" is not commented var_dump('headers_after', $messageEvents->getEvents()[0]->getMessage()->getHeaders() === $messageEvents->getEvents()[1]->getMessage()->getHeaders()); ?> --EXPECT-- object(MessageEvents)#1 (2) { ["events":"MessageEvents":private]=> array(2) { [0]=> object(MessageEvent)#2 (5) { ["propagationStopped":"MessageEvent":private]=> bool(false) ["message":"MessageEvent":private]=> object(Email)#3 (8) { ["message":protected]=> NULL ["headers":protected]=> object(Headers)#4 (2) { ["headers":"Headers":private]=> array(1) { ["to"]=> array(1) { [0]=> object(MailboxListHeader)#6 (5) { ["name":"AbstractHeader":private]=> string(2) "To" ["lineLength":"AbstractHeader":private]=> int(76) ["lang":"AbstractHeader":private]=> NULL ["charset":"AbstractHeader":private]=> string(5) "utf-8" ["addresses":protected]=> array(1) { [0]=> object(Address)#5 (2) { ["address":"Address":private]=> string(17) "alice@example.com" ["name":"Address":private]=> string(0) "" } } } } } ["lineLength":"Headers":private]=> int(76) } ["body":protected]=> NULL ["text":protected]=> NULL ["textCharset":protected]=> NULL ["html":protected]=> NULL ["htmlCharset":protected]=> NULL ["attachments":protected]=> array(0) { } } ["envelope":"MessageEvent":private]=> object(DelayedEnvelope)#7 (5) { ["sender":protected]=> NULL ["recipients":protected]=> array(0) { } ["senderSet":protected]=> bool(false) ["recipientsSet":protected]=> bool(false) ["message":protected]=> object(Email)#3 (8) { ["message":protected]=> NULL ["headers":protected]=> object(Headers)#4 (2) { ["headers":"Headers":private]=> array(1) { ["to"]=> array(1) { [0]=> object(MailboxListHeader)#6 (5) { ["name":"AbstractHeader":private]=> string(2) "To" ["lineLength":"AbstractHeader":private]=> int(76) ["lang":"AbstractHeader":private]=> NULL ["charset":"AbstractHeader":private]=> string(5) "utf-8" ["addresses":protected]=> array(1) { [0]=> object(Address)#5 (2) { ["address":"Address":private]=> string(17) "alice@example.com" ["name":"Address":private]=> string(0) "" } } } } } ["lineLength":"Headers":private]=> int(76) } ["body":protected]=> NULL ["text":protected]=> NULL ["textCharset":protected]=> NULL ["html":protected]=> NULL ["htmlCharset":protected]=> NULL ["attachments":protected]=> array(0) { } } } ["transport":"MessageEvent":private]=> string(11) "null://null" ["queued":"MessageEvent":private]=> bool(false) } [1]=> object(MessageEvent)#8 (5) { ["propagationStopped":"MessageEvent":private]=> bool(false) ["message":"MessageEvent":private]=> object(Email)#9 (8) { ["message":protected]=> NULL ["headers":protected]=> object(Headers)#10 (2) { ["headers":"Headers":private]=> array(1) { ["to"]=> array(1) { [0]=> object(MailboxListHeader)#12 (5) { ["name":"AbstractHeader":private]=> string(2) "To" ["lineLength":"AbstractHeader":private]=> int(76) ["lang":"AbstractHeader":private]=> NULL ["charset":"AbstractHeader":private]=> string(5) "utf-8" ["addresses":protected]=> array(1) { [0]=> object(Address)#11 (2) { ["address":"Address":private]=> string(15) "bob@example.com" ["name":"Address":private]=> string(0) "" } } } } } ["lineLength":"Headers":private]=> int(76) } ["body":protected]=> NULL ["text":protected]=> NULL ["textCharset":protected]=> NULL ["html":protected]=> NULL ["htmlCharset":protected]=> NULL ["attachments":protected]=> array(0) { } } ["envelope":"MessageEvent":private]=> object(DelayedEnvelope)#13 (5) { ["sender":protected]=> NULL ["recipients":protected]=> array(0) { } ["senderSet":protected]=> bool(false) ["recipientsSet":protected]=> bool(false) ["message":protected]=> object(Email)#9 (8) { ["message":protected]=> NULL ["headers":protected]=> object(Headers)#10 (2) { ["headers":"Headers":private]=> array(1) { ["to"]=> array(1) { [0]=> object(MailboxListHeader)#12 (5) { ["name":"AbstractHeader":private]=> string(2) "To" ["lineLength":"AbstractHeader":private]=> int(76) ["lang":"AbstractHeader":private]=> NULL ["charset":"AbstractHeader":private]=> string(5) "utf-8" ["addresses":protected]=> array(1) { [0]=> object(Address)#11 (2) { ["address":"Address":private]=> string(15) "bob@example.com" ["name":"Address":private]=> string(0) "" } } } } } ["lineLength":"Headers":private]=> int(76) } ["body":protected]=> NULL ["text":protected]=> NULL ["textCharset":protected]=> NULL ["html":protected]=> NULL ["htmlCharset":protected]=> NULL ["attachments":protected]=> array(0) { } } } ["transport":"MessageEvent":private]=> string(11) "null://null" ["queued":"MessageEvent":private]=> bool(false) } } ["transports":"MessageEvents":private]=> array(1) { ["null://null"]=> bool(true) } } string(14) "headers_before" bool(false) string(13) "headers_after" bool(false)
[+]
..
[-] igbinary_015.phpt
[edit]
[-] __serialize_005.phpt
[edit]
[-] igbinary_087.phpt
[edit]
[-] igbinary_014.phpt
[edit]
[-] igbinary_082_php74.phpt
[edit]
[-] igbinary_063_php7.phpt
[edit]
[-] typed_property_ref_overwrite.phpt
[edit]
[-] igbinary_bug72134.phpt
[edit]
[-] igbinary_020.phpt
[edit]
[-] __serialize_020.phpt
[edit]
[-] igbinary_063_php72.phpt
[edit]
[-] igbinary_048.phpt
[edit]
[-] __serialize_016.phpt
[edit]
[-] igbinary_046d.phpt
[edit]
[-] __serialize_013.phpt
[edit]
[-] igbinary_069.phpt
[edit]
[-] __serialize_014_php8.phpt
[edit]
[-] igbinary_084.phpt
[edit]
[-] igbinary_092.phpt
[edit]
[-] igbinary_025b.phpt
[edit]
[-] igbinary_057.phpt
[edit]
[-] igbinary_043.phpt
[edit]
[-] igbinary_enums_2.phpt
[edit]
[-] igbinary_004.phpt
[edit]
[-] igbinary_067.phpt
[edit]
[-] __serialize_004.phpt
[edit]
[-] igbinary_028.phpt
[edit]
[-] __serialize_010.phpt
[edit]
[-] igbinary_081.phpt
[edit]
[-] igbinary_070.phpt
[edit]
[-] __serialize_016_php8.phpt
[edit]
[-] igbinary_085.phpt
[edit]
[-] igbinary_094.phpt
[edit]
[-] igbinary_009b.phpt
[edit]
[-] igbinary_068.phpt
[edit]
[-] igbinary_034.phpt
[edit]
[-] igbinary_enums_1.phpt
[edit]
[-] igbinary_086.phpt
[edit]
[-] igbinary_enums_3_php83.phpt
[edit]
[-] igbinary_046b.phpt
[edit]
[-] igbinary_075.phpt
[edit]
[-] __serialize_011.phpt
[edit]
[-] php82_suppress_dynamic_properties_warning.inc
[edit]
[-] igbinary_024.phpt
[edit]
[-] igbinary_045c.phpt
[edit]
[-] igbinary_079.phpt
[edit]
[-] igbinary_015c.phpt
[edit]
[-] __serialize_018.phpt
[edit]
[-] __serialize_012.phpt
[edit]
[-] igbinary_084b.phpt
[edit]
[-] igbinary_058b.phpt
[edit]
[-] igbinary_040.phpt
[edit]
[-] igbinary_066.phpt
[edit]
[-] igbinary_022.phpt
[edit]
[-] igbinary_027.phpt
[edit]
[-] igbinary_016.phpt
[edit]
[-] igbinary_046c.phpt
[edit]
[-] igbinary_023.phpt
[edit]
[-] typed_property_ref_overwrite2.phpt
[edit]
[-] igbinary_041.phpt
[edit]
[-] igbinary_099.phpt
[edit]
[-] igbinary_098.phpt
[edit]
[-] igbinary_026b.phpt
[edit]
[-] igbinary_031.phpt
[edit]
[-] igbinary_030_php72.phpt
[edit]
[-] igbinary_053.phpt
[edit]
[-] igbinary_017.phpt
[edit]
[-] __serialize_017.phpt
[edit]
[-] igbinary_001.phpt
[edit]
[-] igbinary_096.phpt
[edit]
[-] igbinary_050.phpt
[edit]
[-] igbinary_088.phpt
[edit]
[-] igbinary_065.phpt
[edit]
[-] igbinary_026_php8.phpt
[edit]
[-] igbinary_049b.phpt
[edit]
[-] igbinary_009b_php8.phpt
[edit]
[-] __serialize_001.phpt
[edit]
[-] igbinary_078.phpt
[edit]
[-] igbinary_091.phpt
[edit]
[-] igbinary_021.phpt
[edit]
[-] igbinary_enums_3.phpt
[edit]
[-] igbinary_071.phpt
[edit]
[-] igbinary_018.phpt
[edit]
[-] igbinary_029.phpt
[edit]
[-] igbinary_046.phpt
[edit]
[-] __serialize_007.phpt
[edit]
[-] igbinary_003.phpt
[edit]
[-] __serialize_008.phpt
[edit]
[-] igbinary_005.phpt
[edit]
[-] igbinary_095.phpt
[edit]
[-] igbinary_033.phpt
[edit]
[-] igbinary_047.phpt
[edit]
[-] igbinary_076.phpt
[edit]
[-] igbinary_089.phpt
[edit]
[-] igbinary_072.phpt
[edit]
[-] igbinary_049.phpt
[edit]
[-] igbinary_077.phpt
[edit]
[-] igbinary_015b.phpt
[edit]
[-] igbinary_002.phpt
[edit]
[-] igbinary_073.phpt
[edit]
[-] igbinary_048b.phpt
[edit]
[-] igbinary_012.phpt
[edit]
[-] __serialize_019.phpt
[edit]
[-] igbinary_062.phpt
[edit]
[-] __serialize_002.phpt
[edit]
[-] __serialize_015.phpt
[edit]
[-] igbinary_089_32bit.phpt
[edit]
[-] igbinary_008.phpt
[edit]
[-] typed_property_refs_php74.phpt
[edit]
[-] igbinary_064.phpt
[edit]
[-] igbinary_010.phpt
[edit]
[-] igbinary_074.phpt
[edit]
[-] typed_property_ref_assignment_failure.phpt
[edit]
[-] typed_property_refs.phpt
[edit]
[-] igbinary_052.phpt
[edit]
[-] igbinary_009.phpt
[edit]
[-] __serialize_003.phpt
[edit]
[-] igbinary_032.phpt
[edit]
[-] igbinary_bug54662.phpt
[edit]
[-] igbinary_007.phpt
[edit]
[-] igbinary_097.phpt
[edit]
[-] __serialize_006.phpt
[edit]
[-] igbinary_044.phpt
[edit]
[-] __serialize_021.phpt
[edit]
[-] igbinary_013.phpt
[edit]
[-] igbinary_071_php8.phpt
[edit]
[-] sleep_mangled_name_clash.phpt
[edit]
[-] igbinary_022_php82.phpt
[edit]
[-] igbinary_051.phpt
[edit]
[-] igbinary_045b.phpt
[edit]
[-] igbinary_055.phpt
[edit]
[-] igbinary_030_php7.phpt
[edit]
[-] igbinary_082.phpt
[edit]
[-] igbinary_080.phpt
[edit]
[-] __serialize_022.phpt
[edit]
[-] igbinary_025.phpt
[edit]
[-] __serialize_013_php8.phpt
[edit]
[-] igbinary_059.phpt
[edit]
[-] igbinary_054.phpt
[edit]
[-] igbinary_093.phpt
[edit]
[-] __serialize_009.phpt
[edit]
[-] igbinary_006.phpt
[edit]
[-] igbinary_026b_php8.phpt
[edit]
[-] igbinary_058.phpt
[edit]
[-] igbinary_083.phpt
[edit]
[-] __serialize_014.phpt
[edit]
[-] igbinary_026.phpt
[edit]
[-] igbinary_090.phpt
[edit]