[asterisk-commits] kmoore: branch 10 r349928 - /branches/10/pbx/pbx_lua.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 6 15:25:22 CST 2012


Author: kmoore
Date: Fri Jan  6 15:25:19 2012
New Revision: 349928

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=349928
Log:
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)

Modified:
    branches/10/pbx/pbx_lua.c

Modified: branches/10/pbx/pbx_lua.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/pbx/pbx_lua.c?view=diff&rev=349928&r1=349927&r2=349928
==============================================================================
--- branches/10/pbx/pbx_lua.c (original)
+++ branches/10/pbx/pbx_lua.c Fri Jan  6 15:25:19 2012
@@ -94,7 +94,6 @@
 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 @@
 	chan = lua_touserdata(L, -1);
 	lua_pop(L, 1);
 	
-	
-	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);
-
+	context = ast_strdupa(chan->context);
+	exten = ast_strdupa(chan->exten);
+	priority = chan->priority;
+	
 	lua_concat_args(L, 2, nargs);
 	data = lua_tostring(L, -1);
 
@@ -256,75 +246,51 @@
 		return lua_error(L);
 	}
 
-	lua_detect_goto(L);
+	if (strcmp(context, chan->context)) {
+		lua_pushstring(L, context);
+		lua_pushstring(L, chan->context);
+		lua_pushliteral(L, "context");
+	} else if (strcmp(exten, chan->exten)) {
+		lua_pushstring(L, exten);
+		lua_pushstring(L, chan->exten);
+		lua_pushliteral(L, "exten");
+	} else if (priority != chan->priority) {
+		lua_pushinteger(L, priority);
+		lua_pushinteger(L, chan->priority);
+		lua_pushliteral(L, "priority");
+	} 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;
+	}
+
+	/* goto detected - construct error message */
+	lua_insert(L, -3);
+													
+	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 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)) {
-		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)) {
-		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)) {
-		lua_pushliteral(L, "priority");
-		goto e_goto_detected;
-	}
-	lua_pop(L, 2);
-	return;
-
-e_goto_detected:
-	/* format our debug message */
-	lua_insert(L, -3);
-
-	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);
 }
 
 /*!
  * \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.




More information about the asterisk-commits mailing list