From a3b575c5513ba9e2c90fa94dda82bc1f9aaa02f3 Mon Sep 17 00:00:00 2001 From: CurlyMoo Date: Sun, 3 Sep 2017 16:06:34 +0200 Subject: [PATCH] Keep Lua stacks separate on execution --- libs/pilight/events/operator.c | 51 ++++++------ libs/pilight/lua/lua.c | 137 +++++++++++++++++++-------------- 2 files changed, 106 insertions(+), 82 deletions(-) diff --git a/libs/pilight/events/operator.c b/libs/pilight/events/operator.c index cd5739303..9075362b0 100644 --- a/libs/pilight/events/operator.c +++ b/libs/pilight/events/operator.c @@ -75,12 +75,12 @@ void event_operator_init(void) { FREE(f); } -static int plua_operator_module_run(struct lua_State *L, char *file, struct varcont_t *a, struct varcont_t *b, char **ret) { +static int plua_operator_module_run(struct lua_State *l, char *file, struct varcont_t *a, struct varcont_t *b, char **ret) { #if LUA_VERSION_NUM <= 502 - lua_getfield(L, -1, "run"); - if(strcmp(lua_typename(L, lua_type(L, -1)), "function") != 0) { + lua_getfield(l, -1, "run"); + if(strcmp(lua_typename(l, lua_type(l, -1)), "function") != 0) { #else - if(lua_getfield(L, -1, "run") == 0) { + if(lua_getfield(l, -1, "run") == 0) { #endif logprintf(LOG_ERR, "%s: run function missing", file); return 0; @@ -95,14 +95,14 @@ static int plua_operator_module_run(struct lua_State *L, char *file, struct varc } memset(tmp, 0, len+1); sprintf(tmp, "%.*f", a->decimals_, a->number_); - lua_pushstring(L, tmp); + lua_pushstring(l, tmp); FREE(tmp); } break; case JSON_STRING: - lua_pushstring(L, a->string_); + lua_pushstring(l, a->string_); break; case JSON_BOOL: - lua_pushboolean(L, a->bool_); + lua_pushboolean(l, a->bool_); break; } switch(b->type_) { @@ -114,37 +114,37 @@ static int plua_operator_module_run(struct lua_State *L, char *file, struct varc } memset(tmp, 0, len+1); sprintf(tmp, "%.*f", b->decimals_, b->number_); - lua_pushstring(L, tmp); + lua_pushstring(l, tmp); FREE(tmp); } break; case JSON_STRING: - lua_pushstring(L, b->string_); + lua_pushstring(l, b->string_); break; case JSON_BOOL: - lua_pushboolean(L, b->bool_); + lua_pushboolean(l, b->bool_); break; } - if(lua_pcall(L, 2, 1, 0) == LUA_ERRRUN) { - if(strcmp(lua_typename(L, lua_type(L, -1)), "nil") == 0) { + if(lua_pcall(l, 2, 1, 0) == LUA_ERRRUN) { + if(strcmp(lua_typename(l, lua_type(l, -1)), "nil") == 0) { logprintf(LOG_ERR, "%s: syntax error", file); return 0; } - if(strcmp(lua_typename(L, lua_type(L, -1)), "string") == 0) { - logprintf(LOG_ERR, "%s", lua_tostring(L, -1)); - lua_pop(L, 1); + if(strcmp(lua_typename(l, lua_type(l, -1)), "string") == 0) { + logprintf(LOG_ERR, "%s", lua_tostring(l, -1)); + lua_pop(l, 1); return 0; } } - if(lua_isstring(L, -1) == 0) { - logprintf(LOG_ERR, "%s: the run function returned %s, string expected", file, lua_typename(L, lua_type(L, -1))); + if(lua_isstring(l, -1) == 0) { + logprintf(LOG_ERR, "%s: the run function returned %s, string expected", file, lua_typename(l, lua_type(l, -1))); return 0; } - strcpy(*ret, lua_tostring(L, -1)); + strcpy(*ret, lua_tostring(l, -1)); - lua_pop(L, 1); + lua_pop(l, 1); return 1; } @@ -155,17 +155,18 @@ int event_operator_exists(char *module) { int event_operator_callback(char *module, struct varcont_t *a, struct varcont_t *b, char **ret) { struct lua_State *L = plua_get_state(); + struct lua_State *l = lua_newthread(L); char name[255], *p = name; memset(name, '\0', 255); sprintf(p, "operator.%s", module); - lua_getglobal(L, name); - if(lua_isnil(L, -1) != 0) { + lua_getglobal(l, name); + if(lua_isnil(l, -1) != 0) { return -1; } - if(lua_istable(L, -1) != 0) { + if(lua_istable(l, -1) != 0) { char *file = NULL; struct plua_module_t *tmp = plua_get_modules(); while(tmp) { @@ -175,12 +176,12 @@ int event_operator_callback(char *module, struct varcont_t *a, struct varcont_t } tmp = tmp->next; } - if(plua_operator_module_run(L, file, a, b, ret) == 0) { - lua_pop(L, -1); + if(plua_operator_module_run(l, file, a, b, ret) == 0) { + lua_pop(l, -1); return -1; } } - lua_pop(L, -1); + lua_pop(l, -1); return 0; } diff --git a/libs/pilight/lua/lua.c b/libs/pilight/lua/lua.c index 58fb83780..79edf167f 100644 --- a/libs/pilight/lua/lua.c +++ b/libs/pilight/lua/lua.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifndef _WIN32 @@ -61,21 +62,26 @@ struct plua_module_t *modules = NULL; // printf("\n"); /* end the listing */ // } -static int plua_get_table_string_by_key(struct lua_State *L, const char *key, const char **ret) { +static int plua_get_table_string_by_key(struct lua_State *l, const char *key, const char **ret) { + /* + * Check if we are called as a seperate lua thread + */ + assert(L != l); + /* * Push the key we want to retrieve on the stack * * stack now contains: -1 => key -2 => table */ - lua_pushstring(L, key); + lua_pushstring(l, key); - if(lua_istable(L, -2) == 0) { + if(lua_istable(l, -2) == 0) { /* * Remove the key from the stack again * * stack now contains: -1 => table */ - lua_pop(L, 1); + lua_pop(l, 1); return 0; } @@ -84,50 +90,55 @@ static int plua_get_table_string_by_key(struct lua_State *L, const char *key, co * * stack now contains: -1 => value -2 => table */ - lua_gettable(L, -2); + lua_gettable(l, -2); /* * Check if the first element is a number */ - if(lua_isstring(L, -1) == 0) { + if(lua_isstring(l, -1) == 0) { /* * Remove the value from the stack again * * stack now contains: -1 => table */ - lua_pop(L, 1); + lua_pop(l, 1); return 0; } - *ret = lua_tostring(L, -1); + *ret = lua_tostring(l, -1); /* * stack now contains: -1 => table */ - lua_pop(L, 1); + lua_pop(l, 1); return 1; } -// static int plua_get_table_double_by_key(struct lua_State *L, const char *key, double *ret) { +// static int plua_get_table_double_by_key(struct lua_State *l, const char *key, double *ret) { + // /* + // * Check if we are called as a seperate lua thread + // */ + // assert(L != l); + // /* // * Push the key we want to retrieve on the stack // * // * stack now contains: -1 => key -2 => table // */ - // lua_pushstring(L, key); + // lua_pushstring(l, key); // /* // * Replace the key at -1 with it value in table -2 // * // * stack now contains: -1 => value -2 => table // */ - // if(lua_istable(L, -2) == 0) { + // if(lua_istable(l, -2) == 0) { // /* // * Remove the key from the stack again // * // * stack now contains: -1 => table // */ - // lua_pop(L, 1); + // lua_pop(l, 1); // return 0; // } // /* @@ -135,33 +146,38 @@ static int plua_get_table_string_by_key(struct lua_State *L, const char *key, co // * // * stack now contains: -1 => value -2 => table // */ - // lua_gettable(L, -2); + // lua_gettable(l, -2); // /* // * Check if the first element is a number // */ - // if(lua_isnumber(L, -1) == 0) { + // if(lua_isnumber(l, -1) == 0) { // /* // * Remove the value from the stack again // * // * stack now contains: -1 => table // */ - // lua_pop(L, 1); + // lua_pop(l, 1); // return 0; // } - // *ret = lua_tonumber(L, -1); + // *ret = lua_tonumber(l, -1); // /* // * stack now contains: -1 => table // */ - // lua_pop(L, 1); + // lua_pop(l, 1); // return 1; // } -static int plua_table_has_keys(lua_State *L, char **keys, int number) { - if(lua_istable(L, -1) == 0) { +static int plua_table_has_keys(lua_State *l, char **keys, int number) { + /* + * Check if we are called as a seperate lua thread + */ + assert(L != l); + + if(lua_istable(l, -1) == 0) { return 0; } @@ -173,15 +189,15 @@ static int plua_table_has_keys(lua_State *L, char **keys, int number) { * * stack now contains: -1 => table -2 => table */ - lua_pushvalue(L, -1); + lua_pushvalue(l, -1); /* * stack now contains: -1 => nil -2 => table -3 => table */ - lua_pushnil(L); + lua_pushnil(l); int match = 0, nrkeys = 0; - while(lua_next(L, -2)) { + while(lua_next(l, -2)) { nrkeys++; /* @@ -191,9 +207,9 @@ static int plua_table_has_keys(lua_State *L, char **keys, int number) { * * stack now contains: -1 => key -2 => value; -3 => key -4 => table -5 => table */ - lua_pushvalue(L, -2); + lua_pushvalue(l, -2); - const char *k = lua_tostring(L, -1); // key + const char *k = lua_tostring(l, -1); // key for(i=0;i key -2 => table -3 => table */ - lua_pop(L, 2); + lua_pop(l, 2); } /* * After the last lua_next call stack now contains: @@ -222,22 +238,27 @@ static int plua_table_has_keys(lua_State *L, char **keys, int number) { * * stack now contains -1 => table */ - lua_pop(L, 1); + lua_pop(l, 1); return 1; } -static int plua_module_init(struct lua_State *L, char *file, struct plua_module_t *mod) { +static int plua_module_init(struct lua_State *l, char *file, struct plua_module_t *mod) { + /* + * Check if we are called as a seperate lua thread + */ + assert(L != l); + /* * Function info is at top of stack * * stack now contains -1 => function */ #if LUA_VERSION_NUM <= 502 - lua_getfield(L, -1, "info"); - if(strcmp(lua_typename(L, lua_type(L, -1)), "function") != 0) { + lua_getfield(l, -1, "info"); + if(strcmp(lua_typename(l, lua_type(l, -1)), "function") != 0) { #else - if(lua_getfield(L, -1, "info") == 0) { + if(lua_getfield(l, -1, "info") == 0) { #endif logprintf(LOG_ERR, "%s: info function missing", file); return 0; @@ -248,41 +269,41 @@ static int plua_module_init(struct lua_State *L, char *file, struct plua_module_ * * stack now contains -1 => function */ - if(lua_pcall(L, 0, 1, 0) == LUA_ERRRUN) { - if(strcmp(lua_typename(L, lua_type(L, -1)), "string") == 0) { - logprintf(LOG_ERR, "%s", lua_tostring(L, -1)); - lua_pop(L, 1); + if(lua_pcall(l, 0, 1, 0) == LUA_ERRRUN) { + if(strcmp(lua_typename(l, lua_type(l, -1)), "string") == 0) { + logprintf(LOG_ERR, "%s", lua_tostring(l, -1)); + lua_pop(l, 1); return 0; } } - if(lua_istable(L, -1) == 0) { - logprintf(LOG_ERR, "%s: the info function returned %s, table expected", file, lua_typename(L, lua_type(L, -1))); + if(lua_istable(l, -1) == 0) { + logprintf(LOG_ERR, "%s: the info function returned %s, table expected", file, lua_typename(l, lua_type(l, -1))); return 0; } char *keys[12] = {"name", "version", "reqversion", "reqcommit"}; - if(plua_table_has_keys(L, keys, 4) == 0) { + if(plua_table_has_keys(l, keys, 4) == 0) { logprintf(LOG_ERR, "%s: the info table has invalid keys", file); return 0; } const char *name = NULL, *version = NULL, *reqversion = NULL, *reqcommit = NULL; - if(plua_get_table_string_by_key(L, "name", &name) == 0) { + if(plua_get_table_string_by_key(l, "name", &name) == 0) { logprintf(LOG_ERR, "%s: the info table 'name' key is missing or invalid", file); return 0; } - if(plua_get_table_string_by_key(L, "version", &version) == 0) { + if(plua_get_table_string_by_key(l, "version", &version) == 0) { logprintf(LOG_ERR, "%s: the info table 'version' key is missing or invalid", file); return 0; } - if(plua_get_table_string_by_key(L, "reqversion", &reqversion) == 0) { + if(plua_get_table_string_by_key(l, "reqversion", &reqversion) == 0) { logprintf(LOG_ERR, "%s: the info table 'reqversion' key is missing or invalid", file); return 0; } - if(plua_get_table_string_by_key(L, "reqcommit", &reqcommit) == 0) { + if(plua_get_table_string_by_key(l, "reqcommit", &reqcommit) == 0) { logprintf(LOG_ERR, "%s: the info table 'reqcommit' key is missing or invalid", file); return 0; } @@ -321,7 +342,7 @@ static int plua_module_init(struct lua_State *L, char *file, struct plua_module_ * * The stack now contains: nothing */ - lua_pop(L, 1); + lua_pop(l, 1); return 0; } @@ -330,7 +351,7 @@ static int plua_module_init(struct lua_State *L, char *file, struct plua_module_ * * The stack now contains: nothing */ - lua_pop(L, 1); + lua_pop(l, 1); return 1; } @@ -339,6 +360,7 @@ void plua_module_load(char *file, int type) { return; } + struct lua_State *l = lua_newthread(L); struct plua_module_t *module = MALLOC(sizeof(struct plua_module_t)); char name[255] = { '\0' }, *p = name; @@ -346,27 +368,27 @@ void plua_module_load(char *file, int type) { OUT_OF_MEMORY } - if(luaL_dofile(L, file) != 0) { - logprintf(LOG_ERR, "%s", lua_tostring(L, 1)); - lua_pop(L, 1); + if(luaL_dofile(l, file) != 0) { + logprintf(LOG_ERR, "%s", lua_tostring(l, 1)); + lua_pop(l, 1); } - if(lua_istable(L, -1) == 0) { + if(lua_istable(l, -1) == 0) { logprintf(LOG_ERR, "%s: does not return a table"); - lua_pop(L, 1); + lua_pop(l, 1); return; } module->type = type; strcpy(module->file, file); - if(plua_module_init(L, file, module) != 0) { + if(plua_module_init(l, file, module) != 0) { memset(p, '\0', sizeof(name)); switch(module->type) { case OPERATOR: sprintf(p, "operator.%s", module->name); break; } - lua_setglobal(L, name); + lua_setglobal(l, name); module->next = modules; modules = module; @@ -438,6 +460,7 @@ int plua_module_exists(char *module, int type) { if(L == NULL) { return 1; } + struct lua_State *l = lua_newthread(L); char name[255], *p = name; memset(name, '\0', 255); @@ -447,16 +470,16 @@ int plua_module_exists(char *module, int type) { } break; } - lua_getglobal(L, name); - if(lua_isnil(L, -1) != 0) { - lua_pop(L, -1); + lua_getglobal(l, name); + if(lua_isnil(l, -1) != 0) { + lua_pop(l, -1); return -1; } - if(lua_istable(L, -1) == 0) { - lua_pop(L, -1); + if(lua_istable(l, -1) == 0) { + lua_pop(l, -1); return -1; } - lua_pop(L, -1); + lua_pop(l, -1); return 0; }