From b498361532ad34fc764b052bdcfbe802d5ef349d Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Thu, 20 Feb 2014 01:25:07 +0500
Subject: [PATCH] FS-6241 --resolve

---
 src/mod/languages/mod_lua/freeswitch_lua.cpp | 41 +++++++++++++-------
 src/mod/languages/mod_lua/mod_lua.cpp        | 22 ++++++-----
 2 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp
index 34edfaea93..efef9679e7 100644
--- a/src/mod/languages/mod_lua/freeswitch_lua.cpp
+++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp
@@ -4,7 +4,7 @@
 using namespace LUA;
 
 extern "C" {
-	int docall(lua_State * L, int narg, int nresults, int perror);
+	int docall(lua_State * L, int narg, int nresults, int perror, int fatal);
 };
 
 Session::Session():CoreSession()
@@ -147,7 +147,7 @@ void Session::do_hangup_hook()
 			arg_count++;
 		}
 
-		docall(L, arg_count, 1, 1);
+		docall(L, arg_count, 1, 1, 0);
 
 		const char *err = lua_tostring(L, -1);
 		
@@ -273,6 +273,7 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
 			switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
 			char str[3] = "";
 			int arg_count = 3;
+			int r;
 
 			lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function);
 			lua_getfield(L, LUA_GLOBALSINDEX, uuid);
@@ -294,10 +295,14 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
 				arg_count++;
 			}
 
-			docall(L, arg_count, 1, 1);
+			r = docall(L, arg_count, 1, 1, 0);
 
-			ret = lua_tostring(L, -1);
-			lua_pop(L, 1);
+			if (!r) {
+				ret = lua_tostring(L, -1);
+				lua_pop(L, 1);
+			} else {
+				ret = "SCRIPT_ERROR";
+			}
 
 			return process_callback_result((char *) ret);
 		}
@@ -319,9 +324,12 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp
 				arg_count++;
 			}
 
-			docall(L, arg_count, 1, 1);
-			ret = lua_tostring(L, -1);
-			lua_pop(L, 1);
+			if (!docall(L, arg_count, 1, 1, 0)) {
+				ret = lua_tostring(L, -1);
+				lua_pop(L, 1);
+			} else {
+				ret = "SCRIPT_ERROR";
+			}
 
 			return process_callback_result((char *) ret);
 		}
@@ -407,14 +415,17 @@ int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv)
     lua_settable(lua_fun->L, -3);
   }
 
-	docall(lua_fun->L, 1, 1, 1);
-	ret = lua_tonumber(lua_fun->L, -1);
-	lua_pop(lua_fun->L, 1);
-
-	if (ret != 0) {
-		return 1;
-	}
+  if (docall(lua_fun->L, 1, 1, 1, 0)) {
+	  return 1;
+  }
 
+  ret = lua_tonumber(lua_fun->L, -1);
+  lua_pop(lua_fun->L, 1);
+  
+  if (ret != 0) {
+	  return 1;
+  }
+  
   return 0; /* 0 to continue with next row */
 }
 
diff --git a/src/mod/languages/mod_lua/mod_lua.cpp b/src/mod/languages/mod_lua/mod_lua.cpp
index 9715f0dc74..4feaf6bd8c 100644
--- a/src/mod/languages/mod_lua/mod_lua.cpp
+++ b/src/mod/languages/mod_lua/mod_lua.cpp
@@ -81,7 +81,7 @@ static int traceback(lua_State * L)
 	return 1;
 }
 
-int docall(lua_State * L, int narg, int nresults, int perror)
+int docall(lua_State * L, int narg, int nresults, int perror, int fatal)
 {
 	int status;
 	int base = lua_gettop(L) - narg;	/* function index */
@@ -102,9 +102,13 @@ int docall(lua_State * L, int narg, int nresults, int perror)
 		if (!zstr(err)) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err);
 		}
-		//lua_pop(L, 1); /* pop error message from the stack */
+		
 		// pass error up to top
-		lua_error(L);
+		if (fatal) {
+			lua_error(L);
+		} else {
+			lua_pop(L, 1); /* pop error message from the stack */
+		}
 	}
 
 	return status;
@@ -123,7 +127,7 @@ static lua_State *lua_init(void)
 		luaopen_freeswitch(L);
 		lua_gc(L, LUA_GCRESTART, 0);
 		lua_atpanic(L, panic);
-		error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0);
+		error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0, 1);
 	}
 	return L;
 }
@@ -142,10 +146,10 @@ static int lua_parse_and_execute(lua_State * L, char *input_code)
 	
 	if (*input_code == '~') {
 		char *buff = input_code + 1;
-		error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0);	//lua_pcall(L, 0, 0, 0);
+		error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0, 1);	//lua_pcall(L, 0, 0, 0);
 	} else if (!strncasecmp(input_code, "#!/lua", 6)) {
 		char *buff = input_code + 6;
-		error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0);	//lua_pcall(L, 0, 0, 0);
+		error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0, 1);	//lua_pcall(L, 0, 0, 0);
 	} else {
 		char *args = strchr(input_code, ' ');
 		if (args) {
@@ -169,14 +173,14 @@ static int lua_parse_and_execute(lua_State * L, char *input_code)
 			}
 
 			if (code) {
-				error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0);
+				error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0, 1);
 				switch_safe_free(code);
 			}
 		} else {
 			// Force empty argv table
 			char *code = NULL;
 			code = switch_mprintf("argv = {[0]='%s'};", input_code);
-			error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0);
+			error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0, 1);
 			switch_safe_free(code);
 		}
 
@@ -188,7 +192,7 @@ static int lua_parse_and_execute(lua_State * L, char *input_code)
 				switch_assert(fdup);
 				file = fdup;
 			}
-			error = luaL_loadfile(L, file) || docall(L, 0, 0, 0);
+			error = luaL_loadfile(L, file) || docall(L, 0, 0, 0, 1);
 			switch_safe_free(fdup);
 		}
 	}