Handle invalid keys in Lua-to-PHP calls for LuaStandalone

PHP can't handle having arrays/objects or functions as keys in its
arrays, so make sure we don't try to pass them from Lua. Booleans aren't
really well-handled either, so let's disallow them too.

Also, add tests for proper stringification of floats and infinities when
those are used as keys.

Note this behavior change is needed to match the change in LuaSandbox
for fixing bug 54527, but isn't itself a security issue.

Change-Id: I1e2951bbe8cb78358650ad377bf7119fcac4485d
This commit is contained in:
Brad Jorsch 2013-09-24 15:07:54 -04:00
parent bc65238698
commit f52136eada
3 changed files with 40 additions and 5 deletions

View file

@ -439,14 +439,17 @@ function MWServer:serialize( var )
end
done[var] = true
local buf = { '' }
local tmpString
local numElements = 0
for key, value in pairs(var) do
if (isInteger(key)) then
buf[#buf + 1] = 'i:' .. key .. ';'
local t = type( key )
if t == 'number' or t == 'string' then
if (isInteger(key)) then
buf[#buf + 1] = 'i:' .. key .. ';'
else
buf[#buf + 1] = recursiveEncode( tostring( key ), level + 1 )
end
else
tmpString = tostring( key )
buf[#buf + 1] = recursiveEncode( tostring( key ), level + 1 )
error("Cannot use " .. type( key ) .. " as an array key when passing data from Lua to PHP");
end
buf[#buf + 1] = recursiveEncode( value, level + 1 )
numElements = numElements + 1

View file

@ -7,6 +7,18 @@ class Scribunto_LuaStandaloneTests extends Scribunto_LuaEngineTestBase {
return self::makeSuite( $className, 'LuaStandalone' );
}
public function setUp() {
parent::setUp();
$interpreter = $this->getEngine()->getInterpreter();
$func = $interpreter->wrapPhpFunction( function ( $v ) {
return array( preg_replace( '/\s+/', ' ', trim( var_export( $v, 1 ) ) ) );
} );
$interpreter->callFunction(
$interpreter->loadString( 'mw.var_export = ...', 'fortest' ), $func
);
}
function getTestModules() {
return parent::getTestModules() + array(
'StandaloneTests' => __DIR__ . '/StandaloneTests.lua',

View file

@ -25,4 +25,24 @@ return testframework.getTestProvider( {
{ name = 'getfenv on a C function', func = getfenv1,
expect = { nil },
},
{ name = 'Invalid array key (table)', func = mw.var_export,
args = { { [{}] = 1 } },
expect = 'Cannot use table as an array key when passing data from Lua to PHP',
},
{ name = 'Invalid array key (boolean)', func = mw.var_export,
args = { { [true] = 1 } },
expect = 'Cannot use boolean as an array key when passing data from Lua to PHP',
},
{ name = 'Invalid array key (function)', func = mw.var_export,
args = { { [tostring] = 1 } },
expect = 'Cannot use function as an array key when passing data from Lua to PHP',
},
{ name = 'Unusual array key (float)', func = mw.var_export,
args = { { [1.5] = 1 } },
expect = { "array ( '1.5' => 1, )" }
},
{ name = 'Unusual array key (inf)', func = mw.var_export,
args = { { [math.huge] = 1 } },
expect = { "array ( 'inf' => 1, )" }
},
} )