From: Jo-Philipp Wich Date: Fri, 26 Aug 2022 12:11:57 +0000 (+0200) Subject: ucode-mod-lua: various fixes X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=629eb171b7ec47c7f608962d013a4f7894fac00d;p=project%2Fluci.git ucode-mod-lua: various fixes Properly handle accesses to properties of the userdatum itself in the lua_uv_index() __index metamethod and treat integer keys as array indexes in case of wrapped ucode array values. Also fix an incorrect refcount decrement in the function. Also fix uc_lua_vm_get() and uc_lua_lv_getraw() to gracefully handle accesses to not defined or non-table values and ensure that those functions properly reset the Lua stack after they complete. Signed-off-by: Jo-Philipp Wich --- diff --git a/contrib/package/ucode-mod-lua/src/lua.c b/contrib/package/ucode-mod-lua/src/lua.c index 241f4a92ff..ff94d60d8b 100644 --- a/contrib/package/ucode-mod-lua/src/lua.c +++ b/contrib/package/ucode-mod-lua/src/lua.c @@ -460,17 +460,20 @@ lua_uv_index(lua_State *L) { ucv_userdata_t *ud = luaL_checkudata(L, 1, "ucode.value"); const char *key = luaL_checkstring(L, 2); - uc_value_t *proto, *rv; - bool found; + long long idx; + char *e; - proto = ucv_prototype_get(ud->uv); - rv = ucv_object_get(proto, key, &found); + if (ucv_type(ud->uv) == UC_ARRAY) { + idx = strtoll(key, &e, 10); - if (!found) - return 0; + if (e != key && *e == 0 && idx >= 1 && idx <= (long long)ucv_array_length(ud->uv)) { + ucv_to_lua(ud->vm, ucv_array_get(ud->uv, (size_t)(idx - 1)), L, NULL); - ucv_to_lua(ud->vm, rv, L, NULL); - ucv_put(rv); + return 1; + } + } + + ucv_to_lua(ud->vm, ucv_property_get(ud->uv, key), L, NULL); return 1; } @@ -687,13 +690,22 @@ uc_lua_vm_get(uc_vm_t *vm, size_t nargs) uc_value_t *key = uc_fn_arg(0); lua_resource_t *lv; size_t i; + int top; if (!L || !*L || ucv_type(key) != UC_STRING) return NULL; + top = lua_gettop(*L); + lua_getglobal(*L, ucv_string_get(key)); for (i = 1; i < nargs; i++) { + if (lua_type(*L, -1) != LUA_TTABLE) { + lua_settop(*L, top); + + return NULL; + } + ucv_to_lua(vm, uc_fn_arg(i), *L, NULL); lua_gettable(*L, -2); } @@ -702,8 +714,7 @@ uc_lua_vm_get(uc_vm_t *vm, size_t nargs) lv->ref = luaL_ref(*L, LUA_REGISTRYINDEX); lv->uvL = ucv_this_to_uvL(vm); - if (nargs > 1) - lua_pop(*L, nargs - 1); + lua_settop(*L, top); return uc_resource_new(lv_type, lv); } @@ -788,15 +799,24 @@ uc_lua_lv_get_common(uc_vm_t *vm, size_t nargs, bool raw) lua_State *L = uc_lua_lv_to_L(lv); uc_value_t *key; size_t i; + int top; if (!L) return NULL; + top = lua_gettop(L); + lua_rawgeti(L, LUA_REGISTRYINDEX, (*lv)->ref); for (i = 0; i < nargs; i++) { key = uc_fn_arg(i); + if (lua_type(L, -1) != LUA_TTABLE) { + lua_settop(L, top); + + return NULL; + } + if (raw) { if (ucv_type(key) == UC_INTEGER) { lua_rawgeti(L, -1, (int)ucv_int64_get(key)); @@ -816,7 +836,7 @@ uc_lua_lv_get_common(uc_vm_t *vm, size_t nargs, bool raw) ref->ref = luaL_ref(L, LUA_REGISTRYINDEX); ref->uvL = ucv_this_to_uvL(vm); - lua_pop(L, nargs); + lua_settop(L, top); return uc_resource_new(lv_type, ref); }