break;
case LUA_LOG_ERR:
- case LUA_LOG_WARN:
ErrorMessage("%s:%s\n", name.c_str(), message);
break;
+ case LUA_LOG_WARN:
+ WarningMessage("%s:%s\n", name.c_str(), message);
+ break;
+
case LUA_LOG_NOTICE:
case LUA_LOG_INFO:
LogMessage("%s:%s\n", name.c_str(), message);
int rc = pcre_exec(re, // compiled pattern
nullptr, // no extra data
(const char*)lsd->ldp.data, // subject string
- lsd->ldp.size, // length of the subject
+ lsd->ldp.size, // length of the subject
offset, // offset 0
0, // default options
ovector, // output vector for substring information
WarningMessage("ovector only has room for %d captured substrings\n", rc - 1);
}
- lua_checkstack(L, rc);
+ if (!lua_checkstack(L, rc))
+ {
+ WarningMessage("Cannot grow Lua stack by %d slots to hold PCRE matches\n", rc);
+ return 0;
+ }
+
for (int i = 0; i < rc; i++)
{
lua_pushlstring(L, (const char*)lsd->ldp.data + ovector[2*i], ovector[2*i+1] -
unsigned int patternLen = lua_tonumber(L, 3);
unsigned int offset = lua_tonumber(L, 4); /*offset can be zero, no check necessary. */
int rc = memcmp(lsd->ldp.data + offset, pattern, patternLen);
- lua_checkstack (L, 1);
lua_pushnumber(L, rc);
return 1;
}
if ( !lsd->ldp.pkt->has_ip() )
{
- // FIXIT-M J why the inconsistent use of checkstack?
- lua_checkstack (L, 1);
lua_pushnumber(L, 0);
return 1;
}
- lua_checkstack (L, 1);
// FIXIT-M is this conversion to double valid?
lua_pushnumber(L, (double)lsd->ldp.pkt->get_ip_proto_next() );
return 1;
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
const SfIp* ipAddr = lsd->ldp.pkt->ptrs.ip_api.get_src();
- lua_checkstack (L, 1);
lua_pushnumber(L, ipAddr->get_ip4_value());
return 1;
}
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
const SfIp* ipAddr = lsd->ldp.pkt->ptrs.ip_api.get_dst();
- lua_checkstack (L, 1);
lua_pushnumber(L, ipAddr->get_ip4_value());
return 1;
}
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
unsigned int port = lsd->ldp.pkt->ptrs.sp;
- lua_checkstack (L, 1);
lua_pushnumber(L, port);
return 1;
}
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
unsigned int port = lsd->ldp.pkt->ptrs.dp;
- lua_checkstack (L, 1);
lua_pushnumber(L, port);
return 1;
}
**/
static int detector_get_packet_count(lua_State* L)
{
- lua_checkstack (L, 1);
lua_pushnumber(L, appid_stats.processed_packets);
return 1;
}
const char* callback = lua_tostring(L, 3);
- if (!callback)
+ if (!callback or (callback[0] == '\0'))
{
lua_pushnumber(L, -1);
return 1; // number of results
LuaDetectorManager& lua_detector_mgr = odp_thread_local_ctxt->get_lua_detector_mgr();
auto my_lua_state = lua_detector_mgr.L;
+ // when an ODP detector triggers the detector callback to be called, there are some elements
+ // in the stack. Checking here to make sure the number of elements is not too many
+ if (lua_gettop(my_lua_state) > 20)
+ WarningMessage("appid: leak of %d lua stack elements before detector callback\n",
+ lua_gettop(my_lua_state));
+
const string& cb_fn_name = ud.get_cb_fn_name();
const char* detector_name = ud.get_detector()->get_name().c_str();
- if ((cb_fn_name.empty()) || !(lua_checkstack(my_lua_state, 1)))
- {
- ErrorMessage("Detector %s: invalid LUA %s\n", detector_name, lua_tostring(my_lua_state, -1));
- ud.lsd.ldp.pkt = nullptr;
- return -10;
- }
-
lua_getfield(my_lua_state, LUA_REGISTRYINDEX, ud.lsd.package_info.name.c_str());
ud.lsd.ldp.data = data;
{
ErrorMessage("Detector %s: Error validating %s\n", detector_name, lua_tostring(my_lua_state, -1));
ud.lsd.ldp.pkt = nullptr;
+ lua_settop(my_lua_state, 0);
return -10;
}
{
ErrorMessage("Detector %s: Validator returned non-numeric value\n", detector_name);
ud.lsd.ldp.pkt = nullptr;
+ lua_settop(my_lua_state, 0);
return -10;
}
int ret = lua_tonumber(my_lua_state, -1);
lua_pop(my_lua_state, 1); // pop returned value
ud.lsd.ldp.pkt = nullptr;
+ lua_settop(my_lua_state, 0);
return ret;
}
// Verify detector user data and that we are in packet context
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
- if (!lua_checkstack(L, 1))
- return 0;
-
const AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
if (hsession)
// Verify detector user data and that we are in packet context
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
- if (!lua_checkstack(L, 1))
- return 0;
-
const AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
if (hsession)
{
// Verify detector user data and that we are in packet context
LuaStateDescriptor* lsd = ud->validate_lua_state(true);
- if (!lua_checkstack(L, 1))
- return 0;
-
const AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
if (hsession)
{
if (!my_lua_state)
{
ErrorMessage("lua detector %s: no LUA state\n", package_info.name.c_str());
+ lua_settop(my_lua_state, 0);
return APPID_ENULL;
}
if ( (!validateFn) || (validateFn[0] == '\0'))
{
ldp.pkt = nullptr;
+ lua_settop(my_lua_state, 0);
return APPID_NOMATCH;
}
- else if ( !lua_checkstack(my_lua_state, 1) )
- {
- static bool logged_stack_error = false;
- if (!logged_stack_error)
- {
- logged_stack_error = true;
- ErrorMessage("lua detector %s: LUA stack can not grow, %s\n",
- package_info.name.c_str(), lua_tostring(my_lua_state, -1));
- }
- ldp.pkt = nullptr;
- return APPID_ENOMEM;
- }
lua_getfield(my_lua_state, -1, validateFn); // get the function we want to call
package_info.name.c_str(), lua_tostring(my_lua_state, -1));
ldp.pkt = nullptr;
lua_detector_mgr.free_detector_flow();
+ lua_settop(my_lua_state, 0);
return APPID_ENULL;
}
{
ErrorMessage("lua detector %s: returned non-numeric value\n", package_info.name.c_str());
ldp.pkt = nullptr;
+ lua_settop(my_lua_state, 0);
return APPID_ENULL;
}
int rc = lua_tonumber(my_lua_state, -1);
lua_pop(my_lua_state, 1);
ldp.pkt = nullptr;
+ lua_settop(my_lua_state, 0);
+
return rc;
}
lua_pushvalue(L, -1);
- // FIXIT-E: RELOAD - go back to using lua reference
- // instead of using a string for lookups
- // lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-
// FIXIT-E: The control and thread states have the same initialization
// sequence, the stack index shouldn't change between the states, maybe
// use a common index for a detector between all the states
int LuaServiceDetector::validate(AppIdDiscoveryArgs& args)
{
- //FIXIT-M: RELOAD - use lua references to get user data object from stack
auto my_lua_state = odp_thread_local_ctxt->get_lua_detector_mgr().L;
- lua_settop(my_lua_state,0);
+ if (lua_gettop(my_lua_state))
+ WarningMessage("appid: leak of %d lua stack elements before service validate\n",
+ lua_gettop(my_lua_state));
+
std::string name = this->name + "_";
lua_getglobal(my_lua_state, name.c_str());
auto& ud = *UserData<LuaServiceObject>::check(my_lua_state, DETECTOR, 1);
lua_pushvalue(L, -1);
- // FIXIT-E: RELOAD - go back to using lua reference
- // instead of using a string for lookups
- // lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-
// FIXIT-E: The control and thread states have the same initialization
// sequence, the stack index shouldn't change between the states, maybe
// use a common index for a detector between all the states
int LuaClientDetector::validate(AppIdDiscoveryArgs& args)
{
- //FIXIT-M: RELOAD - use lua references to get user data object from stack
auto my_lua_state = odp_thread_local_ctxt->get_lua_detector_mgr().L;
+ if (lua_gettop(my_lua_state))
+ WarningMessage("appid: leak of %d lua stack elements before client validate\n",
+ lua_gettop(my_lua_state));
+
std::string name = this->name + "_";
- lua_settop(my_lua_state,0); //set stack index to 0
lua_getglobal(my_lua_state, name.c_str());
auto& ud = *UserData<LuaClientObject>::check(my_lua_state, DETECTOR, 1);
return ud->lsd.lua_validate(args);
{
lua_pushboolean (L, is_control); // push flag to stack
lua_setglobal(L, "is_control"); // create global key to store value
- lua_pop(L, 1);
}
static lua_State* create_lua_state(const AppIdConfig& config, int is_control)
LuaDetectorManager::~LuaDetectorManager()
{
auto L = this->L;
+ if (lua_gettop(L))
+ WarningMessage("appid: leak of %d lua stack elements before detector unload\n",
+ lua_gettop(L));
+
if (L)
{
if (init(L))
lua_getfield(L, -1, lsd->package_info.cleanFunctionName.c_str());
if ( lua_isfunction(L, -1) )
{
- // FIXIT-M: RELOAD - use lua references to get user data object from stack
- // first parameter is DetectorUserData
std::string name = lsd->package_info.name + "_";
lua_getglobal(L, name.c_str());
lsd->package_info.name.c_str(), lua_tostring(L, -1));
}
}
+ lua_settop(L, 0);
delete lua_object;
}
lua_close(L);
{
if (init(L))
ErrorMessage("Error - appid: can not load Lua detector, %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
return;
}
}
{
if (init(L))
ErrorMessage("Error - appid: can not load Lua detector, %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
return;
}
if (reload and lua_dump(L, dump, &buf))
{
if (init(L))
ErrorMessage("Error - appid: can not compile Lua detector, %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
return;
}
}
{
ErrorMessage("Error - appid: can not set env of Lua detector %s : %s\n",
detector_filename, lua_tostring(L, -1));
+ lua_pop(L, 1);
return;
}
int rval = glob(pattern, 0, nullptr, &globs);
if (rval == 0 )
{
+ if (lua_gettop(L))
+ WarningMessage("appid: leak of %d lua stack elements before detector load\n",
+ lua_gettop(L));
+
std::string buf;
for (unsigned n = 0; n < globs.gl_pathc; n++)
{
lua_detector_mgr->load_detector(globs.gl_pathv[n], is_custom, reload, buf);
buf.clear();
}
+ lua_settop(L, 0);
}
globfree(&globs);
allocated_objects.size());
std::list<LuaObject*>::iterator lo = allocated_objects.begin();
+ if (lua_gettop(L))
+ WarningMessage("appid: leak of %d lua stack elements before detector activate\n",
+ lua_gettop(L));
+
while (lo != allocated_objects.end())
{
LuaStateDescriptor* lsd = (*lo)->validate_lua_state(false);
(*lo)->get_detector()->get_name().c_str());
if (!(*lo)->get_detector()->is_custom_detector())
num_odp_detectors--;
+ lua_settop(L, 0);
delete *lo;
lo = allocated_objects.erase(lo);
continue;
}
- //FIXIT-M: RELOAD - use lua references to get user data object from stack
/*first parameter is DetectorUserData */
std::string name = lsd->package_info.name + "_";
lua_getglobal(L, name.c_str());
ErrorMessage("Error - appid: can not run DetectorInit, %s\n", lua_tostring(L, -1));
if (!(*lo)->get_detector()->is_custom_detector())
num_odp_detectors--;
+ lua_settop(L, 0);
delete *lo;
lo = allocated_objects.erase(lo);
continue;
lua_getfield(L, LUA_REGISTRYINDEX, lsd->package_info.name.c_str());
set_lua_tracker_size(L, lua_tracker_size);
+ lua_settop(L, 0);
++lo;
}
}