--TEST--
__serialize() mechanism (015): Uninitialized properties from __sleep should throw when serializing
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with igbinary_serialize()"; }
?>
--FILE--
<?php
error_reporting(E_ALL);
set_error_handler(function ($errno, $message) {
echo $message . "\n";
});
class OSI {
public stdClass $o;
public string $s;
public ?int $i;
public float $f;
public function __sleep() {
return ['o', 's', 'i'];
}
}
class SimplePublic {
public ?int $i;
public function __sleep() {
return ['i'];
}
}
class SimpleProtected {
protected ?int $i;
public function __sleep() {
return ['i'];
}
public function __set($name, $value) {
$this->$name = $value;
}
}
class SimplePrivate {
private ?int $i;
public function __sleep() {
return ['i'];
}
public function __set($name, $value) {
$this->$name = $value;
}
}
// 00000002 -- header
// 17 03 4d79436c617373 -- object of type "MyClass"
// 14 03 000000 -- with 3 uninitialized properties
$m = new OSI();
function try_serialize_invalid($o) {
try {
var_dump(bin2hex($s = igbinary_serialize($o)));
} catch (Error $e) {
printf("Caught %s: %s\n", get_class($e), $e->getMessage());
}
}
// These should throw whether or not the uninitialized property is nullable.
try_serialize_invalid(new OSI());
try_serialize_invalid(new SimplePublic());
try_serialize_invalid(new SimpleProtected());
try_serialize_invalid(new SimplePrivate());
$s = new SimplePublic();
$s->i = null;
try_serialize_invalid($s);
$s = new SimpleProtected();
$s->i = 0;
try_serialize_invalid($s);
$s = new SimplePrivate();
$s->i = null;
try_serialize_invalid($s);
--EXPECT--
Caught Error: Typed property OSI::$o must not be accessed before initialization (in __sleep)
Caught Error: Typed property SimplePublic::$i must not be accessed before initialization (in __sleep)
Caught Error: Typed property SimpleProtected::$i must not be accessed before initialization (in __sleep)
Caught Error: Typed property SimplePrivate::$i must not be accessed before initialization (in __sleep)
string(48) "00000002170c53696d706c655075626c6963140111016900"
string(62) "00000002170f53696d706c6550726f74656374656414011104002a00690600"
string(80) "00000002170d53696d706c6550726976617465140111100053696d706c6550726976617465006900"