From 2999d3412ccf5c7fc1a9e84695c7a2bce69d3e82 Mon Sep 17 00:00:00 2001 From: ame Date: Thu, 13 Jun 2024 00:01:51 -0500 Subject: working on deepcopy ub --- src/hash/md5.c | 4 ++- src/io.c | 4 +++ src/lua.c | 70 +++++++++++++++++++++++------------------ src/lua.h | 16 +++++++++- src/net.c | 2 +- src/reg.c | 2 +- src/thread.c | 99 ++++++++++++++++++++++++++++++++++++++++++++-------------- tests/h.lua | 12 ++++--- tests/s.lua | 13 ++++++++ 9 files changed, 160 insertions(+), 62 deletions(-) diff --git a/src/hash/md5.c b/src/hash/md5.c index 2e6ad98..78211cd 100644 --- a/src/hash/md5.c +++ b/src/hash/md5.c @@ -106,6 +106,7 @@ void md5_update(uint8_t* input, size_t len, struct md5_hash* hash){ void md5_final(struct md5_hash* hash, char out_stream[64]){ uint8_t old[bs]; struct md5_hash old_hash; + memcpy(&old_hash, hash, sizeof * hash); memcpy(old, hash->buffer, bs); @@ -119,7 +120,8 @@ void md5_final(struct md5_hash* hash, char out_stream[64]){ } uint32_t lhhh = 8*hash->total; - memcpy(hash->buffer + 56, &lhhh, sizeof(lhhh)); + memcpy(hash->buffer + 56, &lhhh, 4); + md5_round(hash); sprintf(out_stream,"%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", diff --git a/src/io.c b/src/io.c index d86283d..97c7e33 100644 --- a/src/io.c +++ b/src/io.c @@ -147,6 +147,10 @@ void i_pprint(lua_State* L, int indent, int skip_indent){ if(!skip_indent) print_indentation(indent); printf(color_yellow"(lud,%p)"color_reset, lua_topointer(L,-1)); break; + //case LUA_TNUMBER: + if(!skip_indent) print_indentation(indent); + printf(color_yellow"%i"color_reset, (int)lua_tonumber(L,-1)); + break; default: if(!skip_indent) print_indentation(indent); printf(color_yellow"%s"color_reset, lua_tostring(L,-1)); diff --git a/src/lua.c b/src/lua.c index 05489e1..8a39af1 100644 --- a/src/lua.c +++ b/src/lua.c @@ -42,10 +42,7 @@ int writer(lua_State *L, const void* p, size_t sz, void* ud){ * @param {void*} items already visited, use NULL * @param {int} whether or not to skip meta data */ -void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int skip_meta){ - parray_t* seen = (parray_t*)_seen; - int wnull = seen == NULL; - if(wnull) seen = parray_init(); +void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags flags){ size_t len; //printf("%i\n",seen->len); int at, at2; @@ -57,46 +54,63 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int skip_meta){ int old_top = lua_gettop(src); int modi = 0; +#define q lua_pushnumber(dest, 5); break; switch(lua_type(src, -1)){ case LUA_TNUMBER: - n = luaL_checknumber(src, -1); + n = lua_tonumber(src, -1); if(n == (int)n) lua_pushinteger(dest, (int)n); else lua_pushnumber(dest, n); break; - case LUA_TSTRING: - s = (char*)luaL_checklstring(src, -1, &len); - lua_pushlstring(dest, s, len); + case LUA_TSTRING:; + //seems to have some "ub" here, lua_pushlstring can overrite arbitrary data? + //has a chance to override other userdata, still testing this + size_t slen; + const char* ss = lua_tolstring(src, -1, &slen); + lua_pushlstring(dest, ss, slen); break; case LUA_TTABLE: modi = 1; lua_newtable(dest); at = lua_gettop(dest); at2 = lua_gettop(src); - char aauwu[50] = {0}; + //printf("before\n"); + char* aauwu = calloc(sizeof * aauwu, 50); sprintf(aauwu, "%p", lua_topointer(src, at2)); - - whar = parray_get(seen, aauwu); - if(whar != NULL){ - lua_pop(dest, 1); - lua_rawgeti(dest, LUA_REGISTRYINDEX, *(int*)whar); - return; + //lua_pushstring(dest, aauwu); + //lua_gettable(dest, LUA_REGISTRYINDEX); + lua_getfield(dest, LUA_REGISTRYINDEX, aauwu); + if(lua_type(dest, -1) == LUA_TNIL){ + //printf("new %p\n", lua_topointer(src, at2)); + lua_pushstring(dest, aauwu); + lua_pushvalue(dest, at); + lua_settable(dest, LUA_REGISTRYINDEX); + lua_pop(dest, 1); + } else { + //printf("use %p\n", lua_topointer(src, at2)); + //lua_pop(dest, 1); + lua_remove(dest, -2); + return; } - int *sp = malloc(sizeof * sp); - - int r = luaL_ref(dest, LUA_REGISTRYINDEX); - lua_rawgeti(dest, LUA_REGISTRYINDEX, r); - *sp = r; - parray_set(seen, aauwu, sp); + free(aauwu); + //printf("after %i:%i\n", at, lua_gettop(dest)); lua_pushnil(src); for(;lua_next(src, at2) != 0;){ int first, second = first = lua_gettop(src); first -= 1; + if((flags & SKIP_GC) && lua_type(src, first) == LUA_TSTRING + && strcmp("__gc", lua_tostring(src, first)) == 0){ + //printf("found %s\n", lua_tostring(src, first)); + lua_pop(src, 1); + continue; + } lua_pushvalue(src, first); - luaI_deepcopy(src, dest, seen, 0); + //l_pprint(src); + //lua_pop(src, 1); + luaI_deepcopy(src, dest, flags); lua_pushvalue(src, second); - luaI_deepcopy(src, dest, seen, 0); + luaI_deepcopy(src, dest, flags); lua_settable(dest, at); lua_pop(src, 3); @@ -111,10 +125,9 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int skip_meta){ str* awa = str_init(""); lua_dump(src, writer, (void*)awa, 0); - lua_pushlstring(dest, awa->c, awa->len); luaL_loadbuffer(dest, awa->c, awa->len, awa->c); - lua_remove(dest, -2); + //lua_remove(dest, -2); str_free(awa); break; case LUA_TUSERDATA: @@ -135,16 +148,13 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int skip_meta){ int tidx = lua_gettop(dest); int aa = lua_gettop(src); - if(modi&&!skip_meta&&lua_getmetatable(src, -1)){ - luaI_deepcopy(src, dest, seen, 1); + if(modi && !(flags & SKIP_META) && lua_getmetatable(src, -1)){ + luaI_deepcopy(src, dest, flags | IS_META | SKIP_META); lua_setmetatable(dest, tidx); lua_settop(dest, tidx); } lua_settop(src, aa); - - if(wnull) parray_clear(seen, FREE); - _seen = seen; } /** diff --git a/src/lua.h b/src/lua.h index 6cb28a7..3328db5 100644 --- a/src/lua.h +++ b/src/lua.h @@ -3,11 +3,21 @@ #include #include +#ifndef __lua_h +#define __lua_h +enum deep_copy_flags { + SKIP_META = (1 << 0), + SKIP_GC = (1 << 1), + IS_META = (1 << 2) +}; +#endif + void* __malloc_(size_t); void __free_(void*); -void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int); +void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags); void lua_set_global_table(lua_State*); +//todo: char* _luaL_tolstring(lua_State*, int, size_t*); //generic macro that takes other macros (see below) #define _tset_b(L, Tidx, K, V, F)\ @@ -50,6 +60,8 @@ int writer(lua_State*, const void*, size_t, void*); #define lua_objlen(L,i) lua_rawlen(L,(i)) #define luaL_register(L, M, F) luaL_newlib(L, F); #else + //todo: #define luaL_tolstring(L, idx, n) _luaL_tolstring(L, idx, n) + #define lreg(N, FN)\ lua_newtable(L);\ luaL_register(L, NULL, FN);\ @@ -80,6 +92,8 @@ int writer(lua_State*, const void*, size_t, void*); lua_pop(L, 1);\ }\ } + + #endif diff --git a/src/net.c b/src/net.c index 36deb0f..cbaf789 100644 --- a/src/net.c +++ b/src/net.c @@ -754,7 +754,7 @@ void* handle_client(void *_arg){ lua_getglobal(args->L, "_G"); //time_start(copy) - luaI_deepcopy(args->L, L, NULL, 0); + luaI_deepcopy(args->L, L, 0); //time_end("copy", copy) lua_settop(args->L, old_top); diff --git a/src/reg.c b/src/reg.c index 417062a..13d5866 100644 --- a/src/reg.c +++ b/src/reg.c @@ -31,7 +31,7 @@ int luaopen_llib(lua_State* L) { luaI_tsetcf(L, meta, "__gc", lua_exit); lua_pushvalue(L, meta); lua_setmetatable(L, ud); - + //create .array functions lua_newtable(L); diff --git a/src/thread.c b/src/thread.c index dec9ceb..5b3cb11 100644 --- a/src/thread.c +++ b/src/thread.c @@ -97,7 +97,7 @@ int l_res(lua_State* L){ int ot = lua_gettop(L); lua_pushvalue(L, 2 + i); - luaI_deepcopy(L, info->L, NULL, 0); + luaI_deepcopy(L, info->L, 0); lua_settop(L, ot); } @@ -149,7 +149,7 @@ int l_await(lua_State* L){ int ot = lua_gettop(info->L); lua_pushvalue(info->L, ot - info->return_count + i); - luaI_deepcopy(info->L, L, NULL, 0); + luaI_deepcopy(info->L, L, 0); lua_settop(info->L, ot); } @@ -176,17 +176,18 @@ int l_clean(lua_State* L){ } int l_async(lua_State* oL){ - lua_State* L = luaL_newstate(); - - //luaL_openlibs(L); + lua_State* L = luaL_newstate(); lua_getglobal(oL, "_G"); - luaI_deepcopy(oL, L, NULL, 0); - lua_set_global_table(L); + luaI_deepcopy(oL, L, SKIP_GC); + //lua_set_global_table(L); + + return 0; struct thread_info* args = calloc(1, sizeof * args); args->L = L; - args->lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + //args->lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&args->lock, NULL); pthread_mutex_lock(&args->lock); args->return_count = 0; @@ -221,7 +222,7 @@ struct thread_buffer { int _buffer_get(lua_State* L){ struct thread_buffer *buffer = lua_touserdata(L, 1); pthread_mutex_lock(&buffer->lock); - luaI_deepcopy(buffer->L, L, NULL, 0); + luaI_deepcopy(buffer->L, L, 0); pthread_mutex_unlock(&buffer->lock); return 1; } @@ -230,7 +231,7 @@ int _buffer_set(lua_State* L){ struct thread_buffer *buffer = lua_touserdata(L, 1); pthread_mutex_lock(&buffer->lock); lua_settop(buffer->L, 0); - luaI_deepcopy(L, buffer->L, NULL, 0); + luaI_deepcopy(L, buffer->L, 0); pthread_mutex_unlock(&buffer->lock); return 1; } @@ -238,7 +239,7 @@ int _buffer_set(lua_State* L){ int _buffer_mod(lua_State* L){ struct thread_buffer *buffer = lua_touserdata(L, 1); pthread_mutex_lock(&buffer->lock); - luaI_deepcopy(buffer->L, L, NULL, 0); + luaI_deepcopy(buffer->L, L, 0); int item = lua_gettop(L); lua_pushvalue(L, 2); lua_pushvalue(L, item); @@ -246,7 +247,7 @@ int _buffer_mod(lua_State* L){ if(lua_type(L, -1) != LUA_TNIL){ lua_settop(buffer->L, 0); - luaI_deepcopy(L, buffer->L, NULL, 0); + luaI_deepcopy(L, buffer->L, 0); } pthread_mutex_unlock(&buffer->lock); return 1; @@ -276,27 +277,79 @@ int l_buffer_index(lua_State* L){ return 1; } -int l_buffer(lua_State* L){ - struct thread_buffer *buffer = malloc(sizeof * buffer); - buffer->L = luaL_newstate(); - pthread_mutex_init(&buffer->lock, NULL); - luaI_deepcopy(L, buffer->L, NULL, 0); +int hi(lua_State* L){ + printf("hi\n"); + return 0; +} + +int meta_proxy(lua_State* L){ + printf("proxy"); + return 1; +} + +void meta_proxy_gen(lua_State* L, int meta_idx, int new_meta_idx){ + + lua_pushnil(L); + for(; lua_next(L, meta_idx) != 0;){ + int k, v = lua_gettop(L); + k = lua_gettop(L) - 1; + + lua_pushcfunction(L, meta_proxy); + lua_setglobal(L, "__proxy_call"); + + char* fn = calloc(128, sizeof * fn); //todo: find optimal value for these + const char* key = lua_tostring(L, k); + sprintf(fn, "return function(_a,_b,_c)\ +return __proxy_call('%s',table.unpack({_a,_b,_c}));end", key); + luaL_dostring(L, fn); + //printf("%s\n",fn); + free(fn); + int nf = lua_gettop(L); + + luaI_tsetv(L, new_meta_idx, lua_tostring(L, k), nf); + + lua_pop(L, 3); + } +} + +int l_buffer_gc(lua_State* L){ + printf("gc\n"); + struct thread_buffer *buffer = lua_touserdata(L, 1); + pthread_mutex_lock(&buffer->lock); + lua_close(buffer->L); + return 0; +} + +int l_buffer(lua_State* L){ + int use = lua_getmetatable(L, 1); + int old_meta_idx = lua_gettop(L); lua_newtable(L); int meta_idx = lua_gettop(L); + if(use!=0) meta_proxy_gen(L, old_meta_idx, meta_idx); luaI_tsetcf(L, meta_idx, "__index", l_buffer_index); + luaI_tsetcf(L, meta_idx, "__gc", l_buffer_gc); - lua_pushlightuserdata(L, buffer); - lua_pushvalue(L, meta_idx); - lua_setmetatable(L, -2); + struct thread_buffer *buffer = lua_newuserdata(L, sizeof * buffer); + int buffer_idx = lua_gettop(L); + + buffer->L = luaL_newstate(); + pthread_mutex_init(&buffer->lock, NULL); + lua_pushvalue(L, 1); + luaI_deepcopy(L, buffer->L, SKIP_GC); + lua_pushvalue(L, meta_idx); + lua_setmetatable(L, buffer_idx); + lua_pushvalue(L, buffer_idx); return 1; } int l_testcopy(lua_State* L){ + lua_settop(L, 0); lua_State* temp = luaL_newstate(); - luaI_deepcopy(L, temp, NULL, 0); - luaI_deepcopy(temp, L, NULL, 0); - + lua_getglobal(L, "_G"); + luaI_deepcopy(L, temp, SKIP_GC); + //luaI_deepcopy(temp, L, NULL, SKIP_GC); + lua_close(temp); return 1; } diff --git a/tests/h.lua b/tests/h.lua index 412d09c..0913892 100644 --- a/tests/h.lua +++ b/tests/h.lua @@ -6,15 +6,17 @@ llib.config.set({print_meta=1,max_depth=22}) --llib.thread.unlock(2) a = llib.thread.buffer(llib.crypto.md5()) -a:mod(function(e) return e end) -print("hi") -for i=1,20 do + +print(a:get():final()) +for i=1,2009 do llib.thread.async(function (res) - a:mod(function(e) return e:update("meow") end) + --llib.io.pprint(a); + --l = a + a + --a:mod(function(e) return e:update("meow") end) end) end -os.execute("sleep 1") +--os.execute("sleep 1") print(a:get():final()) --print("unlock") --llib.thread.unlock(1) diff --git a/tests/s.lua b/tests/s.lua index bac5072..929c127 100644 --- a/tests/s.lua +++ b/tests/s.lua @@ -1,2 +1,15 @@ +local t = function (a) end + require "llib" +a = llib.crypto.md5() + +for i = 1,200 do + --llib.io.pprint(function (a) end) + llib.thread.async(function(a) end)--:await() +end + +if a:final() ~= "d41d8cd98f00b204e9800998ecf8427e" then + print(a:final()) +end + -- cgit v1.2.3