r113891 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113890‎ | r113891 | r113892 >
Date:04:24, 15 March 2012
Author:tstarling
Status:deferred
Tags:
Comment:
Override math.random and math.randomseed with versions that don't allow Lua to affect the exection of PHP by setting the seed, or to obtain information about state of PHP's PRNGs
Modified paths:
  • /trunk/php/luasandbox/luasandbox.c (modified) (history)
  • /trunk/php/luasandbox/php_luasandbox.h (modified) (history)

Diff [purge]

Index: trunk/php/luasandbox/php_luasandbox.h
@@ -66,6 +66,7 @@
6767 struct timespec cpu_normal_limit;
6868 struct timespec cpu_emergency_limit;
6969 int function_index;
 70+ unsigned int random_seed;
7071 };
7172 typedef struct _php_luasandbox_obj php_luasandbox_obj;
7273
Index: trunk/php/luasandbox/luasandbox.c
@@ -10,6 +10,7 @@
1111 #include <float.h>
1212 #include <signal.h>
1313 #include <time.h>
 14+#include <stdlib.h>
1415
1516 #include "php.h"
1617 #include "php_ini.h"
@@ -64,6 +65,8 @@
6566 static int luasandbox_call_php(lua_State * L);
6667 static int luasandbox_dump_writer(lua_State * L, const void * p, size_t sz, void * ud);
6768 static int luasandbox_base_tostring(lua_State * L);
 69+static int luasandbox_math_random(lua_State * L);
 70+static int luasandbox_math_randomseed(lua_State * L);
6871
6972 char luasandbox_timeout_message[] = "The maximum execution time for this script was exceeded";
7073
@@ -425,6 +428,15 @@
426429 lua_setfield(L, -2, "dump");
427430 lua_pop(L, 1);
428431
 432+ // Install our own versions of math.random and math.randomseed
 433+ lua_getglobal(L, "math");
 434+ lua_pushcfunction(L, luasandbox_math_random);
 435+ lua_setfield(L, -2, "random");
 436+ lua_pushcfunction(L, luasandbox_math_randomseed);
 437+ lua_setfield(L, -2, "randomseed");
 438+ lua_pop(L, 1);
 439+
 440+
429441 // Create a table for storing chunks
430442 lua_newtable(L);
431443 lua_setfield(L, LUA_REGISTRYINDEX, "php_luasandbox_chunks");
@@ -1736,6 +1748,54 @@
17371749 return 1;
17381750 }
17391751 /* }}} */
 1752+
 1753+/** {{{ luasandbox_math_random
 1754+ *
 1755+ * A math.random implementation that doesn't share state with PHP's rand()
 1756+ */
 1757+static int luasandbox_math_random(lua_State * L)
 1758+{
 1759+ php_luasandbox_obj * sandbox = luasandbox_get_php_obj(L);
 1760+
 1761+ int i = rand_r(&sandbox->random_seed);
 1762+ if (i >= RAND_MAX) {
 1763+ i -= RAND_MAX;
 1764+ }
 1765+ lua_Number r = (lua_Number)i / (lua_Number)RAND_MAX;
 1766+ switch (lua_gettop(L)) { /* check number of arguments */
 1767+ case 0: { /* no arguments */
 1768+ lua_pushnumber(L, r); /* Number between 0 and 1 */
 1769+ break;
 1770+ }
 1771+ case 1: { /* only upper limit */
 1772+ int u = luaL_checkint(L, 1);
 1773+ luaL_argcheck(L, 1<=u, 1, "interval is empty");
 1774+ lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
 1775+ break;
 1776+ }
 1777+ case 2: { /* lower and upper limits */
 1778+ int l = luaL_checkint(L, 1);
 1779+ int u = luaL_checkint(L, 2);
 1780+ luaL_argcheck(L, l<=u, 2, "interval is empty");
 1781+ lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
 1782+ break;
 1783+ }
 1784+ default: return luaL_error(L, "wrong number of arguments");
 1785+ }
 1786+ return 1;
 1787+}
 1788+/* }}} */
 1789+
 1790+/** {{{ luasandbox_math_randomseed
 1791+ *
 1792+ * Set the seed for the custom math.random.
 1793+ */
 1794+static int luasandbox_math_randomseed(lua_State * L)
 1795+{
 1796+ php_luasandbox_obj * sandbox = luasandbox_get_php_obj(L);
 1797+ sandbox->random_seed = (unsigned int)luaL_checkint(L, 1);
 1798+}
 1799+/* }}} */
17401800 /*
17411801 * Local variables:
17421802 * tab-width: 4

Status & tagging log