diff options
author | Kinsey Moore <kmoore@digium.com> | 2012-01-06 21:26:16 +0000 |
---|---|---|
committer | Kinsey Moore <kmoore@digium.com> | 2012-01-06 21:26:16 +0000 |
commit | 389ac0cff187421f3136c9b30302b372f8e0e8e8 (patch) | |
tree | acfa733ef3b51d89c1f5f116bcb230e961d8170a /pbx/pbx_lua.c | |
parent | d7005bf8ad0ac9aa95fc720c38136f20d105b198 (diff) |
Fix lua goto detection to prevent unexpected behavior with confbridge
A bug in the pbx_lua goto detection was causing the dialplan to hangup
unexpectedly after confbridge exited if it had called lua dialplan code during
execution.
Patch-by: Timo Teras
Acked-by: Matt Nicholson
(closes issue ASTERISK-18976)
........
Merged revisions 349928 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@349929 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'pbx/pbx_lua.c')
-rw-r--r-- | pbx/pbx_lua.c | 106 |
1 files changed, 36 insertions, 70 deletions
diff --git a/pbx/pbx_lua.c b/pbx/pbx_lua.c index 0dccfe644..2c1487466 100644 --- a/pbx/pbx_lua.c +++ b/pbx/pbx_lua.c @@ -94,7 +94,6 @@ 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_detect_goto(lua_State *L); static void lua_concat_args(lua_State *L, int start, int nargs); static void lua_state_destroy(void *data); @@ -213,19 +212,10 @@ static int lua_pbx_exec(lua_State *L) chan = lua_touserdata(L, -1); lua_pop(L, 1); + context = ast_strdupa(chan->context); + exten = ast_strdupa(chan->exten); + priority = chan->priority; - lua_getfield(L, LUA_REGISTRYINDEX, "context"); - context = ast_strdupa(lua_tostring(L, -1)); - lua_pop(L, 1); - - lua_getfield(L, LUA_REGISTRYINDEX, "exten"); - exten = ast_strdupa(lua_tostring(L, -1)); - lua_pop(L, 1); - - lua_getfield(L, LUA_REGISTRYINDEX, "priority"); - priority = lua_tointeger(L, -1); - lua_pop(L, 1); - lua_concat_args(L, 2, nargs); data = lua_tostring(L, -1); @@ -256,75 +246,51 @@ static int lua_pbx_exec(lua_State *L) return lua_error(L); } - lua_detect_goto(L); - - return 0; -} - -/*! - * \brief Detect if a Goto or other dialplan jump has been executed and return - * control to the pbx engine. - */ -static void lua_detect_goto(lua_State *L) -{ - struct ast_channel *chan; - - lua_getfield(L, LUA_REGISTRYINDEX, "channel"); - chan = lua_touserdata(L, -1); - lua_pop(L, 1); - - /* check context */ - lua_getfield(L, LUA_REGISTRYINDEX, "context"); - lua_pushstring(L, chan->context); - if (!lua_equal(L, -1, -2)) { + if (strcmp(context, chan->context)) { + lua_pushstring(L, context); + lua_pushstring(L, chan->context); lua_pushliteral(L, "context"); - goto e_goto_detected; - } - lua_pop(L, 2); - - /* check exten */ - lua_getfield(L, LUA_REGISTRYINDEX, "exten"); - lua_pushstring(L, chan->exten); - if (!lua_equal(L, -1, -2)) { + } else if (strcmp(exten, chan->exten)) { + lua_pushstring(L, exten); + lua_pushstring(L, chan->exten); lua_pushliteral(L, "exten"); - goto e_goto_detected; - } - lua_pop(L, 2); - - /* check priority */ - lua_getfield(L, LUA_REGISTRYINDEX, "priority"); - lua_pushinteger(L, chan->priority); - if (!lua_equal(L, -1, -2)) { + } else if (priority != chan->priority) { + lua_pushinteger(L, priority); + lua_pushinteger(L, chan->priority); lua_pushliteral(L, "priority"); - goto e_goto_detected; + } else { + /* no goto - restore the original position back + * to lua state, in case this was a recursive dialplan + * call (a dialplan application re-entering dialplan) */ + lua_update_registry(L, context, exten, priority); + return 0; } - lua_pop(L, 2); - return; - -e_goto_detected: - /* format our debug message */ - lua_insert(L, -3); - lua_pushliteral(L, " changed from "); + /* goto detected - construct error message */ lua_insert(L, -3); - - lua_pushliteral(L, " to "); - lua_insert(L, -2); - - lua_concat(L, 5); - - ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1)); - lua_pop(L, 1); - - /* let the lua engine know it needs to return control to the pbx */ - lua_pushinteger(L, LUA_GOTO_DETECTED); + + lua_pushliteral(L, " changed from "); + lua_insert(L, -3); + + lua_pushliteral(L, " to "); + lua_insert(L, -2); + + lua_concat(L, 5); + + ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + + /* let the lua engine know it needs to return control to the pbx */ + lua_pushinteger(L, LUA_GOTO_DETECTED); lua_error(L); + + return 0; } /*! * \brief [lua_CFunction] Used to get the value of a variable or dialplan * function (for access from lua, don't call directly) - * + * * The value of the variable or function is returned. This function is the * 'get()' function in the following example as would be seen in * extensions.lua. |