/home/lnzliplg/public_html/alt-php81-pecl-igbinary_3.2.15-1.el8.zip
PK j�\O\��^ ^ tests/igbinary_071_php8.phptnu �[��� --TEST--
igbinary_unserialize with references to typed properties shall skip the references or fail
--SKIPIF--
<?php if (PHP_VERSION_ID < 80000) { echo "skip __serialize/__unserialize error message different in php < 8"; } ?>
--FILE--
<?php
class A {
public int $a;
public $b;
}
class B {
public $a;
public int $b;
}
class C {
public int $a;
public string $b;
}
class D {
public int $a;
public float $b;
}
class Z {
public $a;
public $b;
}
$a = new A();
$a->a = 1234;
$a->b = &$a->a;
var_dump(bin2hex($s = igbinary_serialize($a)));
var_dump(igbinary_unserialize($s));
echo "Test B\n";
$b = new B();
$b->a = -1234;
$b->b = &$b->a;
var_dump(bin2hex($s = igbinary_serialize($b)));
var_dump(igbinary_unserialize($s));
$z = new Z();
$z->a = null;
$z->b = &$z->a;
$s = igbinary_serialize($z);
try {
var_dump(igbinary_unserialize(str_replace('Z', 'A', $s)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('Z', 'B', $s)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
$z = new Z();
$z->a = 1;
$z->b = &$z->a;
$s = igbinary_serialize($z);
try {
var_dump(igbinary_unserialize(str_replace('Z', 'C', $s)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
$z = new Z();
$z->a = 'x';
$z->b = &$z->a;
$s = igbinary_serialize($z);
try {
var_dump(igbinary_unserialize(str_replace('Z', 'C', $s)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
$z = new Z();
$z->a = 1;
$z->b = &$z->a;
$s = igbinary_serialize($z);
try {
var_dump(igbinary_unserialize(str_replace('Z', 'D', $s)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
/*
try {
var_dump(unserialize('O:1:"D":2:{s:1:"a";i:1;s:1:"b";R:2;}'));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
*/
?>
--EXPECT--
string(44) "000000021701411402110161250804d2110162250101"
object(A)#2 (2) {
["a"]=>
&int(1234)
["b"]=>
&int(1234)
}
Test B
string(44) "000000021701421402110161250904d2110162250101"
object(B)#3 (2) {
["a"]=>
&int(-1234)
["b"]=>
&int(-1234)
}
Cannot assign null to property A::$a of type int
Cannot assign null to property B::$b of type int
Cannot assign int to property C::$b of type string
Cannot assign string to property C::$a of type int
Reference with value of type int held by property D::$a of type int is not compatible with property D::$b of type floatPK j�\���P P tests/__serialize_001.phptnu �[��� --TEST--
__serialize() mechanism (001): Basics
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--FILE--
<?php
class Test {
public $prop;
public $prop2;
public function __serialize() {
return ["value" => $this->prop, 42 => $this->prop2];
}
public function __unserialize(array $data) {
$this->prop = $data["value"];
$this->prop2 = $data[42];
}
}
$test = new Test;
$test->prop = "foobar";
$test->prop2 = "barfoo";
var_dump(bin2hex($s = igbinary_serialize($test)));
var_dump(igbinary_unserialize($s));
?>
--EXPECT--
string(74) "000000021704546573741402110576616c75651106666f6f626172062a1106626172666f6f"
object(Test)#2 (2) {
["prop"]=>
string(6) "foobar"
["prop2"]=>
string(6) "barfoo"
}
PK j�\H��7y y tests/igbinary_087.phptnu �[��� --TEST--
Test serializing many values in __sleep
--SKIPIF--
<?php if (!extension_loaded("igbinary")) print "skip"; ?>
--FILE--
<?php
#[AllowDynamicProperties]
class X {
public function __sleep() {
$props = array_keys((array)$this);
echo "Called __sleep props=" . count($props) . "\n";
return $props;
}
}
$x = new X();
for ($i = 0; $i < 300; $i++) {
$x->{"p$i"} = "$i";
}
$ser = igbinary_serialize($x);
$unser = igbinary_unserialize($ser);
echo urlencode($ser), "\n";
var_dump($unser == $x);
unset($unser);
for ($i = 0; $i < 70000; $i++) {
$x->{"p$i"} = "other$i";
}
var_dump(igbinary_unserialize(igbinary_serialize($x)) == $x);
?>
--EXPECT--
Called __sleep props=300
%00%00%00%02%17%01X%15%01%2C%11%02p0%11%010%11%02p1%11%011%11%02p2%11%012%11%02p3%11%013%11%02p4%11%014%11%02p5%11%015%11%02p6%11%016%11%02p7%11%017%11%02p8%11%018%11%02p9%11%019%11%03p10%11%0210%11%03p11%11%0211%11%03p12%11%0212%11%03p13%11%0213%11%03p14%11%0214%11%03p15%11%0215%11%03p16%11%0216%11%03p17%11%0217%11%03p18%11%0218%11%03p19%11%0219%11%03p20%11%0220%11%03p21%11%0221%11%03p22%11%0222%11%03p23%11%0223%11%03p24%11%0224%11%03p25%11%0225%11%03p26%11%0226%11%03p27%11%0227%11%03p28%11%0228%11%03p29%11%0229%11%03p30%11%0230%11%03p31%11%0231%11%03p32%11%0232%11%03p33%11%0233%11%03p34%11%0234%11%03p35%11%0235%11%03p36%11%0236%11%03p37%11%0237%11%03p38%11%0238%11%03p39%11%0239%11%03p40%11%0240%11%03p41%11%0241%11%03p42%11%0242%11%03p43%11%0243%11%03p44%11%0244%11%03p45%11%0245%11%03p46%11%0246%11%03p47%11%0247%11%03p48%11%0248%11%03p49%11%0249%11%03p50%11%0250%11%03p51%11%0251%11%03p52%11%0252%11%03p53%11%0253%11%03p54%11%0254%11%03p55%11%0255%11%03p56%11%0256%11%03p57%11%0257%11%03p58%11%0258%11%03p59%11%0259%11%03p60%11%0260%11%03p61%11%0261%11%03p62%11%0262%11%03p63%11%0263%11%03p64%11%0264%11%03p65%11%0265%11%03p66%11%0266%11%03p67%11%0267%11%03p68%11%0268%11%03p69%11%0269%11%03p70%11%0270%11%03p71%11%0271%11%03p72%11%0272%11%03p73%11%0273%11%03p74%11%0274%11%03p75%11%0275%11%03p76%11%0276%11%03p77%11%0277%11%03p78%11%0278%11%03p79%11%0279%11%03p80%11%0280%11%03p81%11%0281%11%03p82%11%0282%11%03p83%11%0283%11%03p84%11%0284%11%03p85%11%0285%11%03p86%11%0286%11%03p87%11%0287%11%03p88%11%0288%11%03p89%11%0289%11%03p90%11%0290%11%03p91%11%0291%11%03p92%11%0292%11%03p93%11%0293%11%03p94%11%0294%11%03p95%11%0295%11%03p96%11%0296%11%03p97%11%0297%11%03p98%11%0298%11%03p99%11%0299%11%04p100%11%03100%11%04p101%11%03101%11%04p102%11%03102%11%04p103%11%03103%11%04p104%11%03104%11%04p105%11%03105%11%04p106%11%03106%11%04p107%11%03107%11%04p108%11%03108%11%04p109%11%03109%11%04p110%11%03110%11%04p111%11%03111%11%04p112%11%03112%11%04p113%11%03113%11%04p114%11%03114%11%04p115%11%03115%11%04p116%11%03116%11%04p117%11%03117%11%04p118%11%03118%11%04p119%11%03119%11%04p120%11%03120%11%04p121%11%03121%11%04p122%11%03122%11%04p123%11%03123%11%04p124%11%03124%11%04p125%11%03125%11%04p126%11%03126%11%04p127%11%03127%11%04p128%11%03128%11%04p129%11%03129%11%04p130%11%03130%11%04p131%11%03131%11%04p132%11%03132%11%04p133%11%03133%11%04p134%11%03134%11%04p135%11%03135%11%04p136%11%03136%11%04p137%11%03137%11%04p138%11%03138%11%04p139%11%03139%11%04p140%11%03140%11%04p141%11%03141%11%04p142%11%03142%11%04p143%11%03143%11%04p144%11%03144%11%04p145%11%03145%11%04p146%11%03146%11%04p147%11%03147%11%04p148%11%03148%11%04p149%11%03149%11%04p150%11%03150%11%04p151%11%03151%11%04p152%11%03152%11%04p153%11%03153%11%04p154%11%03154%11%04p155%11%03155%11%04p156%11%03156%11%04p157%11%03157%11%04p158%11%03158%11%04p159%11%03159%11%04p160%11%03160%11%04p161%11%03161%11%04p162%11%03162%11%04p163%11%03163%11%04p164%11%03164%11%04p165%11%03165%11%04p166%11%03166%11%04p167%11%03167%11%04p168%11%03168%11%04p169%11%03169%11%04p170%11%03170%11%04p171%11%03171%11%04p172%11%03172%11%04p173%11%03173%11%04p174%11%03174%11%04p175%11%03175%11%04p176%11%03176%11%04p177%11%03177%11%04p178%11%03178%11%04p179%11%03179%11%04p180%11%03180%11%04p181%11%03181%11%04p182%11%03182%11%04p183%11%03183%11%04p184%11%03184%11%04p185%11%03185%11%04p186%11%03186%11%04p187%11%03187%11%04p188%11%03188%11%04p189%11%03189%11%04p190%11%03190%11%04p191%11%03191%11%04p192%11%03192%11%04p193%11%03193%11%04p194%11%03194%11%04p195%11%03195%11%04p196%11%03196%11%04p197%11%03197%11%04p198%11%03198%11%04p199%11%03199%11%04p200%11%03200%11%04p201%11%03201%11%04p202%11%03202%11%04p203%11%03203%11%04p204%11%03204%11%04p205%11%03205%11%04p206%11%03206%11%04p207%11%03207%11%04p208%11%03208%11%04p209%11%03209%11%04p210%11%03210%11%04p211%11%03211%11%04p212%11%03212%11%04p213%11%03213%11%04p214%11%03214%11%04p215%11%03215%11%04p216%11%03216%11%04p217%11%03217%11%04p218%11%03218%11%04p219%11%03219%11%04p220%11%03220%11%04p221%11%03221%11%04p222%11%03222%11%04p223%11%03223%11%04p224%11%03224%11%04p225%11%03225%11%04p226%11%03226%11%04p227%11%03227%11%04p228%11%03228%11%04p229%11%03229%11%04p230%11%03230%11%04p231%11%03231%11%04p232%11%03232%11%04p233%11%03233%11%04p234%11%03234%11%04p235%11%03235%11%04p236%11%03236%11%04p237%11%03237%11%04p238%11%03238%11%04p239%11%03239%11%04p240%11%03240%11%04p241%11%03241%11%04p242%11%03242%11%04p243%11%03243%11%04p244%11%03244%11%04p245%11%03245%11%04p246%11%03246%11%04p247%11%03247%11%04p248%11%03248%11%04p249%11%03249%11%04p250%11%03250%11%04p251%11%03251%11%04p252%11%03252%11%04p253%11%03253%11%04p254%11%03254%11%04p255%11%03255%11%04p256%11%03256%11%04p257%11%03257%11%04p258%11%03258%11%04p259%11%03259%11%04p260%11%03260%11%04p261%11%03261%11%04p262%11%03262%11%04p263%11%03263%11%04p264%11%03264%11%04p265%11%03265%11%04p266%11%03266%11%04p267%11%03267%11%04p268%11%03268%11%04p269%11%03269%11%04p270%11%03270%11%04p271%11%03271%11%04p272%11%03272%11%04p273%11%03273%11%04p274%11%03274%11%04p275%11%03275%11%04p276%11%03276%11%04p277%11%03277%11%04p278%11%03278%11%04p279%11%03279%11%04p280%11%03280%11%04p281%11%03281%11%04p282%11%03282%11%04p283%11%03283%11%04p284%11%03284%11%04p285%11%03285%11%04p286%11%03286%11%04p287%11%03287%11%04p288%11%03288%11%04p289%11%03289%11%04p290%11%03290%11%04p291%11%03291%11%04p292%11%03292%11%04p293%11%03293%11%04p294%11%03294%11%04p295%11%03295%11%04p296%11%03296%11%04p297%11%03297%11%04p298%11%03298%11%04p299%11%03299
bool(true)
Called __sleep props=70000
bool(true)PK j�\"��Ņ � tests/igbinary_020.phptnu �[��� --TEST--
Object test, incomplete class
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
if (PHP_VERSION_ID >= 80200) {
// TODO undo workaround when #[AllowDynamicProperties] is added to __PHP_Incomplete_Class
error_reporting(E_ALL & ~E_DEPRECATED);
}
function test($type, $variable, $test) {
$serialized = pack('H*', $variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
var_dump($unserialized);
// echo "\n";
}
test('incom', '0000000217034f626a140211016106011101620602', false);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECTF--
incom
17034f626a140211016106011101620602
object(__PHP_Incomplete_Class)#%d (3) {
["__PHP_Incomplete_Class_Name"]=>
string(3) "Obj"
["a"]=>
int(1)
["b"]=>
int(2)
}
PK j�\6ğ� � tests/igbinary_054.phptnu �[��� --TEST--
__wakeup can add dynamic properties without affecting other objects
--FILE--
<?php
#[AllowDynamicProperties]
class Obj {
// Testing $this->a being a dynamic property.
function __construct($a) {
$this->a = $a;
}
public function __wakeup() {
echo "Calling __wakeup\n";
for ($i = 0; $i < 10000; $i++) {
$this->{'b' . $i} = 42;
}
}
}
function main() {
$array = array("roh"); // array (not a reference, but should be copied on write)
$a = new Obj($array);
$b = new Obj($array);
$c = new Obj(null);
$variable = array($a, $b, $c);
$serialized = igbinary_serialize($variable);
printf("%s\n", bin2hex($serialized));
$unserialized = igbinary_unserialize($serialized);
echo "Called igbinary_unserialize\n";
for ($a = 0; $a < 3; $a++) {
for ($i = 0; $i < 10000; $i++) {
if ($unserialized[$a]->{'b' . $i} !== 42) {
echo "Fail $a b$i\n";
return;
}
unset($unserialized[$a]->{'b' . $i});
}
}
var_dump($unserialized);
}
main();
--EXPECTF--
000000021403060017034f626a1401110161140106001103726f6806011a0014010e01010206021a0014010e0100
Calling __wakeup
Calling __wakeup
Calling __wakeup
Called igbinary_unserialize
array(3) {
[0]=>
object(Obj)#%d (1) {
["a"]=>
array(1) {
[0]=>
string(3) "roh"
}
}
[1]=>
object(Obj)#%d (1) {
["a"]=>
array(1) {
[0]=>
string(3) "roh"
}
}
[2]=>
object(Obj)#%d (1) {
["a"]=>
NULL
}
}
PK j�\��+��
�
tests/__serialize_004.phptnu �[��� --TEST--
__serialize() mechanism (004): Delayed __unserialize() calls
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()\n"; } ?>
--FILE--
<?php
#[AllowDynamicProperties]
class Wakeup {
public $data;
public function __construct(array $data) {
$this->data = $data;
}
public function __wakeup() {
echo "__wakeup() called\n";
var_dump($this->data);
$this->woken_up = true;
}
}
#[AllowDynamicProperties]
class Unserialize {
public $data;
public function __construct(array $data) {
$this->data = $data;
}
public function __serialize() {
return $this->data;
}
public function __unserialize(array $data) {
$this->data = $data;
echo "__unserialize() called\n";
var_dump($this->data);
$this->unserialized = true;
}
}
$obj = new Wakeup([new Unserialize([new Wakeup([new Unserialize([])])])]);
var_dump(bin2hex($s = igbinary_serialize($obj)));
var_dump(igbinary_unserialize($s));
?>
--EXPECT--
string(110) "00000002170657616b657570140111046461746114010600170b556e73657269616c697a65140106001a0014010e01140106001a021400"
__unserialize() called
array(0) {
}
__wakeup() called
array(1) {
[0]=>
object(Unserialize)#8 (2) {
["data"]=>
array(0) {
}
["unserialized"]=>
bool(true)
}
}
__unserialize() called
array(1) {
[0]=>
object(Wakeup)#7 (2) {
["data"]=>
array(1) {
[0]=>
object(Unserialize)#8 (2) {
["data"]=>
array(0) {
}
["unserialized"]=>
bool(true)
}
}
["woken_up"]=>
bool(true)
}
}
__wakeup() called
array(1) {
[0]=>
object(Unserialize)#6 (2) {
["data"]=>
array(1) {
[0]=>
object(Wakeup)#7 (2) {
["data"]=>
array(1) {
[0]=>
object(Unserialize)#8 (2) {
["data"]=>
array(0) {
}
["unserialized"]=>
bool(true)
}
}
["woken_up"]=>
bool(true)
}
}
["unserialized"]=>
bool(true)
}
}
object(Wakeup)#5 (2) {
["data"]=>
array(1) {
[0]=>
object(Unserialize)#6 (2) {
["data"]=>
array(1) {
[0]=>
object(Wakeup)#7 (2) {
["data"]=>
array(1) {
[0]=>
object(Unserialize)#8 (2) {
["data"]=>
array(0) {
}
["unserialized"]=>
bool(true)
}
}
["woken_up"]=>
bool(true)
}
}
["unserialized"]=>
bool(true)
}
}
["woken_up"]=>
bool(true)
}
PK j�\��z� � tests/__serialize_009.phptnu �[��� --TEST--
__serialize() mechanism (009): Object/reference ids should be the same whether or not __serialize is used.
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--FILE--
<?php
class Vest {
public $value;
public function __construct($value) {
$this->value = $value;
}
}
class Test {
public $prop;
public function __construct($value) {
$this->prop = $value;
}
public function __serialize() {
return ["value" => $this->prop];
}
public function __unserialize(array $data) {
$this->prop = $data["value"];
}
}
$vest = new Vest('first');
$vest2 = new Vest(null);
$vest3 = new Vest($vest2);
$sv = igbinary_serialize([$vest, $vest2, $vest3, $vest, $vest2]);
$test = new Test('first');
$test2 = new Test(null);
$test3 = new Test($test2);
$s = igbinary_serialize([$test, $test2, $test3, $test, $test2]);
// The only difference in the serialization should be the first byte of the only occurrence of the class name.
var_dump(bin2hex($sv));
var_dump(bin2hex($s));
var_dump(igbinary_unserialize($s));
var_dump(igbinary_unserialize($sv));
?>
--EXPECT--
string(114) "00000002140506001704566573741401110576616c75651105666972737406011a0014010e010006021a0014010e0122020603220106042202"
string(114) "00000002140506001704546573741401110576616c75651105666972737406011a0014010e010006021a0014010e0122020603220106042202"
array(5) {
[0]=>
object(Test)#7 (1) {
["prop"]=>
string(5) "first"
}
[1]=>
object(Test)#8 (1) {
["prop"]=>
NULL
}
[2]=>
object(Test)#9 (1) {
["prop"]=>
object(Test)#8 (1) {
["prop"]=>
NULL
}
}
[3]=>
object(Test)#7 (1) {
["prop"]=>
string(5) "first"
}
[4]=>
object(Test)#8 (1) {
["prop"]=>
NULL
}
}
array(5) {
[0]=>
object(Vest)#8 (1) {
["value"]=>
string(5) "first"
}
[1]=>
object(Vest)#7 (1) {
["value"]=>
NULL
}
[2]=>
object(Vest)#9 (1) {
["value"]=>
object(Vest)#7 (1) {
["value"]=>
NULL
}
}
[3]=>
object(Vest)#8 (1) {
["value"]=>
string(5) "first"
}
[4]=>
object(Vest)#7 (1) {
["value"]=>
NULL
}
}
PK j�\�e
v� � tests/igbinary_092.phptnu �[��� --TEST--
Object test, unserialize_callback_func
--INI--
error_reporting=E_ALL
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
try {
$serialized = pack('H*', $variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $test || $unserialized->b == 2 ? 'OK' : 'ERROR';
echo "\n";
} catch (Throwable $e) {
printf("Caught %s: %s\n", get_class($e), $e->getMessage());
}
}
class MyUnserializer {
public static function handleUnserialize(string $class) {
throw new RuntimeException('handleUnserialize: Class not found: ' . $class);
}
}
ini_set('unserialize_callback_func', strtoupper('MyUnserializer::handleUnserialize'));
test('throwing_autoload', '0000000217034f626a140211016106011101620602', false);
?>
--EXPECTF--
Caught RuntimeException: handleUnserialize: Class not found: Obj
PK j�\��/ / tests/igbinary_051.phptnu �[��� --TEST--
Object test, __wakeup (With multiple references)
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
class Obj {
var $a;
var $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
function __wakeup() {
$this->b = $this->a * 3;
}
}
function main() {
$o = new Obj(1, 2);
$variable = array(&$o, &$o);
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo substr(bin2hex($serialized), 8), "\n";
echo $unserialized[0]->b === 3 && $unserialized[0]->a === 1 ? 'OK' : 'ERROR';
echo "\n";
$unserialized[0] = 'a';
var_dump($unserialized);
}
main();
--EXPECT--
140206002517034f626a1402110161060111016206020601252201
OK
array(2) {
[0]=>
&string(1) "a"
[1]=>
&string(1) "a"
}
PK j�\Z� tests/igbinary_027.phptnu �[��� --TEST--
Check for serialization handler
--SKIPIF--
<?php
if (!extension_loaded('session')) {
exit('skip session extension not loaded');
}
ob_start();
phpinfo(INFO_MODULES);
$str = ob_get_clean();
$array = explode("\n", $str);
$array = preg_grep('/^igbinary session support.*yes/', $array);
if (!$array) {
exit('skip igbinary session handler not available');
}
--FILE--
<?php
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
$output .= "read\n";
return pack('H*', '0000000214011103666f6f0601');
}
function write($id, $data) {
global $output;
$output .= "wrote: ";
$output .= substr(bin2hex($data), 8). "\n";
return true;
}
function destroy($id) {
return true;
}
function gc($time) {
return true;
}
class Foo {
}
class Bar {
}
ini_set('session.serialize_handler', 'igbinary');
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
$db_object = new Foo();
$session_object = new Bar();
$v = session_start();
var_dump($v);
$_SESSION['test'] = "foobar";
session_write_close();
echo $output;
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
bool(true)
read
wrote: 14021103666f6f06011104746573741106666f6f626172
PK j�\�H��V V tests/igbinary_084.phptnu �[��� --TEST--
Properly free duplicate properties when unserializing invalid data
--FILE--
<?php
class Test {
public $pub;
public function __sleep() {
// TODO: Could start detecting duplicates and emitting a notice as well
return ["pub", "pub"];
}
}
$t = new Test();
$t->pub = new Test();
$s = igbinary_serialize($t);
echo urlencode($s), "\n";
$unser = igbinary_unserialize($s);
var_dump($unser);
?>
--EXPECT--
%00%00%00%02%17%04Test%14%02%11%03pub%1A%00%14%02%0E%01%00%0E%01%00%0E%01%22%01
object(Test)#3 (1) {
["pub"]=>
object(Test)#4 (1) {
["pub"]=>
NULL
}
}
PK j�\���� tests/igbinary_003.phptnu �[��� --TEST--
Check for bool serialisation
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $unserialized === $variable ? 'OK' : 'ERROR';
echo "\n";
}
test('bool true', true);
test('bool false', false);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
bool true
05
OK
bool false
04
OK
PK j�\E�A`� � tests/igbinary_045c.phptnu �[��� --TEST--
APCu serializer registration - more data types
--INI--
apc.enable_cli=1
apc.serializer=igbinary
--SKIPIF--
<?php
if (!extension_loaded('apcu')) {
echo "skip APCu not loaded";
return;
}
$ext = new ReflectionExtension('apcu');
if (version_compare($ext->getVersion(), '5.1.6') < 0) {
echo "skip require APCu version 5.1.6 or above";
return;
}
?>
--FILE--
<?php
echo ini_get('apc.serializer'), "\n";
class Bar {
public $foo;
}
$a = new Bar;
$a->foo = $a;
apcu_store('objloop', $a);
unset($a);
var_dump(apcu_fetch('objloop'));
apcu_store('nullval', null);
var_dump(apcu_fetch('nullval'));
apcu_store('intval', 777);
var_dump(apcu_fetch('intval'));
$o = new stdClass();
$o->prop = 5;
$a = [$o, $o];
apcu_store('simplearrayval', $a);
$unserialized = apcu_fetch('simplearrayval');
var_dump($unserialized);
if ($unserialized[0] === $unserialized[1]) {
echo "SAME\n";
} else {
echo "DIFFERENT\n";
printf("%s\n", bin2hex(igbinary_serialize($a)));
}
unset($o);
unset($a);
unset($unserialized);
$o = new stdClass();
$o->prop = 6;
$a = [&$o, &$o];
apcu_store('refarrayval', $a);
$unserialized = apcu_fetch('refarrayval');
var_dump($unserialized);
if ($unserialized[0] === $unserialized[1]) {
echo "SAME\n";
} else {
echo "DIFFERENT\n";
printf("%s\n", bin2hex(igbinary_serialize($a)));
}
?>
--EXPECTF--
igbinary
object(Bar)#%d (1) {
["foo"]=>
*RECURSION*
}
NULL
int(777)
array(2) {
[0]=>
object(stdClass)#%d (1) {
["prop"]=>
int(5)
}
[1]=>
object(stdClass)#%d (1) {
["prop"]=>
int(5)
}
}
SAME
array(2) {
[0]=>
&object(stdClass)#%d (1) {
["prop"]=>
int(6)
}
[1]=>
&object(stdClass)#%d (1) {
["prop"]=>
int(6)
}
}
SAME
PK j�\`��Oo o tests/igbinary_040.phptnu �[��� --TEST--
b0rked random data test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test() {
$serialized = igbinary_serialize(null);
$serialized = substr($serialized, 0, -1);
$length = mt_rand(1, 255);
for ($i = 0; $i < $length; ++$i) {
$serialized .= chr(mt_rand(0, 255));
}
// if returned null everything is OK
if (($unserialized = igbinary_unserialize($serialized)) === null) {
return true;
}
error_reporting(E_ALL);
// whole data is read?
$reserialized = igbinary_serialize($unserialized);
if ($serialized === $reserialized) {
return true;
}
if (is_string($reserialized) && strlen($reserialized) < strlen($serialized) && strncmp($reserialized, $serialized, 0) === 0) {
return true;
}
// igbinary should not unserialize an object for invalid data - if it does, print the unexpected value.
echo bin2hex($serialized), "\n";
echo bin2hex($reserialized), "\n";
var_dump($unserialized);
return false;
}
// Test that 100 deterministic random values don't unserialize as valid data
mt_srand(0xface);
for ($i = 0; $i < 100; ++$i) {
error_reporting(E_ERROR | E_PARSE);
if (!test()) break;
}
// Test that igbinary_unserialize warns if extra data is added and fails (suppressed in the above checks)
error_reporting(E_ALL);
echo "After testing 100 random values\n";
$result = igbinary_unserialize(igbinary_serialize(true) . "\x00");
// Should deliberately return null if extra data was seen
var_dump($result);
?>
--EXPECTF--
After testing 100 random values
Warning: igbinary_unserialize: received more data to unserialize than expected in %s on line 48
NULL
PK j�\¡�V V tests/igbinary_095.phptnu �[��� --TEST--
Test handling php 8.1 readonly properties
--SKIPIF--
<?php if (PHP_VERSION_ID < 80100) { echo "skip readonly properties require php 8.1+\n"; } ?>
--FILE--
<?php
class X {
public readonly mixed $var;
public function __construct(
public readonly int $a,
private readonly ArrayAccess&Countable $intersection,
protected readonly ?string $default = null,
) {
$this->var = $intersection;
}
}
class Y {
public readonly mixed $var;
public function __construct(
public readonly int $a,
private readonly ArrayAccess&Countable $intersection,
protected readonly ?string $default = null,
) {
$this->var = $intersection;
}
public function __serialize(): array {
return [
'a' => $this->a,
'intersection' => $this->intersection,
'default' => $this->default,
'var' => $this->var,
];
}
public function __unserialize(array $data) {
[
'a' => $this->a,
'intersection' => $this->intersection,
'default' => $this->default,
'var' => $this->var,
] = $data;
}
}
$ser = igbinary_serialize(new X(1, new ArrayObject()));
echo urlencode($ser), "\n";
var_dump(igbinary_unserialize($ser));
$ser = igbinary_serialize(new Y(1, new ArrayObject()));
echo urlencode($ser), "\n";
var_dump(igbinary_unserialize($ser));
?>
--EXPECT--
%00%00%00%02%17%01X%14%04%11%03var%17%0BArrayObject%14%04%06%00%06%00%06%01%14%00%06%02%14%00%06%03%00%11%01a%06%01%11%0F%00X%00intersection%22%01%11%0A%00%2A%00default%00
object(X)#1 (4) {
["var"]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["a"]=>
int(1)
["intersection":"X":private]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["default":protected]=>
NULL
}
%00%00%00%02%17%01Y%14%04%11%01a%06%01%11%0Cintersection%17%0BArrayObject%14%04%06%00%06%00%06%01%14%00%06%02%14%00%06%03%00%11%07default%00%11%03var%22%01
object(Y)#1 (4) {
["var"]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["a"]=>
int(1)
["intersection":"Y":private]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["default":protected]=>
NULL
}
PK j�\��mG G tests/igbinary_005.phptnu �[��� --TEST--
Check for double serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $unserialized === $variable ? 'OK' : 'ERROR';
echo "\n";
}
test('double: 123.456', 123.456);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
double: 123.456
0c405edd2f1a9fbe77
OK
PK j�\�'��Q Q tests/__serialize_012.phptnu �[��� --TEST--
Test unserialization of classes derived from ArrayIterator
--SKIPIF--
<?php if (PHP_VERSION_ID < 70406) { echo "Skip requires php 7.4.6+"; } ?>
--FILE--
<?php
// based on bug45706.phpt from php-src
//
// NOTE: ArrayIterator::__debugInfo adds a fake private property that doesn't actually exist, which affects var_dump.
// This isn't a bug in the unserializer.
class Foo1 extends ArrayIterator
{
}
class Foo2 {
}
$x = array(new Foo1(),new Foo2);
$s = igbinary_serialize($x);
var_dump(igbinary_unserialize($s));
$s = str_replace("Foo", "Bar", $s);
$y = igbinary_unserialize($s);
var_dump($y);
--EXPECTF--
array(2) {
[0]=>
object(Foo1)#3 (1) {
["storage":"ArrayIterator":private]=>
array(0) {
}
}
[1]=>
object(Foo2)#4 (0) {
}
}
array(2) {
[0]=>
object(__PHP_Incomplete_Class)#4 (5) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "Bar1"
["0"]=>
int(0)
["1"]=>
array(0) {
}
["2"]=>
array(0) {
}
["3"]=>
NULL
}
[1]=>
object(__PHP_Incomplete_Class)#3 (1) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "Bar2"
}
}
PK j�\����� � tests/igbinary_033.phptnu �[��� --TEST--
Object test, cyclic references
--SKIPIF--
<?php
if(!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
--FILE--
<?php
class Foo {
public $parent;
public $children;
public function __construct() {
$this->parent = null;
$this->children = array();
}
public function addChild(Foo $obj) {
$this->children[] = $obj;
$obj->setParent($this);
}
public function setParent(Foo $obj) {
$this->parent = $obj;
}
}
error_reporting(E_ALL);
$obj1 = new Foo();
for ($i = 0; $i < 10; $i++) {
$obj = new Foo();
$obj1->addChild($obj);
}
$o = igbinary_unserialize(igbinary_serialize($obj1->children));
foreach ($obj1->children as $k => $v) {
$obj_v = $v;
$o_v = $o[$k];
echo gettype($obj_v), "\t", gettype($o_v), "\n";
}
--EXPECT--
object object
object object
object object
object object
object object
object object
object object
object object
object object
object object
PK j�\g�5� � tests/igbinary_053.phptnu �[��� --TEST--
__wakeup can modify properties without affecting other objects
--FILE--
<?php
class Obj {
private static $count = 1;
public $a;
function __construct($a) {
$this->a = $a;
}
public function __wakeup() {
echo "call wakeup\n";
$this->a[] = "end";
}
}
function main() {
$array = ["test"]; // array (not a reference, but should be copied on write)
$a = new Obj($array);
$b = new Obj($array);
$variable = [$a, $b];
$serialized = igbinary_serialize($variable);
printf("%s\n", bin2hex($serialized));
$unserialized = igbinary_unserialize($serialized);
var_dump($unserialized);
}
main();
--EXPECTF--
000000021402060017034f626a14011101611401060011047465737406011a0014010e010102
call wakeup
call wakeup
array(2) {
[0]=>
object(Obj)#%d (1) {
["a"]=>
array(2) {
[0]=>
string(4) "test"
[1]=>
string(3) "end"
}
}
[1]=>
object(Obj)#%d (1) {
["a"]=>
array(2) {
[0]=>
string(4) "test"
[1]=>
string(3) "end"
}
}
}
PK j�\� pן � tests/__serialize_016_php8.phptnu �[��� --TEST--
__serialize() mechanism (016): Properties are still typed after unserialization (references)
--SKIPIF--
<?php
if (PHP_VERSION_ID < 80000) { echo "skip __serialize/__unserialize error message different in php < 8"; }
if (PHP_VERSION_ID >= 90000) { echo "skip requires php < 9.0 when testing that the deprecation has no impact on igbinary functionality\n"; }
?>
--FILE--
<?php
declare(strict_types=1);
// Asserts that this will emit a warning about dynamic properties due to the lack of #[AllowDynamicProperties] in PHP 8.2+, and suppresses the warning
if (PHP_VERSION_ID >= 80200) { require_once __DIR__ . '/php82_suppress_dynamic_properties_warning.inc'; }
/** @property mixed $std undeclared dynamic property */
class Test {
public int $i = 0;
public ?string $s = 's';
public object $o;
public stdClass $stdClass;
public array $a = [];
}
$t = new Test();
$t->i = 1;
$t->s = 'other';
$t->o = $t;
$t->std = (object)['key' => 'value'];
$t->a = [&$t->std, &$t->i, &$t->s, &$t->o];
$t->std->key = &$t->a;
var_dump($t);
var_dump(bin2hex($s = igbinary_serialize($t)));
$t2 = igbinary_unserialize($s);
var_dump($t2);
try {
$t2->i = 'x';
} catch (Error $e) {
echo "i: " . $e->getMessage() . "\n";
}
$t2->s = null;
try {
$t2->s = false;
} catch (Error $e) {
// The error message is "Cannot assign false" in php 8.3+
echo "s: " . str_replace('false', 'bool', $e->getMessage()) . "\n";
}
$t2->s = 'other';
try {
$t2->o = null;
} catch (Error $e) {
echo "o: " . $e->getMessage() . "\n";
}
try {
$t2->a = null;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
try {
$t2->stdClass = $t;
} catch (Error $e) {
echo "stdClass: " . $e->getMessage() . "\n";
}
try {
$t2->a = $t2;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
var_dump($t2);
?>
--EXPECT--
object(Test)#1 (5) {
["i"]=>
&int(1)
["s"]=>
&string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
&array(4) {
[0]=>
&object(stdClass)#2 (1) {
["key"]=>
*RECURSION*
}
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
["std"]=>
&object(stdClass)#2 (1) {
["key"]=>
&array(4) {
[0]=>
*RECURSION*
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
}
}
string(176) "0000000217045465737414061101692506011101732511056f7468657211016f252200001101612514040600251708737464436c617373140111036b65792501030601250101060225010206032522001103737464252204"
object(Test)#3 (5) {
["i"]=>
&int(1)
["s"]=>
&string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
&array(4) {
[0]=>
&object(stdClass)#4 (1) {
["key"]=>
*RECURSION*
}
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
["std"]=>
&object(stdClass)#4 (1) {
["key"]=>
&array(4) {
[0]=>
*RECURSION*
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
}
}
i: Cannot assign string to property Test::$i of type int
s: Cannot assign bool to property Test::$s of type ?string
o: Cannot assign null to property Test::$o of type object
a: Cannot assign null to property Test::$a of type array
stdClass: Cannot assign Test to property Test::$stdClass of type stdClass
a: Cannot assign Test to property Test::$a of type array
object(Test)#3 (5) {
["i"]=>
&int(1)
["s"]=>
&string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
&array(4) {
[0]=>
&object(stdClass)#4 (1) {
["key"]=>
*RECURSION*
}
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
["std"]=>
&object(stdClass)#4 (1) {
["key"]=>
&array(4) {
[0]=>
*RECURSION*
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
}
}
PK j�\���m m tests/igbinary_058.phptnu �[��� --TEST--
Should not call __destruct if __wakeup throws an exception
--INI--
igbinary.compact_strings = On
--FILE--
<?php
class Thrower {
public $id;
public $throws;
public $dynamic;
public function __construct($id, $throws = false) {
$this->id = $id;
$this->throws = $throws;
$this->dynamic = "original";
}
public function __wakeup() {
printf("Calling __wakeup %s\n", $this->id);
$this->dynamic = "copy";
if ($this->throws) {
throw new Exception("__wakeup threw");
}
}
public function __destruct() {
printf("Calling __destruct %s dynamic=%s\n", $this->id, $this->dynamic);
}
}
function main() {
$a = new Thrower("a", true);
$serialized = igbinary_serialize($a);
try {
igbinary_unserialize($serialized);
} catch (Exception $e) {
printf("Caught %s\n", $e->getMessage());
}
$a = null;
print("Done a\n");
$b = new Thrower("b", false);
$serialized = igbinary_serialize($b);
$bCopy = igbinary_unserialize($serialized);
print("Unserialized b\n");
var_dump($bCopy);
$bCopy = null;
$b = null;
print("Done b\n");
}
main();
--EXPECT--
Calling __wakeup a
Caught __wakeup threw
Calling __destruct a dynamic=original
Done a
Calling __wakeup b
Unserialized b
object(Thrower)#2 (3) {
["id"]=>
string(1) "b"
["throws"]=>
bool(false)
["dynamic"]=>
string(4) "copy"
}
Calling __destruct b dynamic=copy
Calling __destruct b dynamic=original
Done b
PK j�\e�O� � tests/igbinary_084b.phptnu �[��� --TEST--
Properly free duplicate undeclared properties when unserializing invalid data
--SKIPIF--
<?php
if (PHP_VERSION_ID >= 90000) { echo "skip requires php < 9.0 when testing that the deprecation has no impact on igbinary functionality\n"; }
?>
--FILE--
<?php
if (PHP_VERSION_ID >= 80200) { require_once __DIR__ . '/php82_suppress_dynamic_properties_warning.inc'; }
class Test {
public function __construct( ) {
$this->pub = null;
}
public function __sleep() {
// TODO: Could start detecting duplicates and emitting a notice as well
return ["pub", "pub"];
}
}
$t = new Test();
$t->pub = new Test();
$s = igbinary_serialize($t);
echo urlencode($s), "\n";
$unser = igbinary_unserialize($s);
var_dump($unser);
?>
--EXPECT--
%00%00%00%02%17%04Test%14%02%11%03pub%1A%00%14%02%0E%01%00%0E%01%00%0E%01%22%01
object(Test)#3 (1) {
["pub"]=>
object(Test)#4 (1) {
["pub"]=>
NULL
}
}
PK j�\~-: : tests/igbinary_076.phptnu �[��� --TEST--
igbinary and edge cases unserializing array keys
--FILE--
<?php
set_error_handler(function ($errno, $errstr) {
echo "$errstr\n";
});
var_dump(bin2hex($s = igbinary_serialize(['key' => true])));
// 3-byte string truncated in the middle of the array key
var_dump(igbinary_unserialize("\x00\x00\x00\x02\x14\x01\x11\x03\x6b\x65"));
// null instead of a string - skip over the entry
var_dump(igbinary_unserialize("\x00\x00\x00\x02\x14\x01\x00"));
?>
--EXPECTF--
string(24) "00000002140111036b657905"
igbinary_unserialize_chararray: end-of-data
NULL
array(0) {
}
PK j�\a��� tests/__serialize_013.phptnu �[��� --TEST--
__serialize() mechanism (013): Properties are still typed after unserialization
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; }
if (PHP_VERSION_ID >= 80000) { echo "skip different error message format"; }
?>
--FILE--
<?php
declare(strict_types=1);
class Test {
public int $i = 0;
public ?string $s = 's';
public object $o;
public stdClass $stdClass;
public array $a = [];
}
$t = new Test();
$t->i = 1;
$t->s = 'other';
$t->o = $t;
$t->std = (object)['key' => 'value'];
$t->a = [$t->std];
var_dump($t);
var_dump(bin2hex($s = igbinary_serialize($t)));
$t2 = igbinary_unserialize($s);
var_dump($t2);
try {
$t2->i = 'x';
} catch (Error $e) {
echo "i: " . $e->getMessage() . "\n";
}
$t2->s = null;
try {
$t2->s = false;
} catch (Error $e) {
echo "s: " . $e->getMessage() . "\n";
}
$t2->s = 'other';
try {
$t2->o = null;
} catch (Error $e) {
echo "o: " . $e->getMessage() . "\n";
}
try {
$t2->a = null;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
try {
$t2->stdClass = $t;
} catch (Error $e) {
echo "stdClass: " . $e->getMessage() . "\n";
}
try {
$t2->a = $t2;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
var_dump($t2);
--EXPECT--
object(Test)#1 (5) {
["i"]=>
int(1)
["s"]=>
string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
array(1) {
[0]=>
object(stdClass)#2 (1) {
["key"]=>
string(5) "value"
}
}
["std"]=>
object(stdClass)#2 (1) {
["key"]=>
string(5) "value"
}
}
string(142) "000000021704546573741406110169060111017311056f7468657211016f220000110161140106001708737464436c617373140111036b6579110576616c756511037374642202"
object(Test)#3 (5) {
["i"]=>
int(1)
["s"]=>
string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
array(1) {
[0]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
["std"]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
i: Typed property Test::$i must be int, string used
s: Typed property Test::$s must be string or null, bool used
o: Typed property Test::$o must be object, null used
a: Typed property Test::$a must be array, null used
stdClass: Typed property Test::$stdClass must be an instance of stdClass, Test used
a: Typed property Test::$a must be array, Test used
object(Test)#3 (5) {
["i"]=>
int(1)
["s"]=>
string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
array(1) {
[0]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
["std"]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
PK j�\���� � tests/igbinary_099.phptnu �[��� --TEST--
Test PHP 8.2 deprecation of creation of dynamic properties
--SKIPIF--
<?php
if (!extension_loaded("igbinary")) print "skip\n";
if (PHP_VERSION_ID < 80200) print "skip php < 8.2\n";
?>
--FILE--
<?php
class C {
}
$c = new C();
$invalidValues = [
"\x00\x00\x00\x02\x17\x01C\x14\x01\x11\x01a\x06\x08",
"\x00\x00\x00\x02\x17\x01C\x14\x01\x11\x04\x00*\x00a\x06\x08",
];
foreach ($invalidValues as $invalid) {
try {
var_dump(igbinary_unserialize($invalid));
} catch (Error $e) {
printf("%s: %s\n", $e::class, $e->getMessage());
}
}
--EXPECTF--
Deprecated: igbinary_unserialize(): Creation of dynamic property C::$a is deprecated in %sigbinary_099.php on line 12
object(C)#2 (1) {
["a"]=>
int(8)
}
Deprecated: igbinary_unserialize(): Creation of dynamic property C::$a is deprecated in %sigbinary_099.php on line 12
object(C)#2 (1) {
["a":protected]=>
int(8)
}
PK j�\��Ȁq q tests/igbinary_007.phptnu �[��� --TEST--
Check for simple array serialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $unserialized == $variable ? 'OK' : 'ERROR';
echo "\n";
}
test('empty array:', array());
test('array(1, 2, 3)', array(1, 2, 3));
test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)));
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
empty array:
1400
OK
array(1, 2, 3)
1403060006010601060206020603
OK
array(array(1, 2, 3), arr...
1403060014030600060106010602060206030601140306000604060106050602060606021403060006070601060806020609
OK
PK j�\W�;�g g tests/igbinary_069.phptnu �[��� --TEST--
Test serializing and unserializing many duplicate strings
--FILE--
<?php
function main() {
$arr = array();
// Just more than 2 ** 16
$n = (2 ** 16) + 100;
for ($i = 0; $i < $n; $i++) {
$s = "$i";
$arr[] = $s;
$arr[] = $s;
}
$unser = igbinary_unserialize(igbinary_serialize($arr));
var_export($arr === $unser);
}
main();
--EXPECT--
true
PK j�\�8e e tests/igbinary_026_php8.phptnu �[��� --TEST--
Cyclic array test
--INI--
report_memleaks=0
--SKIPIF--
<?php
if (!extension_loaded('igbinary')) {
echo "skip no igbinary\n";
}
if (PHP_MAJOR_VERSION < 8) {
echo "skip requires php 8.0+\n";
}
--FILE--
<?php
function test($type, $variable, $test) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo !$test || $unserialized == $variable ? 'OK' : 'ERROR', "\n";
}
$a = array(
'a' => array(
'b' => 'c',
'd' => 'e'
),
);
$a['f'] = &$a;
test('array', $a, false);
$a = array("foo" => &$b);
$b = array(1, 2, $a);
$exp = $a;
$act = igbinary_unserialize(igbinary_serialize($a));
ob_start();
var_dump($exp);
$dump_exp = ob_get_clean();
ob_start();
var_dump($act);
$dump_act = ob_get_clean();
if ($dump_act !== $dump_exp) {
echo "Var dump differs:\nActual:\n", $dump_act, "\nExpected:\n", $dump_exp, "\n";
} else {
echo "Var dump OK\n";
}
$act['foo'][1] = 'test value';
$exp['foo'][1] = 'test value';
if ($act['foo'][1] !== $act['foo'][2]['foo'][1]) {
echo "Recursive elements differ:\n";
echo "Actual\n";
var_dump($act);
var_dump($act['foo']);
echo "Expected\n";
var_dump($exp);
var_dump($exp['foo']);
}
?>
--EXPECT--
array
140211016114021101621101631101641101651101662514020e0001010e05250102
OK
Var dump differs:
Actual:
array(1) {
["foo"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
array(1) {
["foo"]=>
*RECURSION*
}
}
}
Expected:
array(1) {
["foo"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
*RECURSION*
}
}
PK j�\"�� � tests/igbinary_068.phptnu �[��� --TEST--
Test serializing and unserializing PHP_INT_MIN
--FILE--
<?php
if (!defined('PHP_INT_MIN')) {
define('PHP_INT_MIN', ~PHP_INT_MAX);
}
var_export(PHP_INT_MAX === igbinary_unserialize(igbinary_serialize(PHP_INT_MAX)));
echo "\n";
var_export(PHP_INT_MIN === igbinary_unserialize(igbinary_serialize(PHP_INT_MIN)));
echo "\n";
var_export(PHP_INT_MIN+1 === igbinary_unserialize(igbinary_serialize(PHP_INT_MIN + 1)));
echo "\n";
?>
--EXPECT--
true
true
true
PK j�\���� tests/igbinary_096.phptnu �[��� --TEST--
Test unserialization creates valid current()
--INI--
display_errors=stderr
error_reporting=E_ALL
--FILE--
<?php
$arr = [
'one' => [
'two' => [
'three' => [
'four'
],
],
],
];
$test = current(current(current(current($arr))));
var_dump($test);
// Note: after unserialization the current is the last array element.
$arr2 = igbinary_unserialize(igbinary_serialize($arr));
$test2 = current(current(current(current($arr2))));
var_dump($test2);
?>
--EXPECT--
string(4) "four"
string(4) "four"PK j�\�E�n tests/igbinary_008.phptnu �[��� --TEST--
Check for array+string serialization
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
if ($unserialized != $variable) {
echo 'ERROR, expected: ';
var_dump($variable);
echo 'got: ';
var_dump($unserialized);
} else {
echo 'OK';
}
echo "\n";
}
test('array("foo", "foo", "foo")', array("foo", "foo", "foo"));
test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2));
test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"));
test('array("" => "empty")', array("" => "empty"));
?>
--EXPECT--
array("foo", "foo", "foo")
140306001103666f6f06010e0006020e00
OK
array("one" => 1, "two" => 2))
140211036f6e650601110374776f0602
OK
array("kek" => "lol", "lol" => "kek")
140211036b656b11036c6f6c0e010e00
OK
array("" => "empty")
14010d1105656d707479
OK
PK j�\�Ue�( ( tests/igbinary_048.phptnu �[��� --TEST--
Object test, __set not called for private attr in extended class
--FILE--
<?php
class Bar {
public $a = [];
public $b = array();
public $c = NULL;
private $_d = NULL;
public function __set($name,$value) {
echo 'magic function called for ' . $name . ' with ' . var_export($value, true) . PHP_EOL;
}
}
class Foo extends Bar {
public $m;
}
$x = new Foo();
$x->a = [1, 2, 3];
$x->nonexistent = 'aaa';
igbinary_unserialize(igbinary_serialize($x));
--EXPECT--
magic function called for nonexistent with 'aaa'
PK j�\�(X�d d tests/igbinary_015c.phptnu �[��� --TEST--
Check for serialization handler
--SKIPIF--
<?php
if (!extension_loaded('session')) {
exit('skip session extension not loaded');
}
ob_start();
phpinfo(INFO_MODULES);
$str = ob_get_clean();
$array = explode("\n", $str);
$array = preg_grep('/^igbinary session support.*yes/', $array);
if (!$array) {
exit('skip igbinary session handler not available');
}
?>
--FILE--
<?php
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
$output .= "read($id)\n";
return '';
}
function write($id, $data) {
global $output;
$output .= "write($id): data:(" . bin2hex($data) . ")\n";
return true;
}
function destroy($id) {
return true;
}
function gc($time) {
return true;
}
ini_set('session.serialize_handler', 'igbinary');
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
session_id('abcdef10231512dfaz_12311');
session_start();
// save an empty session
session_write_close();
// See https://github.com/igbinary/igbinary/issues/231
// - Redis expects a non-empty string to be serialized
// - When igbinary serializes data, many applications expect it to begin with \x00\x00\x00\x02.
// - \x14\x00 represents an array(0x14) of size 0 (0x00)
echo $output;
?>
--EXPECT--
read(abcdef10231512dfaz_12311)
write(abcdef10231512dfaz_12311): data:(000000021400)
PK j�\k�}Z� � tests/igbinary_043.phptnu �[��� --TEST--
Object serialization with compact strings
--SKIPIF--
<?php
if (!extension_loaded("igbinary")) {
print "skip";
}
?>
--INI--
igbinary.compact_strings=Off
--FILE--
<?php
class Foo {
}
class Bar {
}
$expected_array = array();
for ($i = 0; $i < 10; $i++) {
$expected_array['foo_' . $i] = new Foo;
$expected_array['bar_' . $i] = new Bar;
}
$actual_array = igbinary_unserialize(igbinary_serialize($expected_array));
$error = 'OK';
foreach ($expected_array as $key => $object) {
if (!isset($actual_array[$key])) {
$error = 'ERROR';
echo "Key $key is missing from result.\n";
echo "Expected key/value:\n";
var_dump($key, $object);
var_dump($object);
break;
}
if (!is_object($actual_array[$key]) ||
get_class($object) !== get_class($actual_array[$key])) {
$error = 'ERROR';
echo "Array mismatch on $key\n";
echo "Expected key/value:\n";
var_dump($key, $object);
echo "Actual key/value:\n";
var_dump($key, $actual_array[$key]);
break;
}
}
echo $error, "\n";
--EXPECT--
OK
PK j�\ydy� � tests/igbinary_089_32bit.phptnu �[��� --TEST--
Test unserializing invalid 64-bit string header on 32-bit platform
--INI--
display_errors=stderr
error_reporting=E_ALL
--CONFLICTS--
high_memory
--SKIPIF--
<?php
if (!extension_loaded("igbinary")) print "skip\n";
if (PHP_INT_SIZE > 4) { print "skip requires 32-bit\n"; }
?>
--FILE--
<?php
$ser_invalid = hex2bin('0000000213fa56ea002a');
var_dump(igbinary_unserialize($ser_invalid));
?>
--EXPECTF--
Warning: igbinary_unserialize_chararray: %s in %sigbinary_089_32bit.php on line 3
NULLPK j�\���o+ + tests/igbinary_001.phptnu �[��� --TEST--
Check for igbinary presence
--SKIPIF--
<?php if (!extension_loaded("igbinary")) print "skip"; ?>
--FILE--
<?php
echo "igbinary extension is available\n";
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
igbinary extension is available
PK j�\�ILq tests/__serialize_014.phptnu �[��� --TEST--
__serialize() mechanism (014): Uninitialized properties can be serialized and unserialized
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; }
if (PHP_VERSION_ID >= 80000) { echo "skip different error message format"; }
?>
--FILE--
<?php
class MyClass {
public stdClass $o;
public string $s;
public ?int $i;
}
// 00000002 -- header
// 17 07 4d79436c617373 -- object of type "MyClass"
// 14 03 000000 -- with 3 uninitialized properties
$m = new MyClass();
var_dump($m);
var_dump(bin2hex($s = igbinary_serialize($m)));
var_dump(igbinary_unserialize($s));
$m = new MyClass();
$m->o = new stdClass();
unset($m->o);
$m->s = 'other';
unset($m->s);
$m->i = 42;
unset($m->i);
// Should have the same serialized representation.
var_dump($m);
var_dump(bin2hex($s = igbinary_serialize($m)));
try {
$m->i = 'i';
} catch (TypeError $e) {
echo $e->getMessage() . "\n";
}
--EXPECT--
object(MyClass)#1 (0) {
["o"]=>
uninitialized(stdClass)
["s"]=>
uninitialized(string)
["i"]=>
uninitialized(?int)
}
string(36) "0000000217074d79436c6173731403000000"
object(MyClass)#2 (0) {
["o"]=>
uninitialized(stdClass)
["s"]=>
uninitialized(string)
["i"]=>
uninitialized(?int)
}
object(MyClass)#2 (0) {
["o"]=>
uninitialized(stdClass)
["s"]=>
uninitialized(string)
["i"]=>
uninitialized(?int)
}
string(36) "0000000217074d79436c6173731403000000"
Typed property MyClass::$i must be int or null, string used
PK j�\��U� � tests/igbinary_enums_1.phptnu �[��� --TEST--
Test unserializing valid enums
--SKIPIF--
<?php if (PHP_VERSION_ID < 80100) { echo "skip enums requires php 8.1"; } ?>
--FILE--
<?php
enum Suit {
case Hearts;
case Diamonds;
case Spades;
case Clubs;
}
$ser = igbinary_serialize(Suit::Hearts);
echo urlencode($ser), "\n";
var_dump(igbinary_unserialize($ser));
var_dump(igbinary_unserialize($ser));
$serArray = igbinary_serialize([Suit::Hearts, Suit::Diamonds, Suit::Spades, Suit::Clubs, Suit::Clubs, 'Diamonds' => 'Diamonds']);
echo urlencode($serArray), "\n";
var_dump(igbinary_unserialize($serArray));
?>
--EXPECT--
%00%00%00%02%17%04Suit%27%11%06Hearts
enum(Suit::Hearts)
enum(Suit::Hearts)
%00%00%00%02%14%06%06%00%17%04Suit%27%11%06Hearts%06%01%1A%00%27%11%08Diamonds%06%02%1A%00%27%11%06Spades%06%03%1A%00%27%11%05Clubs%06%04%22%04%0E%02%0E%02
array(6) {
[0]=>
enum(Suit::Hearts)
[1]=>
enum(Suit::Diamonds)
[2]=>
enum(Suit::Spades)
[3]=>
enum(Suit::Clubs)
[4]=>
enum(Suit::Clubs)
["Diamonds"]=>
string(8) "Diamonds"
}
PK j�\G�k� � tests/__serialize_007.phptnu �[��� --TEST--
__serialize() mechanism (007): handle __unserialize throwing
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--FILE--
<?php
class Test {
public $prop;
public $prop2;
public function __serialize() {
return [$this->prop, $this->prop2];
}
public function __unserialize(array $data) {
$this->prop = $data[0];
$this->prop2 = $data[1];
throw new RuntimeException($this->prop);
}
public function __destruct() {
// should not be called
echo "Called destruct prop=$this->prop\n";
}
}
$test = new Test;
$test->prop = 'XX';
$test->prop2 = [$test];
// 00000002 - igbinary header
// 17 04 54657374 - object of class with name "Test"
// 14 02 - 2 properties
// 06 00 - uint8(0) =>
// 11 02 5858 - 'XX'
// 06 01 - uint8(1) =>
// 14 01 - array(size=2)
// 06 00 - uint8(0) =>
// 22 00 - igbinary_type_objref8 (pointer to the first referenceable item, i.e. the instance of "Test"
var_dump(bin2hex($s = igbinary_serialize($test)));
try {
var_dump(igbinary_unserialize($s));
} catch (RuntimeException $e) {
echo "Caught: {$e->getMessage()}\n";
}
$test->prop = 'not from igbinary_unserialize';
?>
--EXPECT--
string(52) "0000000217045465737414020600110258580601140106002200"
Caught: XX
Called destruct prop=not from igbinary_unserialize
PK j�\����� � tests/igbinary_090.phptnu �[��� --TEST--
Check for handling of IS_INDIRECT in arrays
--FILE--
<?php
$globalVar = 123;
$otherGlobalVar = &$globalVar;
call_user_func(function () {
$x = $GLOBALS;
foreach ($x as $key => $value) {
if (!in_array($key, ['globalVar', 'otherGlobalVar'])) {
unset($x[$key]);
}
}
var_dump($x);
$ser = igbinary_serialize($x);
echo urlencode($ser) . "\n";
var_dump(igbinary_unserialize($ser));
});
--EXPECT--
array(2) {
["globalVar"]=>
&int(123)
["otherGlobalVar"]=>
&int(123)
}
%00%00%00%02%14%02%11%09globalVar%25%06%7B%11%0EotherGlobalVar%25%01%01
array(2) {
["globalVar"]=>
&int(123)
["otherGlobalVar"]=>
&int(123)
}
PK j�\��o�} } tests/igbinary_058b.phptnu �[��� --TEST--
Should not call __destruct if __wakeup throws an exception (in arrays)
--INI--
igbinary.compact_strings = On
--FILE--
<?php
class Thrower {
public $id;
public $throws;
public $dynamic;
public function __construct($id, $throws = false) {
$this->id = $id;
$this->throws = $throws;
$this->dynamic = "original";
}
public function __wakeup() {
printf("Calling __wakeup %s\n", $this->id);
$this->dynamic = "copy";
if ($this->throws) {
throw new Exception("__wakeup threw for id " . $this->id);
}
}
public function __destruct() {
printf("Calling __destruct %s dynamic=%s\n", $this->id, $this->dynamic);
}
}
function main() {
$values = [
0 => new Thrower("a", false),
'foo' => 'last',
'key1' => new Thrower("b", false),
2 => new Thrower("c", true),
'last' => new Thrower("d", false),
];
$serialized = igbinary_serialize($values);
$values = null;
printf("Going to unserialize\n");
try {
igbinary_unserialize($serialized);
} catch (Exception $e) {
printf("Caught %s\n", $e->getMessage());
}
}
main();
--EXPECT--
Calling __destruct a dynamic=original
Calling __destruct b dynamic=original
Calling __destruct c dynamic=original
Calling __destruct d dynamic=original
Going to unserialize
Calling __wakeup a
Calling __wakeup b
Calling __wakeup c
Calling __destruct a dynamic=copy
Calling __destruct b dynamic=copy
Caught __wakeup threw for id c
PK j�\`�>l� � tests/igbinary_063_php7.phptnu �[��� --TEST--
Accessing unserialized numbers.
--SKIPIF--
<?php
if (!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
if (PHP_VERSION_ID >= 70200) {
echo "Skip php 7.1 or 7.0 required";
}
?>
--FILE--
<?php
$data = (object)array(1,2,3, -1 => 'x', 1234 => 33);
var_dump($data);
$x = "1";
$y = 1;
$z = "1234";
$w = 1234;
var_dump(isset($data->{$x}) ? $data->{$x} : "unset");
error_reporting(0);
$str = igbinary_serialize($data);
$unserialized = igbinary_unserialize($str);
var_dump($unserialized);
var_dump(isset($unserialized->{$x}) ? $unserialized->{$x} : "unset str");
var_dump(isset($unserialized->{$y}) ? $unserialized->{$y} : "unset int");
var_dump(isset($unserialized->{$z}) ? $unserialized->{$z} : "unset str 1234");
var_dump(isset($unserialized->{$w}) ? $unserialized->{$w} : "unset int 1234");
var_dump(isset($unserialized->{-1}) ? $unserialized->{-1} : "unset int -1");
?>
--EXPECT--
object(stdClass)#1 (5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[-1]=>
string(1) "x"
[1234]=>
int(33)
}
string(5) "unset"
object(stdClass)#2 (5) {
["0"]=>
int(1)
["1"]=>
int(2)
["2"]=>
int(3)
["-1"]=>
string(1) "x"
["1234"]=>
int(33)
}
int(2)
int(2)
int(33)
int(33)
string(1) "x"
PK j�\*���7 7 tests/igbinary_enums_2.phptnu �[��� --TEST--
Test unserializing valid and invalid enums
--SKIPIF--
<?php if (PHP_VERSION_ID < 80100) { echo "skip enums requires php 8.1"; } ?>
--FILE--
<?php
class ABCD {
}
enum Suit {
case Hearts;
case Diamonds;
case Spades;
case Clubs;
const HEARTS = self::Hearts;
}
$arr = ['Hearts' => Suit::Hearts];
$arr[1] = &$arr['Hearts'];
$serArray = igbinary_serialize($arr);
// PHP 8.1 added support for %0 as a null byte in EXPECTF in https://github.com/php/php-src/pull/7069
// Igbinary's use case of urlencode on binary data is rare.
// So replace % with \x
echo str_replace(['\\', '%'], ['\\\\', '\x'], urlencode($serArray)), "\n";
$result = igbinary_unserialize($serArray);
var_dump($result);
$result[1] = 'new';
var_dump($result);
$serInvalid = str_replace('Hearts', 'HEARTS', $serArray);
var_dump(igbinary_unserialize($serInvalid));
$serInvalidConst = str_replace('Hearts', 'vvvvvv', $serArray);
var_dump(igbinary_unserialize($serInvalidConst));
$serMissingClass = str_replace('Suit', 'Club', $serArray);
var_dump(igbinary_unserialize($serMissingClass));
$serInvalidClass = str_replace('Suit', 'ABCD', $serArray);
var_dump(igbinary_unserialize($serInvalidClass));
?>
--EXPECTF--
\x00\x00\x00\x02\x14\x02\x11\x06Hearts\x25\x17\x04Suit\x27\x0E\x00\x06\x01\x25\x22\x01
array(2) {
["Hearts"]=>
&enum(Suit::Hearts)
[1]=>
&enum(Suit::Hearts)
}
array(2) {
["Hearts"]=>
&string(3) "new"
[1]=>
&string(3) "new"
}
Warning: igbinary_unserialize_object_enum_case: Suit::HEARTS is not an enum case in %s on line 25
NULL
Warning: igbinary_unserialize_object_enum_case: Undefined constant Suit::vvvvvv in %s on line 28
NULL
Warning: igbinary_unserialize_object_enum_case: Class 'Club' does not exist in %s on line 31
NULL
Warning: igbinary_unserialize_object_enum_case: Class 'ABCD' is not an enum in %s on line 34
NULLPK j�\C�(�" " tests/igbinary_070.phptnu �[��� --TEST--
__serialize() mechanism in igbinary
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70400) {
die('skip requires php 7.4+');
}
?>
--FILE--
<?php
class Test {
public $prop;
public $prop2;
public function __serialize() {
return ["value" => $this->prop, 42 => $this->prop2];
}
public function __unserialize(array $data) {
$this->prop = 'unser' . $data["value"];
$this->prop2 = 'unser' . $data[42];
}
}
$test = new Test;
$test->prop = "foobar";
$test->prop2 = "barfoo";
$s = igbinary_serialize($test);
echo bin2hex($s) . "\n";
var_dump(igbinary_unserialize($s));
?>
--EXPECT--
000000021704546573741402110576616c75651106666f6f626172062a1106626172666f6f
object(Test)#2 (2) {
["prop"]=>
string(11) "unserfoobar"
["prop2"]=>
string(11) "unserbarfoo"
}
PK j�\.��M% % tests/igbinary_bug72134.phptnu �[��� --TEST--
igbinary_unserialize regression test for segfault on 3rd call for objects with dynamic property
--FILE--
<?php
#[AllowDynamicProperties]
class Obj
{
public $bar = "test";
}
$value = new Obj();
$value->i = 1;
$igb = igbinary_serialize($value);
for ($i=0; $i < 30; $i++)
{
// This used to segfault at the third attempt
echo igbinary_unserialize($igb)->bar . PHP_EOL;
}
--EXPECT--
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
test
PK j�\1��I6 6 tests/igbinary_067.phptnu �[��� --TEST--
Test serializing multiple reference groups to the same empty array
--SKIPIF--
<?php
if (!function_exists('json_encode')) { echo "skip requires json_encode\n"; }
?>
--FILE--
<?php
function dump($array) {
echo count($array) . " values\n";
foreach ($array as $k => $value) {
echo "$k: " . json_encode($value) . "\n";
}
}
function main() {
$a = array();
$b = $a;
$c = $a;
$value = array(&$b, $a, &$b, &$c, &$c);
$ser = igbinary_serialize($value);
echo bin2hex($ser) . "\n";
$v = igbinary_unserialize($ser);
dump($v);
$v[0][] = 2;
dump($v);
$v[3][] = 3;
dump($v);
var_export($a);
}
main();
?>
--EXPECT--
000000021405060025140006011400060225010106032514000604250103
5 values
0: []
1: []
2: []
3: []
4: []
5 values
0: [2]
1: []
2: [2]
3: []
4: []
5 values
0: [2]
1: []
2: [2]
3: [3]
4: [3]
array (
)
PK j�\�=u� tests/__serialize_013_php8.phptnu �[��� --TEST--
__serialize() mechanism (013): Properties are still typed after unserialization (php8)
--SKIPIF--
<?php if (PHP_VERSION_ID < 80000) { echo "skip __serialize/__unserialize error message different in php < 8"; } ?>
--FILE--
<?php
declare(strict_types=1);
/** @property mixed $std */
#[AllowDynamicProperties]
class Test {
public int $i = 0;
public ?string $s = 's';
public object $o;
public stdClass $stdClass;
public array $a = [];
}
$t = new Test();
$t->i = 1;
$t->s = 'other';
$t->o = $t;
$t->std = (object)['key' => 'value'];
$t->a = [$t->std];
var_dump($t);
var_dump(bin2hex($s = igbinary_serialize($t)));
$t2 = igbinary_unserialize($s);
var_dump($t2);
try {
$t2->i = 'x';
} catch (Error $e) {
echo "i: " . $e->getMessage() . "\n";
}
$t2->s = null;
try {
$t2->s = false;
} catch (Error $e) {
echo "s: " . str_replace('false', 'bool', $e->getMessage()) . "\n";
}
$t2->s = 'other';
try {
$t2->o = null;
} catch (Error $e) {
echo "o: " . $e->getMessage() . "\n";
}
try {
$t2->a = null;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
try {
$t2->stdClass = $t;
} catch (Error $e) {
echo "stdClass: " . $e->getMessage() . "\n";
}
try {
$t2->a = $t2;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
var_dump($t2);
?>
--EXPECT--
object(Test)#1 (5) {
["i"]=>
int(1)
["s"]=>
string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
array(1) {
[0]=>
object(stdClass)#2 (1) {
["key"]=>
string(5) "value"
}
}
["std"]=>
object(stdClass)#2 (1) {
["key"]=>
string(5) "value"
}
}
string(142) "000000021704546573741406110169060111017311056f7468657211016f220000110161140106001708737464436c617373140111036b6579110576616c756511037374642202"
object(Test)#3 (5) {
["i"]=>
int(1)
["s"]=>
string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
array(1) {
[0]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
["std"]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
i: Cannot assign string to property Test::$i of type int
s: Cannot assign bool to property Test::$s of type ?string
o: Cannot assign null to property Test::$o of type object
a: Cannot assign null to property Test::$a of type array
stdClass: Cannot assign Test to property Test::$stdClass of type stdClass
a: Cannot assign Test to property Test::$a of type array
object(Test)#3 (5) {
["i"]=>
int(1)
["s"]=>
string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
array(1) {
[0]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
["std"]=>
object(stdClass)#4 (1) {
["key"]=>
string(5) "value"
}
}
PK j�\���> tests/igbinary_031.phptnu �[��� --TEST--
Object Serializable interface throws exceptions
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
}
class Obj implements Serializable {
private static $count = 1;
var $a;
var $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function serialize() {
$c = self::$count++;
echo "call serialize, ", ($this->a ? "throw" : "no throw"),"\n";
if ($this->a) {
throw new Exception("exception in serialize $c");
}
return pack('NN', $this->a, $this->b);
}
public function unserialize($serialized) {
$tmp = unpack('N*', $serialized);
$this->__construct($tmp[1], $tmp[2]);
$c = self::$count++;
echo "call unserialize, ", ($this->b ? "throw" : "no throw"),"\n";
if ($this->b) {
throw new Exception("exception in unserialize $c");
}
}
}
$a = new Obj(1, 0);
$a = new Obj(0, 0);
$b = new Obj(0, 0);
$c = new Obj(1, 0);
$d = new Obj(0, 1);
echo "a, a, c\n";
try {
test(array($a, $a, $c));
} catch (Exception $e) {
if ($e->getPrevious()) {
$e = $e->getPrevious();
}
echo $e->getMessage(), "\n";
}
echo "b, b, d\n";
try {
test(array($b, $b, $d));
} catch (Exception $e) {
if ($e->getPrevious()) {
$e = $e->getPrevious();
}
echo $e->getMessage(), "\n";
}
--EXPECT--
a, a, c
call serialize, no throw
call serialize, throw
exception in serialize 2
b, b, d
call serialize, no throw
call serialize, no throw
call unserialize, no throw
call unserialize, throw
exception in unserialize 6
PK j�\k7z8 8 tests/igbinary_081.phptnu �[��� --TEST--
igbinary with reference group of size 1 created by array_walk_recursive
--FILE--
<?php
// Source: https://github.com/igbinary/igbinary/issues/268
//Data must be an array of at least depth 2
$data = [['hello', 'world']];
//Each leaf value must have been accessed
array_walk_recursive($data, function ($value) {});
//Then a second array must be constructed element-wise from the first
$data2 = [$data[0]];
//Then both arrays need to be serialized together
$a = [$data, $data2];
$ser1 = igbinary_serialize($a);
$b = igbinary_unserialize($ser1);
print serialize($a) . "\n";
print serialize($b) . "\n";
print bin2hex($ser1) . "\n";
print bin2hex(igbinary_serialize($b)) . "\n";
--EXPECT--
a:2:{i:0;a:1:{i:0;a:2:{i:0;s:5:"hello";i:1;s:5:"world";}}i:1;a:1:{i:0;a:2:{i:0;s:5:"hello";i:1;s:5:"world";}}}
a:2:{i:0;a:1:{i:0;a:2:{i:0;s:5:"hello";i:1;s:5:"world";}}i:1;a:1:{i:0;a:2:{i:0;s:5:"hello";i:1;s:5:"world";}}}
00000002140206001401060014020600110568656c6c6f06011105776f726c640601140106000102
00000002140206001401060014020600110568656c6c6f06011105776f726c640601140106000102
PK !j�\�[ [ tests/igbinary_028.phptnu �[��� --TEST--
Serialize object into session, full set
--SKIPIF--
<?php
if (!extension_loaded('session')) {
exit('skip session extension not loaded');
}
ob_start();
phpinfo(INFO_MODULES);
$str = ob_get_clean();
$array = explode("\n", $str);
$array = preg_grep('/^igbinary session support.*yes/', $array);
if (!$array) {
exit('skip igbinary session handler not available');
}
--FILE--
<?php
class Foo {
private static $s1 = array();
protected static $s2 = array();
public static $s3 = array();
private $d1;
protected $d2;
public $d3;
public function __construct($foo) {
$this->d1 = $foo;
$this->d2 = $foo;
$this->d3 = $foo;
}
}
class Bar {
private static $s1 = array();
protected static $s2 = array();
public static $s3 = array();
public $d1;
private $d2;
protected $d3;
public function __construct() {
}
public function set($foo) {
$this->d1 = $foo;
$this->d2 = $foo;
$this->d3 = $foo;
}
}
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
$output .= "read\n";
$a = new Bar();
$b = new Foo($a);
$a->set($b);
$session = array('old' => $b);
return igbinary_serialize($session);
}
function write($id, $data) {
global $output;
$output .= "write: ";
$output .= substr(bin2hex($data), 8). "\n";
return true;
}
function destroy($id) {
return true;
}
function gc($time) {
return true;
}
ini_set('session.serialize_handler', 'igbinary');
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
session_start();
$_SESSION['test'] = "foobar";
$a = new Bar();
$b = new Foo($a);
$a->set($b);
$_SESSION['new'] = $a;
session_write_close();
echo $output;
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
read
write: 140311036f6c641703466f6f1403110700466f6f0064311703426172140311026431220111070042617200643222011105002a00643322011105002a00643222021102643322021104746573741106666f6f62617211036e65771a0314030e041a0114030e0222030e0722030e0822030e0522040e062204
PK !j�\�ꞩ6 6 tests/igbinary_049.phptnu �[��� --TEST--
Correctly unserialize multiple references in arrays
--SKIPIF--
--INI--
igbinary.compact_strings = On
--FILE--
<?php
class Foo{}
$a = array("A");
$a[1] = &$a[0];
$a[2] = &$a[1];
$a[3] = &$a[2];
$a[4] = false;
$a[5] = &$a[4];
$a[6] = new Foo();
$a[7] = &$a[6];
$a[8] = &$a[7];
$a[9] = array(33);
$a[10] = new stdClass();
$a[10]->prop = &$a[8];
$a[11] = &$a[10];
$a[12] = $a[9];
$ig_ser = igbinary_serialize($a);
printf("ig_ser=%s\n", bin2hex($ig_ser));
$ig = igbinary_unserialize($ig_ser);
var_dump($ig);
$f = &$ig[3];
$f = 'V';
$g = &$ig[5];
$g = 'H';
$h = $ig[10];
$h->prop = 'S';
var_dump($ig);
--EXPECTF--
ig_ser=00000002140d0600251101410601250101060225010106032501010604250406052501020606251703466f6f1400060725220306082522030609140106000621060a251708737464436c6173731401110470726f70252203060b252205060c0104
array(13) {
[0]=>
&string(1) "A"
[1]=>
&string(1) "A"
[2]=>
&string(1) "A"
[3]=>
&string(1) "A"
[4]=>
&bool(false)
[5]=>
&bool(false)
[6]=>
&object(Foo)#%d (0) {
}
[7]=>
&object(Foo)#%d (0) {
}
[8]=>
&object(Foo)#%d (0) {
}
[9]=>
array(1) {
[0]=>
int(33)
}
[10]=>
&object(stdClass)#%d (1) {
["prop"]=>
&object(Foo)#%d (0) {
}
}
[11]=>
&object(stdClass)#%d (1) {
["prop"]=>
&object(Foo)#%d (0) {
}
}
[12]=>
array(1) {
[0]=>
int(33)
}
}
array(13) {
[0]=>
&string(1) "V"
[1]=>
&string(1) "V"
[2]=>
&string(1) "V"
[3]=>
&string(1) "V"
[4]=>
&string(1) "H"
[5]=>
&string(1) "H"
[6]=>
&string(1) "S"
[7]=>
&string(1) "S"
[8]=>
&string(1) "S"
[9]=>
array(1) {
[0]=>
int(33)
}
[10]=>
&object(stdClass)#%d (1) {
["prop"]=>
&string(1) "S"
}
[11]=>
&object(stdClass)#%d (1) {
["prop"]=>
&string(1) "S"
}
[12]=>
array(1) {
[0]=>
int(33)
}
}
PK !j�\�lr� � tests/__serialize_017.phptnu �[��� --TEST--
__serialize() mechanism (001): Basics
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--FILE--
<?php
class Test {
public $prop;
public function __serialize() {
return ["prop" => $this->prop];
}
public function __unserialize(array $data) {
echo "In __unserialize\n";
if (!$data['prop']) {
throw new RuntimeException("bad prop");
}
}
public function __destruct() {
echo "In __destruct\n";
}
}
$test = new Test;
$test->prop = new Test();
var_dump(bin2hex($s = igbinary_serialize($test)));
try {
igbinary_unserialize($s);
} catch (RuntimeException $e) {
echo "Caught {$e->getMessage()}\n";
}
?>
--EXPECT--
string(50) "000000021704546573741401110470726f701a0014010e0100"
In __unserialize
Caught bad prop
In __destruct
In __destructPK !j�\|���� � tests/__serialize_003.phptnu �[��� --TEST--
__serialize() mechanism (003): Interoperability of different serialization mechanisms
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
class Vest implements Serializable {
public function serialize() {
echo "serialize() called\n";
return "payload";
}
public function unserialize($payload) {
}
}
class Test implements Serializable {
public function __sleep() {
echo "__sleep() called\n";
}
public function __wakeup() {
echo "__wakeup() called\n";
}
public function __serialize() {
echo "__serialize() called\n";
return ["key" => "value"];
}
public function __unserialize(array $data) {
echo "__unserialize() called\n";
var_dump($data);
}
public function serialize() {
echo "serialize() called\n";
return "payload";
}
public function unserialize($payload) {
echo "unserialize() called\n";
var_dump($payload);
}
}
$test = new Test;
var_dump(bin2hex($s = igbinary_serialize($test)));
var_dump(igbinary_unserialize($s));
var_dump(igbinary_unserialize(hex2bin('000000021704546573741d077061796c6f6164')));
?>
--EXPECT--
__serialize() called
string(48) "00000002170454657374140111036b6579110576616c7565"
__unserialize() called
array(1) {
["key"]=>
string(5) "value"
}
object(Test)#2 (0) {
}
unserialize() called
string(7) "payload"
object(Test)#2 (0) {
}
PK "j�\�r�;� � tests/igbinary_017.phptnu �[��� --TEST--
Object test, __wakeup
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $test || $unserialized->b == 3 ? 'OK' : 'ERROR';
echo "\n";
}
class Obj {
var $a;
var $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
function __wakeup() {
$this->b = $this->a * 3;
}
}
$o = new Obj(1, 2);
test('object', $o, false);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
object
17034f626a140211016106011101620602
OK
PK "j�\�x2� � tests/igbinary_046c.phptnu �[��� --TEST--
Correctly unserialize multiple array refs.
--SKIPIF--
--INI--
igbinary.compact_strings = On
--FILE--
<?php
$a = array(array());
$a[1] = &$a[0];
$a[2] = &$a[1];
$a[3] = &$a[2];
printf("%s\n", serialize($a));
$ig_ser = igbinary_serialize($a);
printf("%s\n", bin2hex($ig_ser));
$ig = igbinary_unserialize($ig_ser);
printf("%s\n", serialize($ig));
$f = &$ig[3];
$f = 'V';
var_dump($ig);
--EXPECT--
a:4:{i:0;a:0:{}i:1;R:2;i:2;R:2;i:3;R:2;}
0000000214040600251400060125010106022501010603250101
a:4:{i:0;a:0:{}i:1;R:2;i:2;R:2;i:3;R:2;}
array(4) {
[0]=>
&string(1) "V"
[1]=>
&string(1) "V"
[2]=>
&string(1) "V"
[3]=>
&string(1) "V"
}
PK "j�\"}�� � tests/igbinary_088.phptnu �[��� --TEST--
Test serializing wrong values in __sleep
--SKIPIF--
<?php if (!extension_loaded("igbinary")) print "skip"; ?>
--FILE--
<?php
#[AllowDynamicProperties]
class X {
public function __sleep() {
return $this;
}
}
$x = new X();
for ($i = 0; $i < 3; $i++) {
$x->{"p$i"} = "name$i";
}
$ser = igbinary_serialize($x);
$unser = igbinary_unserialize($ser);
echo str_replace(['\\', '%'], ['\\\\', '\x'], urlencode($ser)), "\n";
var_dump($unser);
?>
--EXPECTF--
Notice: igbinary_serialize(): "name0" returned as member variable from __sleep() but does not exist in %s on line 12
Notice: igbinary_serialize(): "name1" returned as member variable from __sleep() but does not exist in %s on line 12
Notice: igbinary_serialize(): "name2" returned as member variable from __sleep() but does not exist in %s on line 12
\x00\x00\x00\x02\x17\x01X\x14\x03\x11\x05name0\x00\x11\x05name1\x00\x11\x05name2\x00
object(X)#2 (3) {
["name0"]=>
NULL
["name1"]=>
NULL
["name2"]=>
NULL
}PK "j�\\V�� � tests/igbinary_075.phptnu �[��� --TEST--
igbinary and not enough data for array
--FILE--
<?php
set_error_handler(function ($errno, $errstr) {
echo "$errstr\n";
});
class X {}
var_dump(bin2hex($s = igbinary_serialize(new X())));
echo "One byte\n";
var_dump(igbinary_unserialize("\x00\x00\x00\x02\x17\x01\x58\x14"));
echo "Two byte\n";
var_dump(igbinary_unserialize("\x00\x00\x00\x02\x17\x01\x58\x15"));
igbinary_unserialize("\x00\x00\x00\x02\x17\x01\x58\x15\xff");
echo "Four byte\n";
var_dump(igbinary_unserialize("\x00\x00\x00\x02\x17\x01\x58\x16"));
igbinary_unserialize("\x00\x00\x00\x02\x17\x01\x58\x16\x00\x00\x01");
?>
--EXPECTF--
string(18) "000000021701581400"
One byte
igbinary_unserialize_object_properties: end-of-data
NULL
Two byte
igbinary_unserialize_object_properties: end-of-data
NULL
igbinary_unserialize_object_properties: end-of-data
Four byte
igbinary_unserialize_object_properties: end-of-data
NULL
igbinary_unserialize_object_properties: end-of-dataPK "j�\�q��� � tests/igbinary_062.phptnu �[��� --TEST--
igbinary should not call __wakeup() if Serializable::unserialize was used to unserialize the object data (like `unserialize`)
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
class A implements Serializable {
public $prop = 'value';
public function serialize() {
echo "In serialize " . $this->prop . "\n";
return $this->prop;
}
public function unserialize($data) {
echo "In unserialize $data\n";
$this->prop = $data;
}
public function __wakeup() {
echo "In __wakeup, unexpectedly\n";
}
}
function testA() {
$a = new A();
$a->prop = 'other';
$ser = serialize($a);
$b = unserialize($ser);
var_dump($b);
$c = new A();
$c->prop = 'igprop';
$serC = igbinary_serialize($c);
echo bin2hex($serC) . "\n";
$d = igbinary_unserialize($serC);
var_dump($d);
}
testA();
?>
--EXPECTF--
In serialize other
In unserialize other
object(A)#%d (1) {
["prop"]=>
string(5) "other"
}
In serialize igprop
000000021701411d06696770726f70
In unserialize igprop
object(A)#%d (1) {
["prop"]=>
string(6) "igprop"
}
PK #j�\Ծ��
�
tests/__serialize_016.phptnu �[��� --TEST--
__serialize() mechanism (016): Properties are still typed after unserialization (references)
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; }
if (PHP_VERSION_ID >= 80000) { echo "skip different error message format"; }
?>
--FILE--
<?php
declare(strict_types=1);
class Test {
public int $i = 0;
public ?string $s = 's';
public object $o;
public stdClass $stdClass;
public array $a = [];
}
$t = new Test();
$t->i = 1;
$t->s = 'other';
$t->o = $t;
$t->std = (object)['key' => 'value'];
$t->a = [&$t->std, &$t->i, &$t->s, &$t->o];
$t->std->key = &$t->a;
var_dump($t);
var_dump(bin2hex($s = igbinary_serialize($t)));
$t2 = igbinary_unserialize($s);
var_dump($t2);
try {
$t2->i = 'x';
} catch (Error $e) {
echo "i: " . $e->getMessage() . "\n";
}
$t2->s = null;
try {
$t2->s = false;
} catch (Error $e) {
echo "s: " . $e->getMessage() . "\n";
}
$t2->s = 'other';
try {
$t2->o = null;
} catch (Error $e) {
echo "o: " . $e->getMessage() . "\n";
}
try {
$t2->a = null;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
try {
$t2->stdClass = $t;
} catch (Error $e) {
echo "stdClass: " . $e->getMessage() . "\n";
}
try {
$t2->a = $t2;
} catch (Error $e) {
echo "a: " . $e->getMessage() . "\n";
}
var_dump($t2);
--EXPECT--
object(Test)#1 (5) {
["i"]=>
&int(1)
["s"]=>
&string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
&array(4) {
[0]=>
&object(stdClass)#2 (1) {
["key"]=>
*RECURSION*
}
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
["std"]=>
&object(stdClass)#2 (1) {
["key"]=>
&array(4) {
[0]=>
*RECURSION*
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
}
}
string(176) "0000000217045465737414061101692506011101732511056f7468657211016f252200001101612514040600251708737464436c617373140111036b65792501030601250101060225010206032522001103737464252204"
object(Test)#3 (5) {
["i"]=>
&int(1)
["s"]=>
&string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
&array(4) {
[0]=>
&object(stdClass)#4 (1) {
["key"]=>
*RECURSION*
}
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
["std"]=>
&object(stdClass)#4 (1) {
["key"]=>
&array(4) {
[0]=>
*RECURSION*
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
}
}
i: Typed property Test::$i must be int, string used
s: Typed property Test::$s must be string or null, bool used
o: Typed property Test::$o must be object, null used
a: Typed property Test::$a must be array, null used
stdClass: Typed property Test::$stdClass must be an instance of stdClass, Test used
a: Typed property Test::$a must be array, Test used
object(Test)#3 (5) {
["i"]=>
&int(1)
["s"]=>
&string(5) "other"
["o"]=>
*RECURSION*
["stdClass"]=>
uninitialized(stdClass)
["a"]=>
&array(4) {
[0]=>
&object(stdClass)#4 (1) {
["key"]=>
*RECURSION*
}
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
["std"]=>
&object(stdClass)#4 (1) {
["key"]=>
&array(4) {
[0]=>
*RECURSION*
[1]=>
&int(1)
[2]=>
&string(5) "other"
[3]=>
*RECURSION*
}
}
}PK #j�\�;��K K tests/igbinary_080.phptnu �[��� --TEST--
igbinary with hash collision serializing strings
--FILE--
<?php
$var=['id'=>"3010480803", 'user_id'=>12346];
$serialized = igbinary_serialize($var);
$unserialized = igbinary_unserialize($serialized);
var_dump($unserialized);
$var=['id'=>"3010480803", 'user_id'=>"3010480804"];
$serialized = igbinary_serialize($var);
$unserialized = igbinary_unserialize($serialized);
var_dump($unserialized);
?>
--EXPECT--
array(2) {
["id"]=>
string(10) "3010480803"
["user_id"]=>
int(12346)
}
array(2) {
["id"]=>
string(10) "3010480803"
["user_id"]=>
string(10) "3010480804"
}
PK #j�\�,y� tests/igbinary_050.phptnu �[��� --TEST--
Correctly unserialize cyclic object references
--SKIPIF--
--INI--
igbinary.compact_strings = On
--FILE--
<?php
$a = new stdClass();
$a->foo = &$a;
$a->bar = &$a;
$b = new stdClass();
$b->cyclic = &$a;
printf("%s\n", serialize($b));
$ig_ser = igbinary_serialize($b);
printf("%s\n", bin2hex($ig_ser));
$ig = igbinary_unserialize($ig_ser);
printf("%s\n", serialize($ig));
var_dump($ig);
$f = &$ig->cyclic->foo;
$f = 'V';
var_dump($ig);
// Note: While the php7 unserializer consistently makes a distinction between refs to an object and non-refs,
// the php5 serializer does not.
--EXPECTF--
O:8:"stdClass":1:{s:6:"cyclic";O:8:"stdClass":2:{s:3:"foo";R:2;s:3:"bar";R:2;}}
000000021708737464436c617373140111066379636c6963251a0014021103666f6f2522011103626172252201
O:8:"stdClass":1:{s:6:"cyclic";O:8:"stdClass":2:{s:3:"foo";R:2;s:3:"bar";R:2;}}
object(stdClass)#3 (1) {
["cyclic"]=>
&object(stdClass)#4 (2) {
["foo"]=>
*RECURSION*
["bar"]=>
*RECURSION*
}
}
object(stdClass)#3 (1) {
["cyclic"]=>
&string(1) "V"
}
PK #j�\SH� � tests/igbinary_064.phptnu �[��� --TEST--
Works when there are hash collisions in strings when serializing.
--SKIPIF--
<?php
if(!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
?>
--FILE--
<?php
#[AllowDynamicProperties]
class Fy{
public $EzFy = 2;
public function __construct($x) {
$this->x = $x;
}
}
class Ez {
public $FyEz = 'EzEz';
}
class G8 {
public $FyG8;
}
$data = array(new Fy('G8G8'), new Fy('EzG8'), new Ez(), new G8(), new Ez(), 'G8' => new G8(), 'F8Ez' => new G8(), array(new G8()));
var_dump($data);
echo "\n";
$str = igbinary_serialize($data);
echo bin2hex($str) . "\n";
$unserialized = igbinary_unserialize($str);
var_dump($unserialized);
echo "\n";
var_export(serialize($data) === serialize($unserialized));
?>
--EXPECT--
array(8) {
[0]=>
object(Fy)#1 (2) {
["EzFy"]=>
int(2)
["x"]=>
string(4) "G8G8"
}
[1]=>
object(Fy)#2 (2) {
["EzFy"]=>
int(2)
["x"]=>
string(4) "EzG8"
}
[2]=>
object(Ez)#3 (1) {
["FyEz"]=>
string(4) "EzEz"
}
[3]=>
object(G8)#4 (1) {
["FyG8"]=>
NULL
}
[4]=>
object(Ez)#5 (1) {
["FyEz"]=>
string(4) "EzEz"
}
["G8"]=>
object(G8)#6 (1) {
["FyG8"]=>
NULL
}
["F8Ez"]=>
object(G8)#7 (1) {
["FyG8"]=>
NULL
}
[5]=>
array(1) {
[0]=>
object(G8)#8 (1) {
["FyG8"]=>
NULL
}
}
}
00000002140806001702467914021104457a4679060211017811044738473806011a0014020e0106020e021104457a473806021702457a140111044679457a1104457a457a06031702473814011104467947380006041a0514010e060e070e081a0814010e090011044638457a1a0814010e09000605140106001a0814010e0900
array(8) {
[0]=>
object(Fy)#9 (2) {
["EzFy"]=>
int(2)
["x"]=>
string(4) "G8G8"
}
[1]=>
object(Fy)#10 (2) {
["EzFy"]=>
int(2)
["x"]=>
string(4) "EzG8"
}
[2]=>
object(Ez)#11 (1) {
["FyEz"]=>
string(4) "EzEz"
}
[3]=>
object(G8)#12 (1) {
["FyG8"]=>
NULL
}
[4]=>
object(Ez)#13 (1) {
["FyEz"]=>
string(4) "EzEz"
}
["G8"]=>
object(G8)#14 (1) {
["FyG8"]=>
NULL
}
["F8Ez"]=>
object(G8)#15 (1) {
["FyG8"]=>
NULL
}
[5]=>
array(1) {
[0]=>
object(G8)#16 (1) {
["FyG8"]=>
NULL
}
}
}
true
PK $j�\_�� tests/__serialize_010.phptnu �[��� --TEST--
__serialize() mechanism (010): handle references in array returned by __serialize
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--FILE--
<?php
class Test {
public $prop;
public $prop2;
public function __serialize() {
return [$this->prop, $this->prop2];
}
public function __unserialize(array $data) {
$this->prop = $data[0];
$this->prop2 = $data[1];
if (!$this->prop) {
throw new RuntimeException("Threw from __unserialize");
}
}
public function __destruct() {
// should not be called
echo "Called destruct\n";
}
}
$test = new Test;
$test->prop = &$test;
$test->prop2 = [&$test];
var_dump(bin2hex($s = igbinary_serialize($test)));
var_dump(igbinary_unserialize($s));
unset($test->prop);
$test->prop = false;
var_dump(bin2hex($s = igbinary_serialize($test)));
try {
igbinary_unserialize($s);
} catch (RuntimeException $e) {
echo "message={$e->getMessage()}\n";
}
echo "Calling gc_collect_cycles\n";
gc_collect_cycles();
echo "After call to gc_collect_cycles\n";
?>
--EXPECT--
string(50) "00000002170454657374140206002200060114010600252200"
object(Test)#2 (2) {
["prop"]=>
*RECURSION*
["prop2"]=>
array(1) {
[0]=>
*RECURSION*
}
}
string(48) "000000021704546573741402060004060114010600252200"
message=Threw from __unserialize
Calling gc_collect_cycles
Called destruct
After call to gc_collect_cycles
Called destructPK $j�\
-$A A ( tests/typed_property_ref_overwrite2.phptnu �[��� --TEST--
Overwriting a typed property that is not yet a reference
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) die("skip php 7.4+"); ?>
--FILE--
<?php
class Test {
public $drop;
public ?Test $prop;
}
$orig = new Test();
$orig->drop = null;
$orig->prop = new Test();
$orig->prop->prop = &$orig->prop;
$ser = igbinary_serialize($orig);
echo urlencode($ser), "\n";
$ser2 = str_replace('drop', 'prop', $ser);
$result = igbinary_unserialize($ser2);
var_dump($result);
try {
$result->prop = 1;
} catch (TypeError $e) {
printf("Caught %s\n", get_class($e));
}
?>
--EXPECT--
%00%00%00%02%17%04Test%14%02%11%04drop%00%11%04prop%25%1A%00%14%02%0E%01%00%0E%02%25%22%01
object(Test)#3 (2) {
["drop"]=>
NULL
["prop"]=>
&object(Test)#4 (2) {
["drop"]=>
NULL
["prop"]=>
*RECURSION*
}
}
Caught TypeError
PK $j�\�؏7� � tests/igbinary_049b.phptnu �[��� --TEST--
Correctly unserialize multiple references in objects
--SKIPIF--
--INI--
igbinary.compact_strings = On
--FILE--
<?php
class Foo{}
$a = new stdClass();
$a->x0 = NULL;
$a->x1 = &$a->x0;
$a->x2 = &$a->x1;
$a->x3 = &$a->x2;
$a->x4 = false;
$a->x5 = &$a->x4;
$a->x6 = new Foo();
$a->x7 = &$a->x6;
$a->x8 = &$a->x7;
$a->x9 = array(33);
$a->x10 = new stdClass();
$a->x10->prop = &$a->x8;
$a->x11 = &$a->x10;
$a->x12 = $a->x9;
$ig_ser = igbinary_serialize($a);
printf("ig_ser=%s\n", bin2hex($ig_ser));
$ig = igbinary_unserialize($ig_ser);
$f = &$ig->x3;
$f = 'V';
$g = &$ig->x5;
$g = 'H';
$h = $ig->x10;
$h->prop = 'S';
var_dump($ig);
--EXPECTF--
ig_ser=000000021708737464436c617373140d1102783025001102783125010111027832250101110278332501011102783425041102783525010211027836251703466f6f14001102783725220311027838252203110278391401060006211103783130251a001401110470726f70252203110378313125220511037831320104
object(stdClass)#%d (13) {
["x0"]=>
&string(1) "V"
["x1"]=>
&string(1) "V"
["x2"]=>
&string(1) "V"
["x3"]=>
&string(1) "V"
["x4"]=>
&string(1) "H"
["x5"]=>
&string(1) "H"
["x6"]=>
&string(1) "S"
["x7"]=>
&string(1) "S"
["x8"]=>
&string(1) "S"
["x9"]=>
array(1) {
[0]=>
int(33)
}
["x10"]=>
&object(stdClass)#%d (1) {
["prop"]=>
&string(1) "S"
}
["x11"]=>
&object(stdClass)#%d (1) {
["prop"]=>
&string(1) "S"
}
["x12"]=>
array(1) {
[0]=>
int(33)
}
}
PK %j�\�0�"� � tests/igbinary_029.phptnu �[��� --TEST--
Igbinary module info
--SKIPIF--
<?php if (!extension_loaded("igbinary")) print "skip";
?>
--FILE--
<?php
ob_start();
phpinfo(INFO_MODULES);
$str = ob_get_clean();
$array = explode("\n", $str);
$array = preg_grep('/^igbinary/', $array);
echo implode("\n", $array);
--EXPECTF--
igbinary
igbinary support => enabled
igbinary version => %s
igbinary AP%s serializer ABI => %s
igbinary session support => %s
igbinary.compact_strings => %s => %s
PK %j�\C �H H $ tests/typed_property_refs_php74.phptnu �[��� --TEST--
unserialize with references to typed properties shall skip the references or fail
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400 || PHP_VERSION_ID >= 80000) die("skip requires php 7.4 error message"); ?>
--FILE--
<?php
class X {
public $a;
public $b;
}
class A {
public int $a;
public $b;
}
class B {
public $a;
public int $b;
}
class E {
public $a;
public int $b;
}
class C {
public int $a;
public string $b;
}
class D {
public int $a;
public float $b;
}
function create_ser($value): string {
$v = new X();
$v->a = $value;
$v->b = &$v->a;
$ser = igbinary_serialize($v);
printf("for %s: %s\n", var_export($value, true), urlencode($ser));
return $ser;
}
$serInt = create_ser(1);
$serNull = create_ser(null);
$serStr = create_ser('x');
var_dump(igbinary_unserialize(str_replace('X', 'A', $serInt)));
var_dump(igbinary_unserialize(str_replace('X', 'B', $serInt)));
var_dump(igbinary_unserialize(str_replace('X', 'E', $serInt)));
try {
var_dump(igbinary_unserialize(str_replace('X', 'A', $serNull)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'B', $serNull)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'C', $serInt)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'C', $serStr)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'D', $serInt)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
for 1: %00%00%00%02%17%01X%14%02%11%01a%25%06%01%11%01b%25%01%01
for NULL: %00%00%00%02%17%01X%14%02%11%01a%25%00%11%01b%25%01%01
for 'x': %00%00%00%02%17%01X%14%02%11%01a%25%11%01x%11%01b%25%01%01
object(A)#1 (2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
object(B)#1 (2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
object(E)#1 (2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
Typed property A::$a must be int, null used
Typed property B::$b must be int, null used
Typed property C::$b must be string, int used
Typed property C::$a must be int, string used
Reference with value of type int held by property D::$a of type int is not compatible with property D::$b of type float
PK %j�\�Ɗ�
tests/igbinary_079.phptnu �[��� --TEST--
igbinary and many arrays
--FILE--
<?php
function generate_test_array(int $n) : array {
$result = [];
for ($i = 0; $i < $n; $i++) {
$result[] = [$i];
}
// Validate that igbinary properly serializes and unserializes the references to arrays created earlier
for ($i = 0; $i < $n; $i++) {
$result[] = $result[$i];
}
return $result;
}
$small = generate_test_array(2);
var_dump(bin2hex($s = igbinary_serialize($small)));
var_dump(igbinary_unserialize($s));
$medium = generate_test_array(1 << 8);
var_dump(igbinary_unserialize(igbinary_serialize($medium)) === $medium);
$large = generate_test_array(1 << 16);
var_dump(igbinary_unserialize(igbinary_serialize($large)) === $large);
?>
--EXPECTF--
string(60) "000000021404060014010600060006011401060006010602010106030102"
array(4) {
[0]=>
array(1) {
[0]=>
int(0)
}
[1]=>
array(1) {
[0]=>
int(1)
}
[2]=>
array(1) {
[0]=>
int(0)
}
[3]=>
array(1) {
[0]=>
int(1)
}
}
bool(true)
bool(true)
PK &j�\l�oҺ � tests/igbinary_026b.phptnu �[��� --TEST--
Cyclic array test 2
--INI--
report_memleaks=0
--SKIPIF--
<?php
if (!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
if (PHP_MAJOR_VERSION > 7) {
echo "skip requires php 7.x\n";
}
--FILE--
<?php
$a = array("foo" => &$b);
$b = array(1, 2, $a);
/* all three statements below should produce same output however PHP stock
* unserialize/serialize produces different output (5.2.16). I consider this is
* a PHP bug. - Oleg Grenrus
*/
//$k = $a;
//$k = unserialize(serialize($a));
$k = igbinary_unserialize(igbinary_serialize($a));
function check($a, $k) {
ob_start();
var_dump($a);
$a_str = ob_get_clean();
ob_start();
var_dump($k);
$k_str = ob_get_clean();
if ($a_str !== $k_str) {
echo "Output differs\n";
echo "Expected:\n", $a_str, "\n";
echo "Actual:\n", $k_str, "\n";
} else {
echo "OK\n";
}
}
check($a, $k);
$a["foo"][2]["foo"][1] = "b";
$k["foo"][2]["foo"][1] = "b";
check($a, $k);
?>
--EXPECT--
OK
OK
PK &j�\}�xu4 4 tests/__serialize_018.phptnu �[��� --TEST--
__serialize() freed on unserialize exception without calling destructor.
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
class ThrowsInUnserialize implements Serializable {
public function serialize() {
return "test data";
}
public function unserialize($ser) {
echo "Unserializing $ser\n";
throw new Error($ser);
}
public function __destruct() {
echo "In __destruct ThrowsInUnserialize\n";
}
}
class Test {
public $prop;
public $prop2;
public function __serialize() {
return [0 => $this->prop, "value" => $this->prop2];
}
public function __unserialize(array $data) {
echo "In __unserialize Test\n";
}
public function __destruct() {
echo "In __destruct Test\n";
}
}
$test = new Test;
$test->prop = new ThrowsInUnserialize();
$test->prop2 = "barfoo";
var_dump(bin2hex($s = igbinary_serialize($test)));
try {
var_dump(igbinary_unserialize($s));
} catch (Error $e) {
echo "Caught: {$e->getMessage()}\n";
}
gc_collect_cycles();
echo "After gc_collect_cycles\n";
unset($test);
gc_collect_cycles();
echo "And for serialize/unserialize\n";
$test = new Test;
$test->prop = new ThrowsInUnserialize();
$test->prop2 = "barfoo";
var_dump(bin2hex($s = serialize($test)));
try {
var_dump(unserialize($s));
} catch (Error $e) {
echo "Caught: {$e->getMessage()}\n";
}
?>
--EXPECT--
string(122) "000000021704546573741402060017135468726f7773496e556e73657269616c697a651d09746573742064617461110576616c75651106626172666f6f"
Unserializing test data
In __destruct ThrowsInUnserialize
Caught: test data
After gc_collect_cycles
In __destruct Test
In __destruct ThrowsInUnserialize
And for serialize/unserialize
string(168) "4f3a343a2254657374223a323a7b693a303b433a31393a225468726f7773496e556e73657269616c697a65223a393a7b7465737420646174617d733a353a2276616c7565223b733a363a22626172666f6f223b7d"
Unserializing test data
In __destruct ThrowsInUnserialize
Caught: test data
In __destruct Test
In __destruct ThrowsInUnserializePK &j�\��:M M tests/igbinary_015.phptnu �[��� --TEST--
Check for serialization handler
--SKIPIF--
<?php
if (!extension_loaded('session')) {
exit('skip session extension not loaded');
}
ob_start();
phpinfo(INFO_MODULES);
$str = ob_get_clean();
$array = explode("\n", $str);
$array = preg_grep('/^igbinary session support.*yes/', $array);
if (!$array) {
exit('skip igbinary session handler not available');
}
--FILE--
<?php
$output = '';
function open($path, $name) {
return true;
}
function close() {
return true;
}
function read($id) {
global $output;
return pack('H*', '0000000214011103666f6f0601');
}
function write($id, $data) {
global $output;
$output .= substr(bin2hex($data), 8). "\n";
return true;
}
function destroy($id) {
return true;
}
function gc($time) {
return true;
}
ini_set('session.serialize_handler', 'igbinary');
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
session_start();
echo ++$_SESSION['foo'], "\n";
session_write_close();
echo $output;
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
2
14011103666f6f0602
PK &j�\wZ�� � ! tests/igbinary_enums_3_php83.phptnu �[��� --TEST--
Test unserializing valid enums inferring value
--SKIPIF--
<?php if (PHP_VERSION_ID < 80300) { echo "skip non-compile time constant in enums requires php 8.3"; } ?>
--FILE--
<?php
enum X: string {
case X = X;
}
$x = 'X';
define('X', "dynamic$x");
$value = urldecode('%00%00%00%02%17%01X%27%0E%00');
var_dump(igbinary_unserialize($value));
$ser = igbinary_serialize(X::X);
echo urlencode($ser), "\n";
var_dump(X::X->value);
?>
--EXPECT--
enum(X::X)
%00%00%00%02%17%01X%27%0E%00
string(8) "dynamicX"
PK 'j�\�]4s s tests/igbinary_034.phptnu �[��� --TEST--
Unserialize invalid random data
--SKIPIF--
<?php
if(!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
--FILE--
<?php
$datas = array(
87817,
-1,
array(1,2,3,"testing" => 10, "foo"),
true,
false,
0.187182,
"dakjdh98389\000",
null,
(object)array(1,2,3),
);
error_reporting(0);
foreach ($datas as $data) {
$str = igbinary_serialize($data);
$len = strlen($str);
for ($j = 0; $j < 200; $j++) {
for ($i = 0; $i < $len - 1; $i++) {
$sub = substr($str, 0, $i);
$sub .= mcrypt_create_iv(30, MCRYPT_DEV_URANDOM);
$php_errormsg = null;
$v = igbinary_unserialize($sub);
}
}
}
--EXPECT--
PK 'j�\�s�� � tests/igbinary_009.phptnu �[��� --TEST--
Check for reference serialisation
--SKIPIF--
<?php
if(!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
--FILE--
<?php
function test($type, $variable, $normalize = false) {
// Canonicalize $variable
if ($normalize) {
$variable = unserialize(serialize($variable));
}
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
$serialize_act = serialize($unserialized);
$serialize_exp = serialize($variable);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $serialize_act === $serialize_exp ? 'OK' : 'ERROR', "\n";
ob_start();
var_dump($variable);
$dump_exp = ob_get_clean();
ob_start();
var_dump($unserialized);
$dump_act = ob_get_clean();
if ($dump_act !== $dump_exp) {
echo "But var dump differs:\nActual:\n", $dump_act, "\nExpected\n", $dump_exp, "\n";
if ($normalize) {
echo "(Was normalized)\n";
}
}
if ($serialize_act !== $serialize_exp) {
echo "But serialize differs:\nActual:\n", $serialize_act, "\nExpected:\n", $serialize_exp, "\n";
}
}
$a = array('foo');
test('array($a, $a)', array($a, $a));
test('array(&$a, &$a)', array(&$a, &$a));
$a = array(null);
$b = array(&$a);
$a[0] = &$b;
test('cyclic $a = array(&array(&$a)) - normalized', $a, true);
--EXPECT--
array($a, $a)
14020600140106001103666f6f06010101
OK
array(&$a, &$a)
1402060025140106001103666f6f0601250101
OK
cyclic $a = array(&array(&$a)) - normalized
14010600251401060014010600250101
OK
PK 'j�\�&L�K K tests/igbinary_091.phptnu �[��� --TEST--
Check for handling of anonymous classes
--INI--
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
function check_serialize_throws($obj) {
try {
var_dump(serialize($obj));
} catch (Throwable $e) {
echo "Caught: " . $e->getMessage() . "\n";
}
}
check_serialize_throws(new class () {});
// TODO: Update behavior based on https://bugs.php.net/bug.php?id=81111
/**
check_serialize_throws(new class () {
public function __serialize() { return []; }
public function __unserialize($value) { }
});
*/
check_serialize_throws(new class () implements Serializable {
public function serialize() { return ''; }
public function unserialize($ser) { return new self(); }
});
?>
--EXPECTF--
Caught: Serialization of 'class@anonymous' is not allowed
Caught: Serialization of '%s@anonymous' is not allowed
PK (j�\�*f f tests/igbinary_021.phptnu �[��� --TEST--
Object Serializable interface
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $test || $unserialized == $variable ? 'OK' : 'ERROR';
echo "\n";
}
class Obj implements Serializable {
var $a;
var $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function serialize() {
return pack('NN', $this->a, $this->b);
}
public function unserialize($serialized) {
$tmp = unpack('N*', $serialized);
$this->__construct($tmp[1], $tmp[2]);
}
}
$o = new Obj(1, 2);
test('object', $o, false);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
object
17034f626a1d080000000100000002
OK
PK (j�\��̝ � tests/igbinary_055.phptnu �[��� --TEST--
__wakeup can replace a copy of the object referring to the root node.
--FILE--
<?php
#[AllowDynamicProperties]
class Obj {
function __construct($a) {
$this->a = $a;
}
public function __wakeup() {
echo "Calling __wakeup\n";
$this->a = "replaced";
}
}
$a = new stdClass();
$a->obj = new Obj($a);;
$serialized = igbinary_serialize($a);
printf("%s\n", bin2hex($serialized));
$unserialized = igbinary_unserialize($serialized);
var_dump($unserialized);
--EXPECTF--
000000021708737464436c617373140111036f626a17034f626a14011101612200
Calling __wakeup
object(stdClass)#%d (1) {
["obj"]=>
object(Obj)#%d (1) {
["a"]=>
string(8) "replaced"
}
}
PK )j�\���� � tests/__serialize_006.phptnu �[��� --TEST--
__serialize() mechanism (006): DateTime
--SKIPIF--
<?php if (PHP_VERSION_ID < 70400) { echo "skip __serialize/__unserialize not supported in php < 7.4 for compatibility with serialize()"; } ?>
--FILE--
<?php
$dt = new DateTime('2019-12-08 12:34', new DateTimeZone('UTC'));
var_dump(bin2hex($s = igbinary_serialize($dt)));
var_dump(igbinary_unserialize($s));
$dt = new DateTime('2019-12-08 12:34', new DateTimeZone('Pacific/Nauru'));
var_dump(bin2hex($s = igbinary_serialize($dt)));
var_dump(igbinary_unserialize($s));
?>
--EXPECT--
string(164) "0000000217084461746554696d651403110464617465111a323031392d31322d30382031323a33343a30302e303030303030110d74696d657a6f6e655f747970650603110874696d657a6f6e651103555443"
object(DateTime)#2 (3) {
["date"]=>
string(26) "2019-12-08 12:34:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
string(184) "0000000217084461746554696d651403110464617465111a323031392d31322d30382031323a33343a30302e303030303030110d74696d657a6f6e655f747970650603110874696d657a6f6e65110d506163696669632f4e61757275"
object(DateTime)#1 (3) {
["date"]=>
string(26) "2019-12-08 12:34:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Pacific/Nauru"
}
PK )j�\�2� � tests/igbinary_002.phptnu �[��� --TEST--
Check for null serialisation
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $unserialized === $variable ? 'OK' : 'ERROR';
echo "\n";
}
test('null', null);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*/
?>
--EXPECT--
null
00
OK
PK )j�\ŋ9�% % tests/igbinary_bug54662.phptnu �[��� --TEST--
Nested objects cause segfault, php bug #54662
--SKIPIF--
<?php if (!extension_loaded("igbinary")) print "skip"; ?>
--FILE--
<?php
/**
* Proof of concept, segmentation fault (spl_array.c/igbinary.c)
* when using nested objects.
*
* @author Aleksey Korzun
*/
class Storage {
public $storage = "a string";
}
$collection = new ArrayObject;
$collection->append(new Storage);
$ser = igbinary_serialize($collection);
$new_collection = igbinary_unserialize($ser);
var_dump($new_collection[0]->storage);
--EXPECT--
string(8) "a string"
PK *j�\nX�� tests/igbinary_072.phptnu �[��� --TEST--
igbinary and __PHP_INCOMPLETE_CLASS
--FILE--
<?php
// TODO: Remove temporary workaround for __PHP_Incomplete_Class missing #[AllowDynamicProperties]
if (PHP_VERSION_ID >= 80200) { require_once __DIR__ . '/php82_suppress_dynamic_properties_warning.inc'; }
class Test {}
function test_ser_unser($obj) {
var_dump(bin2hex($s = igbinary_serialize($obj)));
$s = str_replace('Test', 'Best', $s);
$obj2 = igbinary_unserialize($s);
var_dump($obj2);
var_dump(bin2hex($s = igbinary_serialize($obj2)));
var_dump(igbinary_unserialize($s));
}
test_ser_unser(new Test());
echo "Testing with properties\n";
$obj = new Test();
$obj->dynamicProp = 'value';
$obj->nullProp = null;
test_ser_unser($obj);
?>
--EXPECT--
string(24) "000000021704546573741400"
object(__PHP_Incomplete_Class)#2 (1) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "Best"
}
string(24) "000000021704426573741400"
object(__PHP_Incomplete_Class)#3 (1) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "Best"
}
Testing with properties
string(86) "000000021704546573741402110b64796e616d696350726f70110576616c756511086e756c6c50726f7000"
object(__PHP_Incomplete_Class)#1 (3) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "Best"
["dynamicProp"]=>
string(5) "value"
["nullProp"]=>
NULL
}
string(86) "000000021704426573741402110b64796e616d696350726f70110576616c756511086e756c6c50726f7000"
object(__PHP_Incomplete_Class)#3 (3) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "Best"
["dynamicProp"]=>
string(5) "value"
["nullProp"]=>
NULL
}PK *j�\0�Q� � tests/igbinary_010.phptnu �[��� --TEST--
Array test
--SKIPIF--
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($type, $variable, $test) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $test || $unserialized == $variable ? 'OK' : 'ERROR';
echo "\n";
}
$a = array(
'a' => array(
'b' => 'c',
'd' => 'e'
),
'f' => array(
'g' => 'h'
)
);
test('array', $a, false);
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
array
140211016114021101621101631101641101651101661401110167110168
OK
PK +j�\����3 3 tests/igbinary_041.phptnu �[��� --TEST--
Check for double NaN, Inf, -Inf, 0, and -0. IEEE 754 doubles
--FILE--
<?php
function str2bin($bytestring) {
$len = strlen($bytestring);
$output = '';
for ($i = 0; $i < $len; $i++) {
$bin = decbin(ord($bytestring[$i]));
$bin = str_pad($bin, 8, '0', STR_PAD_LEFT);
$output .= $bin;
}
return $output;
}
function test($type, $variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, ":\n";
var_dump($variable);
var_dump($unserialized);
echo " 6 5 4 3 2 1\n";
echo "3210987654321098765432109876543210987654321098765432109876543210\n";
echo str2bin(substr($serialized, 5, 8)), "\n";
echo "\n";
}
// exponent all-1, non zero mantissa
test('double NaN', NAN);
// sign 0, exp all-1, zero mantissa
test('double Inf', INF);
// sign 1, exp all-1, zero mantissa
test('double -Inf', -INF);
// sign 0, all-0
test('double 0.0', 0.0);
// sign 1, all-0
test('double -0.0', -1 * 0.0);
--EXPECTREGEX--
double NaN:
float\(NAN\)
float\(NAN\)
6 5 4 3 2 1
3210987654321098765432109876543210987654321098765432109876543210
.111111111110*1.*
double Inf:
float\(INF\)
float\(INF\)
6 5 4 3 2 1
3210987654321098765432109876543210987654321098765432109876543210
0111111111110000000000000000000000000000000000000000000000000000
double -Inf:
float\(-INF\)
float\(-INF\)
6 5 4 3 2 1
3210987654321098765432109876543210987654321098765432109876543210
1111111111110000000000000000000000000000000000000000000000000000
double 0.0:
float\(0\)
float\(0\)
6 5 4 3 2 1
3210987654321098765432109876543210987654321098765432109876543210
0000000000000000000000000000000000000000000000000000000000000000
double -0.0:
float\(-0\)
float\(-0\)
6 5 4 3 2 1
3210987654321098765432109876543210987654321098765432109876543210
1000000000000000000000000000000000000000000000000000000000000000
PK +j�\N�.�{ { tests/igbinary_032.phptnu �[��� --TEST--
Object test, __sleep and __wakeup exceptions
--SKIPIF--
<?php
if(!extension_loaded('igbinary')) {
echo "skip no igbinary";
}
--FILE--
<?php
function test($variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
}
class Obj {
private static $count = 0;
var $a;
var $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
function __sleep() {
$c = self::$count++;
if ($this->a) {
throw new Exception("exception in __sleep $c");
}
return array('a', 'b');
}
function __wakeup() {
$c = self::$count++;
if ($this->b) {
throw new Exception("exception in __wakeup $c");
}
$this->b = $this->a * 3;
}
}
$a = new Obj(1, 0);
$b = new Obj(0, 1);
$c = new Obj(0, 0);
try {
test($a);
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
try {
test($b);
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
try {
test($c);
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
/*
* you can add regression tests for your extension here
*
* the output of your test code has to be equal to the
* text in the --EXPECT-- section below for the tests
* to pass, differences between the output and the
* expected text are interpreted as failure
*
* see TESTING.md for further information on
* writing regression tests
*/
?>
--EXPECT--
exception in __sleep 0
exception in __wakeup 2
PK +j�\^�-X� � tests/igbinary_052.phptnu �[��� --TEST--
Object Serializable interface can be serialized in references
--INI--
; Note that php 8.1 deprecates using Serializable without __serialize/__unserialize but we are testing Serialize for igbinary. Suppress deprecations.
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php
if(!extension_loaded('igbinary')) {
dl('igbinary.' . PHP_SHLIB_SUFFIX);
}
function test($variable) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
}
class Obj implements Serializable {
private static $count = 1;
public $a;
public $b;
function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function serialize() {
$c = self::$count++;
echo "call serialize\n";
return pack('NN', $this->a, $this->b);
}
public function unserialize($serialized) {
$tmp = unpack('N*', $serialized);
$this->__construct($tmp[1], $tmp[2]);
$c = self::$count++;
echo "call unserialize\n";
}
}
function main() {
$a = new Obj(1, 0);
$b = new Obj(42, 43);
$variable = array(&$a, &$a, $b);
$serialized = igbinary_serialize($variable);
printf("%s\n", bin2hex($serialized));
$unserialized = igbinary_unserialize($serialized);
var_dump($unserialized);
$unserialized[0] = 'A';
var_dump($unserialized[1]);
}
main();
--EXPECTF--
call serialize
call serialize
00000002140306002517034f626a1d080000000100000000060125220106021a001d080000002a0000002b
call unserialize
call unserialize
array(3) {
[0]=>
&object(Obj)#%d (2) {
["a"]=>
int(1)
["b"]=>
int(0)
}
[1]=>
&object(Obj)#%d (2) {
["a"]=>
int(1)
["b"]=>
int(0)
}
[2]=>
object(Obj)#%d (2) {
["a"]=>
int(42)
["b"]=>
int(43)
}
}
string(1) "A"
PK ,j�\�H�4 4 tests/typed_property_refs.phptnu �[��� --TEST--
unserialize with references to typed properties shall skip the references or fail
--SKIPIF--
<?php if (PHP_VERSION_ID < 80000) die("skip requires php 8.0+"); ?>
--FILE--
<?php
class X {
public $a;
public $b;
}
class A {
public int $a;
public $b;
}
class B {
public $a;
public int $b;
}
class E {
public $a;
public int $b;
}
class C {
public int $a;
public string $b;
}
class D {
public int $a;
public float $b;
}
function create_ser($value): string {
$v = new X();
$v->a = $value;
$v->b = &$v->a;
$ser = igbinary_serialize($v);
printf("for %s: %s\n", var_export($value, true), urlencode($ser));
return $ser;
}
$serInt = create_ser(1);
$serNull = create_ser(null);
$serStr = create_ser('x');
var_dump(igbinary_unserialize(str_replace('X', 'A', $serInt)));
var_dump(igbinary_unserialize(str_replace('X', 'B', $serInt)));
var_dump(igbinary_unserialize(str_replace('X', 'E', $serInt)));
try {
var_dump(igbinary_unserialize(str_replace('X', 'A', $serNull)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'B', $serNull)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'C', $serInt)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'C', $serStr)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(igbinary_unserialize(str_replace('X', 'D', $serInt)));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
for 1: %00%00%00%02%17%01X%14%02%11%01a%25%06%01%11%01b%25%01%01
for NULL: %00%00%00%02%17%01X%14%02%11%01a%25%00%11%01b%25%01%01
for 'x': %00%00%00%02%17%01X%14%02%11%01a%25%11%01x%11%01b%25%01%01
object(A)#1 (2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
object(B)#1 (2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
object(E)#1 (2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
Cannot assign null to property A::$a of type int
Cannot assign null to property B::$b of type int
Cannot assign int to property C::$b of type string
Cannot assign string to property C::$a of type int
Reference with value of type int held by property D::$a of type int is not compatible with property D::$b of type float
PK ,j�\��� � tests/igbinary_094.phptnu �[��� --TEST--
Test refusing to serialize/unserialize unserializable internal classes
--INI--
error_reporting=E_ALL
--SKIPIF--
<?php
if (PHP_VERSION_ID < 70400) { echo "skip CURLFile serialization forbidden in php 7.4, test requires 7.4+\n"; }
if (!extension_loaded('curl')) { echo "skip requires curl\n"; }
?>
--FILE--
<?php
// https://bugs.php.net/bug.php?id=81111
function check_serialize_throws($obj) {
try {
echo urlencode(igbinary_serialize($obj)), "\n";
} catch (Throwable $e) {
echo "Caught: " . $e->getMessage() . "\n";
}
}
class Something extends CURLFile {
public function __serialize() { return []; }
public function __unserialize($value) { return new self('file'); }
}
check_serialize_throws(new CURLFile('file'));
check_serialize_throws(new Something('file'));
?>
--EXPECTF--
Caught: Serialization of 'CURLFile' is not allowed
Caught: Serialization of 'Something' is not allowed
PK ,j�\j3��� � tests/igbinary_023.phptnu �[��� --TEST--
Resource
--SKIPIF--
<?php
if (!extension_loaded("igbinary")) print "skip extension not loaded\n";
--FILE--
<?php
function test($type, $variable, $test) {
$serialized = igbinary_serialize($variable);
$unserialized = igbinary_unserialize($serialized);
echo $type, "\n";
echo substr(bin2hex($serialized), 8), "\n";
echo $test || $unserialized === null ? 'OK' : 'FAIL';
echo "\n";
}
$res = tmpfile();
test('resource', $res, false);
fclose($res);
test('resource', $res, false);
--EXPECTF--
Deprecated: igbinary_serialize(): Cannot serialize resource(stream) and resources may be converted to objects that cannot be serialized in future php releases. Serializing the value as null instead in %sigbinary_023.php on line 4
resource
00
OK
Deprecated: igbinary_serialize(): Cannot serialize resource(Unknown) and resources may be converted to objects that cannot be serialized in future php releases. Serializing the value as null instead in %sigbinary_023.php on line 4
resource
00
OK
PK -j�\�<h�O O tests/igbinary_078.phptnu �[��� --TEST--
igbinary and large arrays
--FILE--
<?php
class BadSleep {
public $prop = 'x';
public function __construct($value) {
$this->prop = $value;
}
public function __sleep() {
return null;
}
}
var_dump(bin2hex($s = igbinary_serialize(new BadSleep('override'))));
var_dump(igbinary_unserialize($s));
?>
--EXPECTF--
Notice: igbinary_serialize(): __sleep should return an array only containing the names of instance-variables to serialize in %s on line %d
string(32) "000000021708426164536c6565701400"
object(BadSleep)#1 (1) {
["prop"]=>
string(1) "x"
}PK -j�\2� '