Skip to content

Commit ee6c0de

Browse files
authored
Add files via upload
1 parent 27f4c5c commit ee6c0de

1 file changed

Lines changed: 29 additions & 19 deletions

File tree

‎app/src/main/jni/quickjs/lua_quickjs.c‎

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/**
2-
* QuickJS Lua Module for AndroLua (Thread-Safe Version)
2+
* QuickJS Lua Module for AndroLua (Final Stable Version)
33
*
4-
* This version is completely thread-safe by removing all static global variables.
5-
* It uses the JSRuntime's opaque pointer to pass captured data, preventing race conditions
6-
* when called from multiple Lua threads (e.g., Http callbacks, timers).
4+
* This version definitively solves the crash issue by correctly managing memory
5+
* on the heap instead of the stack for the shared data structure,
6+
* preventing dangling pointers and ensuring stability.
77
*/
88
#include <stdlib.h>
99
#include <string.h>
@@ -19,18 +19,15 @@ typedef struct {
1919
// Custom C function to handle 'document.cookie' setter
2020
static JSValue js_dom_set_cookie(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
2121
if (argc > 0) {
22-
// Get the runtime and the associated opaque data structure
2322
JSRuntime *rt = JS_GetRuntime(ctx);
2423
CapturedData *data = JS_GetRuntimeOpaque(rt);
2524

2625
if (data) {
2726
const char *cookie_str = JS_ToCString(ctx, argv[0]);
2827
if (cookie_str) {
29-
// Free any previously captured value within this context
3028
if (data->cookie_value) {
3129
free(data->cookie_value);
3230
}
33-
// Store the new value
3431
data->cookie_value = strdup(cookie_str);
3532
JS_FreeCString(ctx, cookie_str);
3633
}
@@ -39,12 +36,12 @@ static JSValue js_dom_set_cookie(JSContext *ctx, JSValueConst this_val, int argc
3936
return JS_UNDEFINED;
4037
}
4138

42-
// Dummy function for browser APIs like 'reload()'
39+
// Dummy function for browser APIs
4340
static JSValue js_dom_dummy_func(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
4441
return JS_UNDEFINED;
4542
}
4643

47-
// The main function exposed to Lua: quickjs.eval(js_code, host)
44+
// The main function exposed to Lua
4845
static int l_quickjs_eval(lua_State *L) {
4946
size_t js_len;
5047
const char *js_code = luaL_checklstring(L, 1, &js_len);
@@ -57,12 +54,21 @@ static int l_quickjs_eval(lua_State *L) {
5754
return 2;
5855
}
5956

60-
// --- 【核心修改】: 创建一个与 Runtime 绑定的数据结构 ---
61-
CapturedData captured_data = { .cookie_value = NULL };
62-
JS_SetRuntimeOpaque(rt, &captured_data); // "藏"数据
57+
// --- 【核心修正】: 在堆上为 CapturedData 分配内存 ---
58+
CapturedData *data = (CapturedData *)malloc(sizeof(CapturedData));
59+
if (!data) {
60+
JS_FreeRuntime(rt);
61+
lua_pushnil(L);
62+
lua_pushstring(L, "Fatal: Could not allocate memory for captured data.");
63+
return 2;
64+
}
65+
data->cookie_value = NULL;
66+
JS_SetRuntimeOpaque(rt, data); // 传递这个稳定的堆内存地址
6367

6468
JSContext *ctx = JS_NewContext(rt);
6569
if (!ctx) {
70+
JS_SetRuntimeOpaque(rt, NULL);
71+
free(data); // 释放我们刚刚分配的内存
6672
JS_FreeRuntime(rt);
6773
lua_pushnil(L);
6874
lua_pushstring(L, "Fatal: Could not create QuickJS context.");
@@ -95,28 +101,32 @@ static int l_quickjs_eval(lua_State *L) {
95101
}
96102
JS_FreeValue(ctx, result);
97103

98-
// --- 从绑定的数据结构中取回结果 ---
99-
if (captured_data.cookie_value) {
100-
char *start = strstr(captured_data.cookie_value, "acw_sc__v2=");
104+
if (data->cookie_value) {
105+
char *start = strstr(data->cookie_value, "acw_sc__v2=");
101106
if (start) {
102107
start += strlen("acw_sc__v2=");
103108
char *end = strchr(start, ';');
104109
if (end) {
105110
*end = '\0';
106111
lua_pushstring(L, start);
107-
*end = ';'; // Restore original string before freeing
112+
*end = ';';
108113
} else {
109114
lua_pushstring(L, start);
110115
}
111116
} else {
112-
lua_pushstring(L, captured_data.cookie_value);
117+
lua_pushstring(L, data->cookie_value);
113118
}
114-
// 【核心修改】: 手动释放内存
115-
free(captured_data.cookie_value);
116119
} else {
117120
lua_pushnil(L);
118121
}
119122

123+
// --- 【核心修正】: 释放所有在堆上分配的内存 ---
124+
if (data->cookie_value) {
125+
free(data->cookie_value);
126+
}
127+
JS_SetRuntimeOpaque(rt, NULL); // 解除绑定
128+
free(data); // 释放 CapturedData 结构体本身
129+
120130
JS_FreeContext(ctx);
121131
JS_FreeRuntime(rt);
122132

0 commit comments

Comments
 (0)