11/**
2- * QuickJS Lua Module for AndroLua
2+ * QuickJS Lua Module for AndroLua (Robust Version)
33 *
4- * This module embeds the QuickJS engine and provides a 'quickjs.eval' function.
5- * It simulates a minimal browser DOM to execute JS code that relies on objects
6- * like 'document' and 'location', specifically to capture cookie values.
4+ * This version includes critical checks for memory allocation and uses safer
5+ * string handling to prevent crashes.
76 */
87#include <stdlib.h>
98#include <string.h>
@@ -37,40 +36,52 @@ static JSValue js_dom_dummy_func(JSContext *ctx, JSValueConst this_val, int argc
3736
3837// The main function exposed to Lua: quickjs.eval(js_code, host)
3938static int l_quickjs_eval (lua_State * L ) {
40- const char * js_code = luaL_checkstring (L , 1 );
39+ // 【修正 1】: 使用 luaL_checklstring 获取字符串和其真实长度
40+ size_t js_len ;
41+ const char * js_code = luaL_checklstring (L , 1 , & js_len );
4142 const char * host = luaL_optstring (L , 2 , "localhost" );
4243
44+ // 【修正 2】: 严格检查 QuickJS Runtime 和 Context 是否创建成功
4345 JSRuntime * rt = JS_NewRuntime ();
46+ if (!rt ) {
47+ lua_pushnil (L );
48+ lua_pushstring (L , "Fatal: Could not create QuickJS runtime." );
49+ return 2 ;
50+ }
51+
4452 JSContext * ctx = JS_NewContext (rt );
53+ if (!ctx ) {
54+ JS_FreeRuntime (rt );
55+ lua_pushnil (L );
56+ lua_pushstring (L , "Fatal: Could not create QuickJS context." );
57+ return 2 ;
58+ }
4559
4660 if (captured_cookie_value ) {
4761 free (captured_cookie_value );
4862 captured_cookie_value = NULL ;
4963 }
5064
65+ // --- 创建 DOM 模拟环境 (DOM Shim) ---
5166 JSValue global_obj = JS_GetGlobalObject (ctx );
52-
5367 JSValue location = JS_NewObject (ctx );
5468 JS_SetPropertyStr (ctx , location , "host" , JS_NewString (ctx , host ));
5569 JS_SetPropertyStr (ctx , global_obj , "location" , location );
56-
5770 JSValue document = JS_NewObject (ctx );
5871 JS_SetPropertyStr (ctx , global_obj , "document" , document );
59-
6072 JSValue doc_location = JS_NewObject (ctx );
6173 JS_SetPropertyStr (ctx , doc_location , "reload" , JS_NewCFunction (ctx , js_dom_dummy_func , "reload" , 0 ));
6274 JS_SetPropertyStr (ctx , document , "location" , doc_location );
63-
64- // ** CRITICAL PART - FIX **
65- // Define the 'cookie' property on the 'document' object.
66- // The 'getter' is set to UNDEFINED because we only care about intercepting the 'setter'.
6775 JS_DefineProperty (ctx , document , JS_NewAtom (ctx , "cookie" ), JS_UNDEFINED ,
68- JS_UNDEFINED , // 【修正】: 添加了 JS_UNDEFINED 作为 getter 参数,补全为7个参数
76+ JS_UNDEFINED ,
6977 JS_NewCFunction (ctx , js_dom_set_cookie , "set" , 1 ),
7078 JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE );
7179
72- JSValue result = JS_Eval (ctx , js_code , strlen (js_code ), "<eval>" , JS_EVAL_TYPE_GLOBAL );
80+ // --- 执行 JS 代码 ---
81+ // 使用从 Lua 获取到的真实长度 js_len
82+ JSValue result = JS_Eval (ctx , js_code , js_len , "<eval>" , JS_EVAL_TYPE_GLOBAL );
7383
84+ // --- 异常处理 ---
7485 if (JS_IsException (result )) {
7586 JSValue exception = JS_GetException (ctx );
7687 const char * error_str = JS_ToCString (ctx , exception );
@@ -85,6 +96,7 @@ static int l_quickjs_eval(lua_State *L) {
8596 }
8697 JS_FreeValue (ctx , result );
8798
99+ // --- 返回结果 ---
88100 if (captured_cookie_value ) {
89101 char * start = strstr (captured_cookie_value , "acw_sc__v2=" );
90102 if (start ) {
@@ -104,6 +116,7 @@ static int l_quickjs_eval(lua_State *L) {
104116 lua_pushnil (L );
105117 }
106118
119+ // --- 清理资源 ---
107120 JS_FreeContext (ctx );
108121 JS_FreeRuntime (rt );
109122
0 commit comments