Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
--TEST--
unserialize_callback_func with partially deprecated callable string
--INI--
unserialize_callback_func=parent::my_unserialize
--FILE--
<?php

class TesterParent {
public static function my_unserialize($name) {
echo 'callback_called in ', __CLASS__ , PHP_EOL;
eval('class Foo {}');
}
}

class TesterChild extends TesterParent {
public static function my_unserialize($name) {
echo 'callback_called in ', __CLASS__ , PHP_EOL;
eval('class Foo {}');
}

public function unserialize(string $str) {
return unserialize($str);
}
}

$s = 'O:3:"FOO":0:{}';
try {
$o = unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}

try {
$tester = new TesterChild();
$o = $tester->unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
echo "Done";

?>
--EXPECTF--
Error: Invalid callback parent::my_unserialize, cannot access "parent" when no class scope is active

Deprecated: Use of "parent" in callables is deprecated in %s on line %d
callback_called in TesterParent
object(Foo)#3 (0) {
}
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
unserialize_callback_func with fully qualified name function
--INI--
unserialize_callback_func=\my_global_fn
--FILE--
<?php
function my_global_fn($name) {
echo "callback_called\n";
eval('class Foo {}');
}

$o = unserialize('O:3:"FOO":0:{}');

var_dump($o);

echo "Done";
?>
--EXPECT--
callback_called
object(Foo)#1 (0) {
}
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
unserialize_callback_func with fully qualified named namespaced function
--INI--
unserialize_callback_func=\php\test\my_global_fn
--FILE--
<?php

namespace php\test {
function my_global_fn($name) {
echo "callback_called\n";
eval('class Foo {}');
}
}
namespace {
$o = unserialize('O:3:"FOO":0:{}');

var_dump($o);

echo "Done";
}
?>
--EXPECT--
callback_called
object(Foo)#1 (0) {
}
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
unserialize_callback_func with function name containing null bytes
--FILE--
<?php

ini_set('unserialize_callback_func', "foo\0butno");

function foo(string $name) {
echo "callback_called\n";
eval('class Foo {}');
}

$s = 'O:3:"FOO":0:{}';
try {
$o = unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}

echo "Done";
?>
--EXPECT--
Error: Invalid callback foo, function "foo" not found or invalid function name
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
unserialize_callback_func with private non-static method
--INI--
unserialize_callback_func=Tester::my_unserialize
--FILE--
<?php

class Tester {
private function my_unserialize($name) {
echo "callback_called\n";
eval('class Foo {}');
}

public function unserialize(string $str) {
return unserialize($str);
}
}

$s = 'O:3:"FOO":0:{}';
try {
$o = unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}

try {
$tester = new Tester();
$o = $tester->unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
echo "Done";

?>
--EXPECT--
Error: Invalid callback Tester::my_unserialize, non-static method Tester::my_unserialize() cannot be called statically
callback_called
object(Foo)#3 (0) {
}
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
unserialize_callback_func with public non-static method
--INI--
unserialize_callback_func=Tester::my_unserialize
--FILE--
<?php

class Tester {
public function my_unserialize($name) {
echo "callback_called\n";
eval('class Foo {}');
}

public function unserialize(string $str) {
return unserialize($str);
}
}

$s = 'O:3:"FOO":0:{}';
try {
$o = unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}

try {
$tester = new Tester();
$o = $tester->unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
echo "Done";

?>
--EXPECT--
Error: Invalid callback Tester::my_unserialize, non-static method Tester::my_unserialize() cannot be called statically
callback_called
object(Foo)#3 (0) {
}
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
unserialize_callback_func with public static method
--INI--
unserialize_callback_func=Tester::my_unserialize
--FILE--
<?php

class Tester {
public static function my_unserialize($name) {
echo "callback_called\n";
eval('class Foo {}');
}
}

$o = unserialize('O:3:"FOO":0:{}');

var_dump($o);

echo "Done";

?>
--EXPECT--
callback_called
object(Foo)#1 (0) {
}
Done
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
unserialize_callback_func with private static method
--INI--
unserialize_callback_func=Tester::my_unserialize
--FILE--
<?php

class Tester {
private static function my_unserialize($name) {
echo "callback_called\n";
eval('class Foo {}');
}

public static function unserialize(string $str) {
return unserialize($str);
}
}

$s = 'O:3:"FOO":0:{}';
try {
$o = unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}

try {
$o = Tester::unserialize($s);
var_dump($o);
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
echo "Done";

?>
--EXPECT--
Error: Invalid callback Tester::my_unserialize, cannot access private method Tester::my_unserialize()
callback_called
object(Foo)#2 (0) {
}
Done
2 changes: 1 addition & 1 deletion ext/standard/var_unserializer.re
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ object ":" uiv ":" ["] {
}

/* Call unserialize callback */
ZVAL_STR_COPY(&user_func, PG(unserialize_callback_func));
ZVAL_STR(&user_func, zend_string_dup(PG(unserialize_callback_func), false));
Comment thread
Girgias marked this conversation as resolved.

ZVAL_STR(&args[0], class_name);
BG(serialize_lock)++;
Expand Down
Loading