From fffb591fd7acd704c4ee7c37d651c07a57e3d533 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Tue, 24 Sep 2013 15:11:34 -0400 Subject: [PATCH 2/3] Handle invalid keys in Lua-to-PHP calls for LuaSandbox 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, fix stringification of infinities as "inf" rather than as the number 0. Also, add tests for proper stringification of floats and infinities when those are used as keys. Bug: 54527 Change-Id: I566c943b5c00194f6a00cb97eb1f39c99176e4b4 --- data_conversion.c | 31 ++++++++++++++++++++++++++++++- tests/call.phpt | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/data_conversion.c b/data_conversion.c index 50453d7..1ae139f 100644 --- a/data_conversion.c +++ b/data_conversion.c @@ -406,7 +406,7 @@ static int luasandbox_lua_to_array(HashTable *ht, lua_State *L, int index, if (lua_type(L, -2) == LUA_TNUMBER) { n = lua_tonumber(L, -2); - if (n == floor(n)) { + if (isfinite(n) && n == floor(n)) { // Integer key zend_hash_index_update(ht, n, (void*)&value, sizeof(zval*), NULL); lua_settop(L, top + 1); @@ -417,6 +417,35 @@ static int luasandbox_lua_to_array(HashTable *ht, lua_State *L, int index, // Make a copy of the key so that we can call lua_tolstring() which is destructive lua_pushvalue(L, -2); str = lua_tolstring(L, -1, &length); + if ( str == NULL ) { + // Only strings and integers may be used as keys + zval *zex, *ztrace; + char *message; + + spprintf(&message, 0, "Cannot use %s as an array key when passing data from Lua to PHP", + lua_typename(L, lua_type(L, -3)) + ); + + MAKE_STD_ZVAL(zex); + object_init_ex(zex, luasandboxruntimeerror_ce); + + MAKE_STD_ZVAL(ztrace); + luasandbox_push_structured_trace(L, 1); + luasandbox_lua_to_zval(ztrace, L, -1, sandbox_zval, NULL TSRMLS_CC); + zend_update_property(luasandboxruntimeerror_ce, zex, "luaTrace", sizeof("luaTrace")-1, ztrace TSRMLS_CC); + zval_ptr_dtor(&ztrace); + lua_pop(L, 1); + + zend_update_property_string(luasandboxruntimeerror_ce, zex, + "message", sizeof("message")-1, message TSRMLS_CC); + zend_update_property_long(luasandboxruntimeerror_ce, zex, "code", sizeof("code")-1, -1 TSRMLS_CC); + zend_throw_exception_object(zex TSRMLS_CC); + + efree(message); + + lua_settop(L, top); + return 0; + } zend_hash_update(ht, str, length + 1, (void*)&value, sizeof(zval*), NULL); // Pop temporary values off the stack diff --git a/tests/call.phpt b/tests/call.phpt index 0817730..51beb61 100644 --- a/tests/call.phpt +++ b/tests/call.phpt @@ -81,6 +81,51 @@ while ( is_array( $v ) ) { } 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]=> @@ -94,3 +139,12 @@ 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, +) -- 1.8.4.rc3