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
2020static 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
4340static 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
4845static 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