From c0d3d4b0e417913e98a10a97399f8edfa42c2e4f Mon Sep 17 00:00:00 2001 From: Matthew Nicholson Date: Fri, 21 Oct 2011 16:18:51 +0000 Subject: [PATCH] don't limit the length of app and function arguments ASTERISK-18395 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@341806 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- pbx/pbx_lua.c | 112 +++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/pbx/pbx_lua.c b/pbx/pbx_lua.c index db62c93ee9..378826c3c6 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 static char *lua_read_extensions_file(lua_State *L, long *size); @@ -77,13 +81,14 @@ 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); 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_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); @@ -177,15 +182,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); @@ -216,21 +219,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)), @@ -245,7 +236,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); @@ -389,16 +383,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); @@ -527,7 +523,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'; @@ -536,7 +532,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 */ @@ -589,6 +586,38 @@ static int lua_set_variable(lua_State *L) return 0; } +/*! + * \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) @@ -608,34 +637,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; } -- 2.47.2