/home/fresvfqn/waterdamagerestorationgerritsenbeach.com/alt-php80-pecl-luasandbox_4.1.2-2.el8.tar
tests/ipairs.phpt 0000644 00000003034 15055745140 0010100 0 ustar 00 --TEST--
ipairs() and __ipairs
--FILE--
<?php
$lua = <<<LUA
function ipairs_test1()
local t = { 'a' }
local f, s, var = ipairs( t )
if type( f ) == 'function' and s == t and var == 0 then
local k, v = f(t, var)
if k == 1 and v == 'a' then
return "Ok"
else
return "Fail: First call returned " .. k .. "\\t" .. v
end
else
return "Fail:\\n" ..
tostring(f) .. '\\t' .. tostring(s) .. '\\t' .. tostring(var) .. '\\n' ..
tostring(next) .. '\\t' .. tostring(t) .. '\\t0'
end
end
function ipairs_test2()
local t = { 1 }
setmetatable( t, { __ipairs = function () return 1, 2, 3 end } )
local f, s, var = ipairs( t )
if f == 1 and s == 2 and var == 3 then
return "Ok"
else
return "Fail:\\n" ..
tostring(f) .. '\\t' .. tostring(s) .. '\\t' .. tostring(var) .. '\\n' ..
'1\\t2\\t3'
end
end
function ipairs_test3()
ipairs()
return "Fail: Should have thrown an error"
end
LUA;
$tests = array(
'Normal' => 'ipairs_test1',
'With __ipairs' => 'ipairs_test2',
'No argument' => 'ipairs_test3',
);
foreach ( $tests as $desc => $func ) {
echo "$desc: ";
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->setCPULimit( 0.25 );
$sandbox->setMemoryLimit( 100000 );
try {
print implode("\n", $sandbox->callFunction( $func ) ) . "\n";
} catch ( LuaSandboxError $e ) {
echo "LuaSandboxError: " . $e->getMessage() . "\n";
}
}
--EXPECT--
Normal: Ok
With __ipairs: Ok
No argument: LuaSandboxError: [string ""]:32: bad argument #1 to 'ipairs' (table expected, got no value)
tests/dump_loadBinary_call.phpt 0000644 00000000611 15055745140 0012713 0 ustar 00 --TEST--
dump -> loadBinary -> call
--FILE--
<?php
var_dump( $sandbox = new LuaSandbox );
var_dump( $f = $sandbox->loadString( 'return 1' ) );
$dump = $f->dump();
var_dump( $restore = $sandbox->loadBinary( $dump ) );
var_dump( $restore->call() );
--EXPECT--
object(LuaSandbox)#1 (0) {
}
object(LuaSandboxFunction)#2 (0) {
}
object(LuaSandboxFunction)#3 (0) {
}
array(1) {
[0]=>
int(1)
}
tests/datatypes-unsupported.phpt 0000644 00000005440 15055745140 0013200 0 ustar 00 --TEST--
Handling of unsupported datatypes
--FILE--
<?php
function doTest( $test, $data ) {
printf( "%s ", "$test (call PHP->Lua):" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
try {
$ret = $sandbox->loadString( 'return 1' )->call( $data );
printf( "%s\n", preg_replace( '/\s+/', ' ', var_export( $ret, 1 ) ) );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
printf( "%s ", "$test (return PHP->Lua):" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
$f = $sandbox->wrapPhpFunction( function () use ( $data ) {
return [ $data ];
} );
try {
$sandbox->loadString( 'local f = ...; f()' )->call( $f );
printf( "%s\n", preg_replace( '/\s+/', ' ', var_export( $ret, 1 ) ) );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
}
function doTest2( $test, $lua ) {
printf( "%s ", "$test (call Lua->PHP):" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
$f = $sandbox->wrapPhpFunction( function ( $val ) {
echo "PHP received " . preg_replace( '/\s+/', ' ', var_export( $val, 1 ) ) . "\n";
} );
try {
$sandbox->loadString( "local f = ...\n$lua\nf(v)" )->call( $f );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
printf( "%s ", "$test (return Lua->PHP):" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
try {
$ret = $sandbox->loadString( "$lua\nreturn v" )->call();
printf( "%s\n", preg_replace( '/\s+/', ' ', var_export( $ret, 1 ) ) );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
}
$test = array();
$test['foo'] = &$test;
doTest( 'recursive array', $test );
$test = new stdClass;
doTest( 'object', $test );
doTest2( 'recursive table', 'v = {}; v.v = v' );
--EXPECTF--
recursive array (call PHP->Lua): %AWarning: LuaSandboxFunction::call(): Cannot pass circular reference to Lua in %s on line %d
%AWarning: LuaSandboxFunction::call(): unable to convert argument 1 to a lua value in %s on line %d
false
recursive array (return PHP->Lua): %AWarning: LuaSandboxFunction::call(): Cannot pass circular reference to Lua in %s on line %d
false
object (call PHP->Lua): %AWarning: LuaSandboxFunction::call(): Unable to convert object of type stdClass in %s on line %d
%AWarning: LuaSandboxFunction::call(): unable to convert argument 1 to a lua value in %s on line %d
false
object (return PHP->Lua): %AWarning: LuaSandboxFunction::call(): Unable to convert object of type stdClass in %s on line %d
false
recursive table (call Lua->PHP): EXCEPTION: Cannot pass circular reference to PHP
recursive table (return Lua->PHP): EXCEPTION: Cannot pass circular reference to PHP
tests/pcall.phpt 0000644 00000002425 15055745140 0007707 0 ustar 00 --TEST--
pcall() catching various errors
--FILE--
<?php
$lua = <<<LUA
function pcall_test(f)
local status, msg
status, msg = pcall(f)
if not status then
return "Caught: " .. msg
else
return "success"
end
end
LUA;
$tests = array(
'Normal' => 'return 1',
'User error' => 'error("runtime error")',
'Argument check error' => 'string.byte()',
'Infinite recursion' => 'function foo() foo() end foo()',
'Infinite loop (timeout)' => 'while true do end',
'Out of memory' => 'string.rep("x", 1000000)'
);
foreach ( $tests as $desc => $code ) {
echo "$desc: ";
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->setCPULimit( 0.25 );
$sandbox->setMemoryLimit( 100000 );
try {
print implode("\n",
$sandbox->callFunction( 'pcall_test', $sandbox->loadString( $code ) ) ) . "\n";
} catch ( LuaSandboxError $e ) {
echo "LuaSandboxError: " . $e->getMessage() . "\n";
}
}
--EXPECT--
Normal: success
User error: Caught: [string ""]:1: runtime error
Argument check error: Caught: [string ""]:1: bad argument #1 to 'byte' (string expected, got no value)
Infinite recursion: LuaSandboxError: not enough memory
Infinite loop (timeout): LuaSandboxError: The maximum execution time for this script was exceeded
Out of memory: LuaSandboxError: not enough memory
tests/call.phpt 0000644 00000012150 15055745140 0007523 0 ustar 00 --TEST--
LuaSandboxFunction::call
--FILE--
<?php
$sandbox = new LuaSandbox;
var_dump( $sandbox->loadString( 'return 1' )->call() );
echo "Proper handling of circular tables returned by Lua: ";
$sandbox = new LuaSandbox;
try {
$ret = $sandbox->loadString( 'local t = {}; t.t = t; return t' )->call();
echo var_export( $ret, 1 ) . "\n";
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
echo "Proper handling of circular tables in Lua→PHP call: ";
$sandbox = new LuaSandbox;
$f = $sandbox->wrapPhpFunction( function () {
echo func_num_args() . " args ok\n";
} );
try {
$sandbox->loadString( 'local f = ...; local t = {}; t.t = t; f( t )' )->call( $f );
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
echo "Passing lots of arguments PHP->Lua doesn't cause a crash: ";
$sandbox = new LuaSandbox;
$ret = call_user_func_array(
array( $sandbox->loadString( 'return select( "#", ... )' ), 'call' ),
array_fill( 0, 500, '' )
);
echo "$ret[0] args ok\n";
echo "Passing lots of arguments Lua->PHP doesn't cause a crash: ";
$sandbox = new LuaSandbox;
$f = $sandbox->wrapPhpFunction( function () {
echo func_num_args() . " args ok\n";
} );
$sandbox->loadString( 'local f = ...; f( string.byte( string.rep( "x", 500 ), 1, -1 ) )' )->call( $f );
echo "Returning lots of values PHP->Lua doesn't cause a crash: ";
$sandbox = new LuaSandbox;
$f = $sandbox->wrapPhpFunction( function () {
return array_fill( 0, 500, '' );
} );
$ret = $sandbox->loadString( 'local f = ...; return select( "#", f() )' )->call( $f );
echo "$ret[0] values ok\n";
echo "Returning lots of values Lua->PHP doesn't cause a crash: ";
$sandbox = new LuaSandbox;
$ret = $sandbox->loadString( 'return string.byte( string.rep( "x", 500 ), 1, -1 )' )->call();
echo count( $ret ) . " values ok\n";
echo "Passing deeply-nested arrays PHP->Lua doesn't cause a crash: ";
$sandbox = new LuaSandbox;
$v = 1;
for ( $i = 0; $i < 500; $i++ ) {
$v = array( $v );
}
$lua = <<<LUA
local ct, t = 0, ...
while type( t ) == "table" do
_, t = next( t )
ct = ct + 1
end
return ct
LUA;
$ret = $sandbox->loadString( $lua )->call( $v );
echo "$ret[0] levels ok\n";
echo "Passing deeply-nested tables Lua->PHP doesn't cause a crash: ";
$sandbox = new LuaSandbox;
$ret = $sandbox->loadString( 'local t = 1; for i = 1, 500 do t = { t } end; return t' )->call();
$ct = 0;
$v = $ret[0];
while ( is_array( $v ) ) {
$v = reset( $v );
$ct++;
}
echo "$ct levels ok\n";
echo "Proper handling of invalid keys in Lua→PHP conversion (table): ";
$sandbox = new LuaSandbox;
try {
$ret = $sandbox->loadString( 'return { [{}] = 1 }' )->call();
echo var_export( $ret[0], 1 ) . "\n";
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
echo "Proper handling of invalid keys in Lua→PHP conversion (bool): ";
$sandbox = new LuaSandbox;
try {
$ret = $sandbox->loadString( 'return { [true] = 1 }' )->call();
echo var_export( $ret[0], 1 ) . "\n";
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
echo "Proper handling of invalid keys in Lua→PHP conversion (function): ";
$sandbox = new LuaSandbox;
try {
$ret = $sandbox->loadString( 'return { [tostring] = 1 }' )->call();
echo var_export( $ret[0], 1 ) . "\n";
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
echo "Proper handling of unusual keys in Lua→PHP conversion (float): ";
$sandbox = new LuaSandbox;
try {
$ret = $sandbox->loadString( 'return { [1.5] = 1 }' )->call();
echo var_export( $ret[0], 1 ) . "\n";
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
echo "Proper handling of unusual keys in Lua→PHP conversion (inf): ";
$sandbox = new LuaSandbox;
try {
$ret = $sandbox->loadString( 'return { [math.huge] = 1 }' )->call();
echo var_export( $ret[0], 1 ) . "\n";
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
--EXPECT--
array(1) {
[0]=>
int(1)
}
Proper handling of circular tables returned by Lua: Exception: Cannot pass circular reference to PHP
Proper handling of circular tables in Lua→PHP call: Exception: Cannot pass circular reference to PHP
Passing lots of arguments PHP->Lua doesn't cause a crash: 500 args ok
Passing lots of arguments Lua->PHP doesn't cause a crash: 500 args ok
Returning lots of values PHP->Lua doesn't cause a crash: 500 values ok
Returning lots of values Lua->PHP doesn't cause a crash: 500 values ok
Passing deeply-nested arrays PHP->Lua doesn't cause a crash: 500 levels ok
Passing deeply-nested tables Lua->PHP doesn't cause a crash: 500 levels ok
Proper handling of invalid keys in Lua→PHP conversion (table): Exception: Cannot use table as an array key when passing data from Lua to PHP
Proper handling of invalid keys in Lua→PHP conversion (bool): Exception: Cannot use boolean as an array key when passing data from Lua to PHP
Proper handling of invalid keys in Lua→PHP conversion (function): Exception: Cannot use function as an array key when passing data from Lua to PHP
Proper handling of unusual keys in Lua→PHP conversion (float): array (
'1.5' => 1,
)
Proper handling of unusual keys in Lua→PHP conversion (inf): array (
'inf' => 1,
)
tests/extending-LuaSandbox.phpt 0000644 00000001515 15055745140 0012636 0 ustar 00 --TEST--
Extending LuaSandbox
--FILE--
<?php
// bugs T59292 and T205370
#[AllowDynamicProperties]
class ExtendedLuaSandbox extends LuaSandbox {
public $var1;
public $var2;
public $var3;
public $var4;
public $var5;
}
$sandbox = new ExtendedLuaSandbox;
for($i=1; $i<=5; $i++){
$sandbox->{"var$i"} = $i;
}
var_dump( $sandbox );
for($i=6; $i<=10; $i++){
$sandbox->{"var$i"} = $i;
}
var_dump( $sandbox );
echo "ok\n";
--EXPECT--
object(ExtendedLuaSandbox)#1 (5) {
["var1"]=>
int(1)
["var2"]=>
int(2)
["var3"]=>
int(3)
["var4"]=>
int(4)
["var5"]=>
int(5)
}
object(ExtendedLuaSandbox)#1 (10) {
["var1"]=>
int(1)
["var2"]=>
int(2)
["var3"]=>
int(3)
["var4"]=>
int(4)
["var5"]=>
int(5)
["var6"]=>
int(6)
["var7"]=>
int(7)
["var8"]=>
int(8)
["var9"]=>
int(9)
["var10"]=>
int(10)
}
ok
tests/array-key-conversion.phpt 0000644 00000006154 15055745140 0012706 0 ustar 00 --TEST--
Array key conversion
--FILE--
<?php
function testPhpToLua( $test, $array ) {
printf( "PHP→Lua %-30s ", "$test:" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
try {
$ret = $sandbox
->loadString( 'local t, r = ..., {}; for k, v in pairs( t ) do r[v] = type(k) end return r' )
->call( $array );
if ( is_array( $ret[0] ) ) {
ksort( $ret[0], SORT_STRING );
}
printf( "%s\n", preg_replace( '/\s+/', ' ', var_export( $ret[0], 1 ) ) );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
}
function testLuaToPhp( $test, $lua ) {
printf( "Lua→PHP %-30s ", "$test:" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
try {
$ret = $sandbox->loadString( "return { $lua }" )->call();
if ( is_array( $ret[0] ) ) {
ksort( $ret[0], SORT_STRING );
}
printf( "%s\n", preg_replace( '/\s+/', ' ', var_export( $ret[0], 1 ) ) );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
}
if ( PHP_INT_MAX > 9007199254740992 ) {
$a = [
'9007199254740992' => 'max', '9007199254740993' => 'max+1',
'-9007199254740992' => 'min', '-9007199254740993' => 'min-1',
];
$max = '9223372036854775807';
$max2 = '9223372036854775808';
$min = '-9223372036854775808';
$min2 = '-9223372036854775809';
} else {
$a = [
'2147483647' => 'max', '2147483648' => 'max+1',
'-2147483648' => 'min', '-2147483649' => 'min-1',
];
$max = '2147483647';
$max2 = '2147483648';
$min = '-2147483648';
$min2 = '-2147483649';
}
testPhpToLua( 'simple integers', [ -10 => 'minus ten', 0 => 'zero', 10 => 'ten' ] );
testPhpToLua( 'maximal values', $a );
testLuaToPhp( 'simple integers', '[-10] = "minus ten", [0] = "zero", [10] = "ten"' );
testLuaToPhp( 'stringified integers', '["-10"] = "minus ten", ["0"] = "zero", ["10"] = "ten"' );
testLuaToPhp( 'maximal integers', "['$max'] = 'max', ['$max2'] = 'max+1', ['$min'] = 'min', ['$min2'] = 'min-1'" );
testLuaToPhp( 'collision (0)', '[0] = "number zero", ["0"] = "string zero"' );
testLuaToPhp( 'collision (float)', '[1.5] = "number 1.5", ["1.5"] = "string 1.5"' );
testLuaToPhp( 'collision (inf)', '[1/0] = "number inf", ["inf"] = "string inf"' );
--EXPECTF--
PHP→Lua simple integers: array ( 'minus ten' => 'number', 'ten' => 'number', 'zero' => 'number', )
PHP→Lua maximal values: array ( 'max' => 'number', 'max+1' => 'string', 'min' => 'number', 'min-1' => 'string', )
Lua→PHP simple integers: array ( -10 => 'minus ten', 0 => 'zero', 10 => 'ten', )
Lua→PHP stringified integers: array ( -10 => 'minus ten', 0 => 'zero', 10 => 'ten', )
Lua→PHP maximal integers: array ( -%d => 'min', '-%d' => 'min-1', %d => 'max', '%d' => 'max+1', )
Lua→PHP collision (0): EXCEPTION: Collision for array key 0 when passing data from Lua to PHP
Lua→PHP collision (float): EXCEPTION: Collision for array key 1.5 when passing data from Lua to PHP
Lua→PHP collision (inf): EXCEPTION: Collision for array key inf when passing data from Lua to PHP
tests/profiler.phpt 0000644 00000003054 15055745140 0010435 0 ustar 00 --TEST--
profiler
--FILE--
<?php
// Note these tests have to waste CPU cycles rather than sleep(), because the
// timer counts CPU time used and sleep() doesn't use CPU time.
$lua = <<<LUA
lua = {}
function lua.test()
local t = os.clock() + 0.2
while os.clock() < t do end
end
LUA;
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->enableProfiler( 0.02 );
$sandbox->callFunction( 'lua.test' );
echo "Samples: " . $sandbox->getProfilerFunctionReport( LuaSandbox::SAMPLES )['clock'] . "\n";
echo "Seconds: " . $sandbox->getProfilerFunctionReport( LuaSandbox::SECONDS )['clock'] . "\n";
echo "Seconds > 0: "
. ( $sandbox->getProfilerFunctionReport( LuaSandbox::SECONDS )['clock'] > 0 ? 'yes' : 'no' )
. "\n";
echo "Percent: " . $sandbox->getProfilerFunctionReport( LuaSandbox::PERCENT )['clock'] . "\n";
// Test that re-enabling the profiler doesn't explode
$sandbox->enableProfiler( 0.03 );
$sandbox->callFunction( 'lua.test' );
echo "Samples: " . $sandbox->getProfilerFunctionReport( LuaSandbox::SAMPLES )['clock'] . "\n";
echo "Seconds: " . $sandbox->getProfilerFunctionReport( LuaSandbox::SECONDS )['clock'] . "\n";
echo "Seconds > 0: "
. ( $sandbox->getProfilerFunctionReport( LuaSandbox::SECONDS )['clock'] > 0 ? 'yes' : 'no' )
. "\n";
echo "Percent: " . $sandbox->getProfilerFunctionReport( LuaSandbox::PERCENT )['clock'] . "\n";
// Test that disabling the profiler doesn't explode
$sandbox->disableProfiler();
--EXPECTF--
Samples: %d
Seconds: %f
Seconds > 0: yes
Percent: %f
Samples: %d
Seconds: %f
Seconds > 0: yes
Percent: %f
tests/callback_exception.phpt 0000644 00000000610 15055745140 0012420 0 ustar 00 --TEST--
Exception in a PHP function called from Lua
--FILE--
<?php
function throw_exception() {
throw new Exception('message');
}
$sandbox = new LuaSandbox;
$sandbox->registerLibrary( 'test', array( 'throw_exception' => 'throw_exception' ) );
$f = $sandbox->loadString('test.throw_exception()');
try {
$f->call();
} catch ( Exception $e ) {
print $e->getMessage();
}
--EXPECT--
message
tests/reentrant.phpt 0000644 00000002147 15055745140 0010617 0 ustar 00 --TEST--
Re-entering Lua during a callback to PHP
--FILE--
<?php
$sandbox = new LuaSandbox;
$chunk = $sandbox->loadString('
function factorial(n)
if n <= 1 then
return 1
else
return n * test.factorial(n - 1)
end
end
return factorial
');
$ret = $chunk->call();
$luaFactorial = $ret[0];
$sandbox->registerLibrary( 'test', array( 'factorial' => 'factorial' ) );
function factorial($n) {
global $luaFactorial;
if ($n <= 1) {
return array(1);
} else {
$ret = $luaFactorial->call($n - 1);
return array($n * $ret[0]);
}
}
print implode('', factorial(10)) . "\n";
var_dump( $luaFactorial->call(10) );
try {
$luaFactorial->call(1000000000);
} catch ( LuaSandboxError $e ) {
print $e->getMessage() . "\n";
}
try {
factorial(1000000000);
} catch ( LuaSandboxError $e ) {
print $e->getMessage() . "\n";
}
--EXPECTF--
3628800
array(1) {
[0]=>
int(3628800)
}
%AWarning: LuaSandboxFunction::call(): Failed to generate Lua trace (C stack overflow) in %s on line %d
C stack overflow
%AWarning: LuaSandboxFunction::call(): Failed to generate Lua trace (C stack overflow) in %s on line %d
C stack overflow
tests/lua_catches_php_exception.phpt 0000644 00000002532 15055745140 0014013 0 ustar 00 --TEST--
PHP throwing exceptions to be caught by pcall()
--FILE--
<?php
$lua = <<<LUA
function pcall_test(f)
local status, msg
status, msg = pcall(f)
if not status then
return "Caught: " .. msg
else
return "success"
end
end
function hang_test(f)
pcall_test(f)
while true do end
end
LUA;
function runtime_error() {
throw new LuaSandboxRuntimeError("runtime error");
}
function fatal_error() {
throw new LuaSandboxFatalError("fatal error");
}
function plain_exception() {
throw new Exception("exception");
}
$tests = array(
'Runtime error' => array( 'pcall_test', 'runtime_error' ),
'Fatal error' => array( 'hang_test', 'fatal_error' ),
'Plain Exception' => array( 'hang_test', 'plain_exception' ),
);
foreach ( $tests as $desc => $info ) {
list( $wrapper, $funcName ) = $info;
echo "$desc: ";
try {
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->setCPULimit( 0.25 );
$sandbox->registerLibrary( 'test', array( 'test' => $funcName ) );
$res = $sandbox->loadString( 'return test.test' )->call();
print implode("\n",
$sandbox->callFunction( $wrapper, $res[0] ) ) . "\n";
} catch ( Exception $e ) {
echo get_class( $e ) . ': ' . $e->getMessage() . "\n";
}
}
--EXPECT--
Runtime error: Caught: runtime error
Fatal error: LuaSandboxFatalError: fatal error
Plain Exception: Exception: exception
tests/loadString.phpt 0000644 00000000516 15055745140 0010721 0 ustar 00 --TEST--
loadString 1
--FILE--
<?php
var_dump($sandbox = new LuaSandbox);
var_dump($f = $sandbox->loadString('foo()'));
try {
$f = $sandbox->loadString('foo');
} catch( Exception $e ) {
print $e->getMessage();
}
--EXPECTF--
object(LuaSandbox)#1 (0) {
}
object(LuaSandboxFunction)#2 (0) {
}
[string ""]:1: '=' expected near '<eof>'
tests/profiler-sorting.phpt 0000644 00000002267 15055745140 0012125 0 ustar 00 --TEST--
profiler sorting
--FILE--
<?php
// Note these tests have to busy-loop. Even if Lua had an "os.sleep", it'd just
// say "sleep" used all the time. And we can't directly loop on os.clock() here
// either, because that would say "clock" used most of the time.
$lua = <<<LUA
function test1()
for i = 0, 1e6 do end
end
function test2()
for i = 0, 4e6 do end
end
function test3()
for i = 0, 2e6 do end
end
function test()
local t = os.clock() + 0.5
while os.clock() < t do
test1()
test2()
test3()
end
end
LUA;
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->enableProfiler( 0.01 );
$sandbox->callFunction( 'test' );
foreach( [
'samples' => LuaSandbox::SAMPLES,
'seconds' => LuaSandbox::SECONDS,
'percent' => LuaSandbox::PERCENT
] as $name => $stat ) {
$result = $sandbox->getProfilerFunctionReport( $stat );
// "clone" and sort
$sorted = array_combine( array_keys( $result ), array_values( $result ) );
arsort( $sorted );
if ( $result === $sorted ) {
echo "$name: OK\n";
} else {
echo "$name: FAIL\n";
var_export( [
'result' => $result,
'sorted' => $sorted,
] );
}
}
--EXPECTF--
samples: OK
seconds: OK
percent: OK
tests/datatypes.phpt 0000644 00000004672 15055745141 0010621 0 ustar 00 --TEST--
Data type round-tripping
--FILE--
<?php
function doTest( $test, $data ) {
printf( "%-25s ", "$test:" );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
try {
$ret = $sandbox->loadString( 'return ...' )->call( $data );
if ( is_array( $ret[0] ) ) {
ksort( $ret[0], SORT_STRING );
}
printf( "%s\n", preg_replace( '/\s+/', ' ', var_export( $ret[0], 1 ) ) );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
}
doTest( 'null', null );
doTest( 'int', 123 );
if ( is_int( 17179869184 ) ) {
doTest( 'long', 17179869184 );
} else {
// Fake it for 32-bit systems
printf( "%-25s %s\n", "long:", "17179869184" );
}
doTest( 'double', 3.125 );
doTest( 'NAN', NAN );
doTest( 'INF', INF );
doTest( 'true', true );
doTest( 'false', false );
doTest( 'string', 'foobar' );
doTest( 'empty string', '' );
doTest( 'string containing NULs', "foo\0bar" );
doTest( 'array', array( 'foo', 'bar' ) );
doTest( 'associative array', array( 'foo', 'bar' => 'baz' ) );
$var = 42;
doTest( 'array with reference', [ &$var ] );
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
$sandbox->setCPULimit( 0.1 );
$func = $sandbox->wrapPhpFunction( function ( $x ) { return [ "FUNC: $x" ]; } );
try {
$ret = $sandbox->loadString( 'return ...' )->call( $func );
$ret2 = $ret[0]->call( "ok" );
printf( "%-25s %s\n", "function, pass-through:", $ret2[0] );
$ret = $sandbox->loadString( 'f = ...; return f( "ok" )' )->call( $func );
printf( "%-25s %s\n", "function, called:", $ret[0] );
$ret = $sandbox->loadString( 'return function ( x ) return "FUNC: " .. x end' )->call();
$ret2 = $ret[0]->call( "ok" );
printf( "%-25s %s\n", "function, returned:", $ret2[0] );
} catch ( LuaSandboxError $e ) {
printf( "EXCEPTION: %s\n", $e->getMessage() );
}
--EXPECT--
null: NULL
int: 123
long: 17179869184
double: 3.125
NAN: NAN
INF: INF
true: true
false: false
string: 'foobar'
empty string: ''
string containing NULs: 'foo' . "\0" . 'bar'
array: array ( 0 => 'foo', 1 => 'bar', )
associative array: array ( 0 => 'foo', 'bar' => 'baz', )
array with reference: array ( 0 => 42, )
function, pass-through: FUNC: ok
function, called: FUNC: ok
function, returned: FUNC: ok
tests/errors-at-call-boundaries.phpt 0000644 00000003760 15055745141 0013600 0 ustar 00 --TEST--
Errors at PHP→Lua call boundaries
--FILE--
<?php
$sandbox = null; // Will be filled in later
function doTest( $str, callable $c ) {
global $sandbox;
echo "$str: ";
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 100000 );
try {
$ret = $sandbox->loadString( 'local f = ...; return f()' )
->call( $sandbox->wrapPhpFunction( $c ) );
var_dump( $ret );
} catch ( Exception $ex ) {
echo "Exception: " . $ex->getMessage() . "\n";
}
}
doTest( 'LuaSandbox::callFunction', function () {
global $sandbox;
$sandbox->loadString( 'function foo() return "no error" end' )->call();
return $sandbox->callFunction( 'foo',
str_repeat( 'a', 33334 ),
str_repeat( 'b', 33334 ),
str_repeat( 'c', 33334 ),
str_repeat( 'd', 33334 )
);
} );
doTest( 'LuaSandbox::registerLibrary 1', function () {
global $sandbox;
$sandbox->registerLibrary( str_repeat( 'a', 33334 ), [ 'foo' => function () {} ] );
$sandbox->registerLibrary( str_repeat( 'b', 33334 ), [ 'foo' => function () {} ] );
$sandbox->registerLibrary( str_repeat( 'c', 33334 ), [ 'foo' => function () {} ] );
$sandbox->registerLibrary( str_repeat( 'd', 33334 ), [ 'foo' => function () {} ] );
return [ 'no error' ];
} );
doTest( 'LuaSandbox::registerLibrary 2', function () {
global $sandbox;
$sandbox->registerLibrary( 'foo', [
str_repeat( 'a', 33334 ) => function () {},
str_repeat( 'b', 33334 ) => function () {},
str_repeat( 'c', 33334 ) => function () {},
str_repeat( 'd', 33334 ) => function () {},
] );
return [ 'no error' ];
} );
doTest( 'LuaSandboxFunction::call', function () {
global $sandbox;
return $sandbox->loadString( 'return "no error"' )->call(
str_repeat( 'a', 33334 ),
str_repeat( 'b', 33334 ),
str_repeat( 'c', 33334 ),
str_repeat( 'd', 33334 )
);
} );
--EXPECT--
LuaSandbox::callFunction: Exception: not enough memory
LuaSandbox::registerLibrary 1: Exception: not enough memory
LuaSandbox::registerLibrary 2: Exception: not enough memory
LuaSandboxFunction::call: Exception: not enough memory
tests/xpcall.phpt 0000644 00000005153 15055745141 0010101 0 ustar 00 --TEST--
xpcall() basic behaviour
--FILE--
<?php
$lua = <<<LUA
function xpcall_test(f, err)
local status, msg
status, msg = xpcall(f, err)
if not status then
return msg
else
return "success"
end
end
LUA;
$xperr = 'return "xp: " .. msg';
$tests = array(
'Normal' => array(
'return 1',
$xperr
),
'User error' => array(
'error("runtime error")',
$xperr
),
'Error in error handler' => array(
'error("original error")',
'error("error in handler")'
),
'Unconvertible error in error handler' => array(
'error("original error")',
'error({})'
),
'Numeric error in error handler' => array(
'error("original error")',
'error(2)',
),
'Argument check error' => array(
'string.byte()',
$xperr
),
'Protected infinite recursion' => array(
'function foo() foo() end foo()',
$xperr
),
'Infinite recursion in handler' => array(
'error("x")',
'function foo() foo() end foo()'
),
'Protected infinite loop' => array(
'while true do end',
$xperr,
),
'Infinite loop in handler' => array(
'error("x")',
'while true do end',
),
'Out of memory in handler' => array(
'error("x")',
'string.rep("x", 1000000)'
),
);
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->setCPULimit( 0.25 );
$sandbox->setMemoryLimit( 100000 );
foreach ( $tests as $desc => $info ) {
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->setCPULimit( 0.25 );
$sandbox->setMemoryLimit( 100000 );
echo "$desc: ";
list( $code, $errorCode ) = $info;
$func = $sandbox->loadString( $code );
$errorCode = "return function(msg) $errorCode end";
$ret = $sandbox->loadString( $errorCode )->call();
$errorFunc = $ret[0];
try {
print implode("\n",
$sandbox->callFunction( 'xpcall_test', $func, $errorFunc ) ) . "\n";
} catch ( LuaSandboxError $e ) {
echo "LuaSandboxError: " . $e->getMessage() . "\n";
}
}
--EXPECT--
Normal: success
User error: xp: [string ""]:1: runtime error
Error in error handler: LuaSandboxError: [string ""]:1: error in handler
Unconvertible error in error handler: LuaSandboxError: unknown error
Numeric error in error handler: LuaSandboxError: [string ""]:1: 2
Argument check error: xp: [string ""]:1: bad argument #1 to 'byte' (string expected, got no value)
Protected infinite recursion: LuaSandboxError: not enough memory
Infinite recursion in handler: LuaSandboxError: not enough memory
Protected infinite loop: LuaSandboxError: The maximum execution time for this script was exceeded
Infinite loop in handler: LuaSandboxError: The maximum execution time for this script was exceeded
Out of memory in handler: LuaSandboxError: not enough memory
tests/pairs.phpt 0000644 00000006500 15055745141 0007731 0 ustar 00 --TEST--
pairs() and __pairs
--FILE--
<?php
$lua = <<<LUA
function pairs_test1()
local t = { a = 1 }
local f, s, var = pairs( t )
if type( f ) == 'function' and s == t and var == nil then
local k, v = f(t, var)
if k == 'a' and v == 1 then
return "Ok"
else
return "Fail: First call returned " .. k .. "\\t" .. v
end
else
return "Fail:\\n" ..
tostring(f) .. '\\t' .. tostring(s) .. '\\t' .. tostring(var) .. '\\n' ..
tostring(next) .. '\\t' .. tostring(t) .. '\\tnil'
end
end
function pairs_test2()
local t = { a = 1 }
setmetatable( t, { __pairs = function () return 1, 2, 3 end } )
local f, s, var = pairs( t )
if f == 1 and s == 2 and var == 3 then
return "Ok"
else
return "Fail:\\n" ..
tostring(f) .. '\\t' .. tostring(s) .. '\\t' .. tostring(var) .. '\\n' ..
'1\\t2\\t3'
end
end
function pairs_test3()
pairs()
return "Fail: Should have thrown an error"
end
function pairs_return()
local data = { a = 1, b = 2 }
local t = {}
setmetatable( t, { __pairs = function () return pairs( data ) end } )
return t
end
function pairs_error()
local t = {}
setmetatable( t, { __pairs = function () error( "Error from __pairs function" ) end } )
pairs( t )
return "Fail: Should have thrown an error"
end
function pairs_return_error()
local t = {}
setmetatable( t, { __pairs = function () error( "Error from __pairs function" ) end } )
return t
end
function pairs_next_error()
local t = {}
setmetatable( t, {
__pairs = function ()
return function() error( "Error from next function" ) end
end
} )
for k, v in pairs( t ) do end
return "Fail: Should have thrown an error"
end
function pairs_return_next_error()
local t = {}
setmetatable( t, {
__pairs = function ()
return function() error( "Error from next function" ) end
end
} )
return t
end
LUA;
$tests = array(
'Normal' => 'pairs_test1',
'With __pairs' => 'pairs_test2',
'No argument' => 'pairs_test3',
'With __pairs throwing an error' => 'pairs_error',
'With next func throwing an error' => 'pairs_next_error',
'Table with __pairs returned to PHP' => 'pairs_return',
'Table with __pairs throwing an error returned to PHP' => 'pairs_return_error',
'Table with next func throwing an error returned to PHP' => 'pairs_return_next_error',
);
foreach ( $tests as $desc => $func ) {
echo "$desc: ";
$sandbox = new LuaSandbox;
$sandbox->loadString( $lua )->call();
$sandbox->setCPULimit( 0.25 );
$sandbox->setMemoryLimit( 100000 );
try {
print var_export( $sandbox->callFunction( $func ), 1 ) . "\n";
} catch ( LuaSandboxError $e ) {
echo "LuaSandboxError: " . $e->getMessage() . "\n";
}
}
--EXPECT--
Normal: array (
0 => 'Ok',
)
With __pairs: array (
0 => 'Ok',
)
No argument: LuaSandboxError: [string ""]:32: bad argument #1 to 'pairs' (table expected, got no value)
With __pairs throwing an error: LuaSandboxError: [string ""]:45: Error from __pairs function
With next func throwing an error: LuaSandboxError: [string ""]:60: Error from next function
Table with __pairs returned to PHP: array (
0 =>
array (
'a' => 1,
'b' => 2,
),
)
Table with __pairs throwing an error returned to PHP: LuaSandboxError: [string ""]:52: Error from __pairs function
Table with next func throwing an error returned to PHP: LuaSandboxError: [string ""]:71: Error from next function
tests/LuaSandboxFunction_construct.phpt 0000644 00000000375 15055745141 0014471 0 ustar 00 --TEST--
LuaSandboxFunction::construct() is private
--SKIPIF--
<?php if (!extension_loaded("luasandbox")) print "skip"; ?>
--FILE--
<?php
new LuaSandboxFunction;
?>
--EXPECTF--
%AFatal error:%sCall to private%S LuaSandboxFunction::__construct%S from %a