From 89a95d4776098c0d70653eebdc4f455f2e8e341d Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 7 Jan 2016 01:13:08 -0800 Subject: [PATCH] Protect system, add process.argv and global print. --- Console.cpp | 13 ++++++---- Execute.cpp | 65 +++++++++++++++++++++++++++++++++++++------------- JavaScript.hpp | 2 +- libcycript.cy | 6 ++--- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/Console.cpp b/Console.cpp index 43012ac..f4f5b10 100644 --- a/Console.cpp +++ b/Console.cpp @@ -829,6 +829,8 @@ int Main(int argc, char * const argv[], char const * const envp[]) { const char *host(NULL); const char *port(NULL); + const char *argv0(argv[0]); + optind = 1; for (;;) { @@ -1007,15 +1009,18 @@ int Main(int argc, char * const argv[], char const * const envp[]) { if (argc == 0) script = NULL; else { -#ifdef CY_EXECUTE - // XXX: const_cast?! wtf gcc :( - CYSetArgs(argc - 1, const_cast(argv + 1)); -#endif script = argv[0]; if (strcmp(script, "-") == 0) script = NULL; + --argc; + ++argv; } +#ifdef CY_EXECUTE + // XXX: const_cast?! wtf gcc :( + CYSetArgs(argv0, script, argc, const_cast(argv)); +#endif + #ifdef CY_ATTACH if (pid == _not(pid_t)) client_ = -1; diff --git a/Execute.cpp b/Execute.cpp index db6c5ba..229e238 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -430,6 +430,22 @@ static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjec return CYJSUndefined(context); } CYCatch(NULL) } +static JSValueRef Global_print(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + FILE *file(stdout); + CYPool pool; + + for (size_t i(0); i != count; ++i) { + if (i != 0) + fputc(' ', file); + CYUTF8String string(CYPoolUTF8String(pool, context, CYJSString(context, arguments[i]))); + fwrite(string.data, string.size, 1, file); + } + + fputc('\n', file); + fflush(file); + return CYJSUndefined(context); +} CYCatch(NULL) } + static void (*JSSynchronousGarbageCollectForDebugging$)(JSContextRef); _visible void CYGarbageCollect(JSContextRef context) { @@ -1980,15 +1996,24 @@ static JSStaticFunction Type_staticFunctions[10] = { {NULL, NULL, 0} }; -_visible void CYSetArgs(int argc, const char *argv[]) { +_visible void CYSetArgs(const char *argv0, const char *script, int argc, const char *argv[]) { JSContextRef context(CYGetJSContext()); - JSValueRef args[argc]; + JSValueRef args[argc + 2]; for (int i(0); i != argc; ++i) - args[i] = CYCastJSValue(context, argv[i]); + args[i + 2] = CYCastJSValue(context, argv[i]); + + size_t offset; + if (script == NULL) + offset = 1; + else { + offset = 0; + args[1] = CYCastJSValue(context, CYJSString(script)); + } - JSObjectRef array(CYObjectMakeArray(context, argc, args)); - JSObjectRef System(CYGetCachedObject(context, CYJSString("System"))); - CYSetProperty(context, System, CYJSString("args"), array); + args[offset] = CYCastJSValue(context, CYJSString(argv0)); + + CYSetProperty(context, CYGetCachedObject(context, CYJSString("System")), CYJSString("args"), CYObjectMakeArray(context, argc, args + 2)); + CYSetProperty(context, CYGetCachedObject(context, CYJSString("process")), CYJSString("argv"), CYObjectMakeArray(context, argc + 2 - offset, args + offset)); } JSObjectRef CYGetGlobalObject(JSContextRef context) { @@ -2473,17 +2498,6 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { CYSetPrototype(context, last, cache); } - JSObjectRef System(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, cy, CYJSString("System"), System); - - CYSetProperty(context, global, CYJSString("require"), &require_callAsFunction, kJSPropertyAttributeDontEnum); - - CYSetProperty(context, global, CYJSString("system"), System); - CYSetProperty(context, System, CYJSString("args"), CYJSNull(context)); - CYSetProperty(context, System, CYJSString("print"), &System_print); - - CYSetProperty(context, global, CYJSString("global"), global); - #ifdef __APPLE__ if (&JSWeakObjectMapCreate != NULL) { JSWeakObjectMapRef weak(JSWeakObjectMapCreate(context, NULL, &CYDestroyWeak)); @@ -2522,6 +2536,23 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { CYSetProperty(context, cache, CYJSString("float"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); CYSetProperty(context, cache, CYJSString("double"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); + CYSetProperty(context, global, CYJSString("require"), &require_callAsFunction, kJSPropertyAttributeDontEnum); + + JSObjectRef System(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, all, CYJSString("system"), System); + System = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("system"))); + CYSetProperty(context, cy, CYJSString("System"), System); + + JSObjectRef process(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, global, CYJSString("process"), process); + CYSetProperty(context, cy, CYJSString("process"), process); + + CYSetProperty(context, System, CYJSString("args"), CYJSNull(context)); + CYSetProperty(context, System, CYJSString("print"), &System_print); + + CYSetProperty(context, global, CYJSString("global"), global); + CYSetProperty(context, global, CYJSString("print"), &Global_print); + for (CYHook *hook : GetHooks()) if (hook->SetupContext != NULL) (*hook->SetupContext)(context); diff --git a/JavaScript.hpp b/JavaScript.hpp index 47a9618..8b58024 100644 --- a/JavaScript.hpp +++ b/JavaScript.hpp @@ -69,7 +69,7 @@ const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code); void CYCancel(); #endif -void CYSetArgs(int argc, const char *argv[]); +void CYSetArgs(const char *argv0, const char *script, int argc, const char *argv[]); bool CYCastBool(JSContextRef context, JSValueRef value); double CYCastDouble(JSContextRef context, JSValueRef value); diff --git a/libcycript.cy b/libcycript.cy index 45caaf2..57e8894 100644 --- a/libcycript.cy +++ b/libcycript.cy @@ -19,10 +19,6 @@ **/ /* }}} */ -var process = { - env: {}, -}; - (function() { this.typeid = function(object) { @@ -428,6 +424,8 @@ process.binding = function(name) { return binding; }; +process.env = {}; + let environ = *(typedef char ***)(dlsym(RTLD_DEFAULT, "environ")); for (let i = 0; environ[i] != null; ++i) { let assign = environ[i]; -- 2.47.2