diff options
author | Matthew Nicholson <mnicholson@digium.com> | 2011-10-21 16:22:23 +0000 |
---|---|---|
committer | Matthew Nicholson <mnicholson@digium.com> | 2011-10-21 16:22:23 +0000 |
commit | 9c7a01754076372f1011aea67c0047416536edde (patch) | |
tree | 68a1dda281101b23baab89caf1972fe0a2958011 /pbx/pbx_lua.c | |
parent | b009ea5216398a2760ae9502ae3c56aa41198f0d (diff) |
don't limit the length of app and function arguments
ASTERISK-18395
........
Merged revisions 341806 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 341807 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@341808 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'pbx/pbx_lua.c')
-rw-r--r-- | pbx/pbx_lua.c | 112 |
1 files changed, 61 insertions, 51 deletions
diff --git a/pbx/pbx_lua.c b/pbx/pbx_lua.c index c1088629b..db6090a60 100644 --- a/pbx/pbx_lua.c +++ b/pbx/pbx_lua.c @@ -50,7 +50,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") static char *config = "extensions.lua"; static char *registrar = "pbx_lua"; +#ifdef LOW_MEMORY #define LUA_EXT_DATA_SIZE 256 +#else +#define LUA_EXT_DATA_SIZE 8192 +#endif #define LUA_BUF_SIZE 4096 /* This value is used by the lua engine to signal that a Goto or dialplan jump @@ -83,7 +87,7 @@ static int lua_check_hangup(lua_State *L); static int lua_error_function(lua_State *L); static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority); -static void lua_push_variable_table(lua_State *L, const char *name); +static void lua_push_variable_table(lua_State *L); static void lua_create_app_table(lua_State *L); static void lua_create_channel_table(lua_State *L); static void lua_create_variable_metatable(lua_State *L); @@ -91,6 +95,7 @@ static void lua_create_application_metatable(lua_State *L); static void lua_create_autoservice_functions(lua_State *L); static void lua_create_hangup_function(lua_State *L); static void lua_detect_goto(lua_State *L); +static void lua_concat_args(lua_State *L, int start, int nargs); static void lua_state_destroy(void *data); static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan); @@ -184,15 +189,13 @@ static int lua_pbx_findapp(lua_State *L) static int lua_pbx_exec(lua_State *L) { int res, nargs = lua_gettop(L); - char data[LUA_EXT_DATA_SIZE] = ""; - char *data_next = data, *app_name; - char *context, *exten; + const char *data = ""; + char *app_name, *context, *exten; char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE]; int priority, autoservice; - size_t data_left = sizeof(data); struct ast_app *app; struct ast_channel *chan; - + lua_getfield(L, 1, "name"); app_name = ast_strdupa(lua_tostring(L, -1)); lua_pop(L, 1); @@ -223,21 +226,9 @@ static int lua_pbx_exec(lua_State *L) priority = lua_tointeger(L, -1); lua_pop(L, 1); + lua_concat_args(L, 2, nargs); + data = lua_tostring(L, -1); - if (nargs > 1) { - int i; - - if (!lua_isnil(L, 2)) - ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2)); - - for (i = 3; i <= nargs; i++) { - if (lua_isnil(L, i)) - ast_build_string(&data_next, &data_left, ","); - else - ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i)); - } - } - ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n", exten, context, priority, term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)), @@ -252,7 +243,10 @@ static int lua_pbx_exec(lua_State *L) ast_autoservice_stop(chan); res = pbx_exec(chan, app, data); - + + lua_pop(L, 1); /* pop data */ + data = ""; + if (autoservice) ast_autoservice_start(chan); @@ -459,16 +453,18 @@ static void lua_update_registry(lua_State *L, const char *context, const char *e * \brief Push a 'variable' table on the stack for access the channel variable * with the given name. * + * The value on the top of the stack is popped and used as the name. + * * \param L the lua_State to use * \param name the name of the variable */ -static void lua_push_variable_table(lua_State *L, const char *name) +static void lua_push_variable_table(lua_State *L) { lua_newtable(L); luaL_getmetatable(L, "variable"); lua_setmetatable(L, -2); - lua_pushstring(L, name); + lua_insert(L, -2); /* move the table after the name */ lua_setfield(L, -2, "name"); lua_pushcfunction(L, &lua_get_variable_value); @@ -597,7 +593,7 @@ static void lua_create_hangup_function(lua_State *L) static int lua_get_variable(lua_State *L) { struct ast_channel *chan; - char *name = ast_strdupa(luaL_checkstring(L, 2)); + const char *name = luaL_checkstring(L, 2); char *value = NULL; char *workspace = alloca(LUA_BUF_SIZE); workspace[0] = '\0'; @@ -606,7 +602,8 @@ static int lua_get_variable(lua_State *L) chan = lua_touserdata(L, -1); lua_pop(L, 1); - lua_push_variable_table(L, name); + lua_pushvalue(L, 2); + lua_push_variable_table(L); /* if this is not a request for a dialplan funciton attempt to retrieve * the value of the variable */ @@ -660,6 +657,38 @@ static int lua_set_variable(lua_State *L) } /*! + * \brief Concatenate a list of lua function arguments into a comma separated + * string. + * \param L the lua_State to use + * \param start the index of the first argument + * \param nargs the number of args + * + * The resulting string will be left on the top of the stack. + */ +static void lua_concat_args(lua_State *L, int start, int nargs) { + int concat = 0; + int i = start + 1; + + if (!lua_isnil(L, start)) { + lua_pushvalue(L, start); + concat += 1; + } + + for (; i <= nargs; i++) { + if (lua_isnil(L, i)) { + lua_pushliteral(L, ","); + concat += 1; + } else { + lua_pushliteral(L, ","); + lua_pushvalue(L, i); + concat += 2; + } + } + + lua_concat(L, concat); +} + +/*! * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan * function (for access from lua, don't call directly) * @@ -678,34 +707,15 @@ static int lua_set_variable(lua_State *L) static int lua_func_read(lua_State *L) { int nargs = lua_gettop(L); - char fullname[LUA_EXT_DATA_SIZE] = ""; - char *fullname_next = fullname, *name; - size_t fullname_left = sizeof(fullname); - - lua_getfield(L, 1, "name"); - name = ast_strdupa(lua_tostring(L, -1)); - lua_pop(L, 1); - - ast_build_string(&fullname_next, &fullname_left, "%s(", name); - - if (nargs > 1) { - int i; - if (!lua_isnil(L, 2)) - ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2)); - - for (i = 3; i <= nargs; i++) { - if (lua_isnil(L, i)) - ast_build_string(&fullname_next, &fullname_left, ","); - else - ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i)); - } - } + /* build a string in the form of "func_name(arg1,arg2,arg3)" */ + lua_getfield(L, 1, "name"); + lua_pushliteral(L, "("); + lua_concat_args(L, 2, nargs); + lua_pushliteral(L, ")"); + lua_concat(L, 4); - ast_build_string(&fullname_next, &fullname_left, ")"); - - lua_push_variable_table(L, fullname); - + lua_push_variable_table(L); return 1; } |