Index: trunk/php/luasandbox/luasandbox.c |
— | — | @@ -669,6 +669,19 @@ |
670 | 670 | zend_object_store_get_object(this_ptr TSRMLS_CC); |
671 | 671 | L = sandbox->state; |
672 | 672 | |
| 673 | + // The following code puts zval of the sandbox object into the register. |
| 674 | + // Why here? It should have been done at the constructor, but there was |
| 675 | + // no getThis() available at that point. Let's hope user will not run any |
| 676 | + // code requiring this register until he actually loads the code. |
| 677 | + // Why put it? Because when creating function object we need a zval, |
| 678 | + // not just php_luasandbox_obj, since we are going to reference to it from |
| 679 | + // the function object, and such referencing is possible only through zvalues. |
| 680 | + // Let us hope putting zval into Lua register won't corrupt any PHP internal |
| 681 | + // mechanisms. |
| 682 | + // FIXME: there should be a better way of doing this. |
| 683 | + lua_pushlightuserdata(L, (void*)getThis()); |
| 684 | + lua_setfield(L, LUA_REGISTRYINDEX, "php_luasandbox_obj_zval"); |
| 685 | + |
673 | 686 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", |
674 | 687 | &code, &codeLength, &chunkName, &chunkNameLength) == FAILURE) { |
675 | 688 | RETURN_FALSE; |
— | — | @@ -1357,7 +1370,45 @@ |
1358 | 1371 | } |
1359 | 1372 | break; |
1360 | 1373 | } |
1361 | | - case LUA_TFUNCTION: |
| 1374 | + case LUA_TFUNCTION: { |
| 1375 | + int func_index; |
| 1376 | + php_luasandboxfunction_obj * func_obj; |
| 1377 | + php_luasandbox_obj * sandbox; |
| 1378 | + zval * sandbox_zval; |
| 1379 | + |
| 1380 | + // Get the sandbox object and its zval |
| 1381 | + sandbox = luasandbox_get_php_obj(L); |
| 1382 | + lua_getfield(L, LUA_REGISTRYINDEX, "php_luasandbox_obj_zval"); |
| 1383 | + sandbox_zval = (zval*)lua_touserdata(L, -1); |
| 1384 | + assert(sandbox_zval != NULL); |
| 1385 | + lua_pop(L, 1); |
| 1386 | + |
| 1387 | + // Get the chunks table |
| 1388 | + lua_getfield(L, LUA_REGISTRYINDEX, "php_luasandbox_chunks"); |
| 1389 | + |
| 1390 | + // Get the next free index |
| 1391 | + func_index = ++(sandbox->function_index); |
| 1392 | + if (func_index >= INT_MAX) { |
| 1393 | + php_error_docref(NULL TSRMLS_CC, E_WARNING, |
| 1394 | + "too many chunks loaded already"); |
| 1395 | + ZVAL_NULL(z); |
| 1396 | + } |
| 1397 | + |
| 1398 | + // Put the function together with other chunks |
| 1399 | + lua_pushvalue(L, index); |
| 1400 | + lua_rawseti(L, -2, (int)func_index); |
| 1401 | + |
| 1402 | + // Create a LuaSandboxFunction object to hold a reference to the function |
| 1403 | + object_init_ex(z, luasandboxfunction_ce); |
| 1404 | + func_obj = (php_luasandboxfunction_obj*)zend_object_store_get_object(z); |
| 1405 | + func_obj->index = func_index; |
| 1406 | + func_obj->sandbox = sandbox_zval; |
| 1407 | + Z_ADDREF_P(func_obj->sandbox); |
| 1408 | + |
| 1409 | + // Balance the stack |
| 1410 | + lua_pop(L, 1); |
| 1411 | + break; |
| 1412 | + } |
1362 | 1413 | case LUA_TUSERDATA: |
1363 | 1414 | case LUA_TTHREAD: |
1364 | 1415 | case LUA_TLIGHTUSERDATA: |