From: Jay Freeman (saurik) Date: Mon, 4 Jan 2016 23:13:07 +0000 (-0800) Subject: Embed core libraries for node.js in libcycript.db. X-Git-Tag: v0.9.590~59 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/849b0beafc5d722cd9abf4050430600d149cc342 Embed core libraries for node.js in libcycript.db. --- diff --git a/.gitmodules b/.gitmodules index 5d5f583..62da59d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,3 +8,6 @@ [submodule "libuv"] path = libuv url = https://github.com/joyent/libuv.git +[submodule "node"] + path = node + url = https://github.com/joyent/node.git diff --git a/Execute.cpp b/Execute.cpp index 986b88f..8cf7b91 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -2252,17 +2252,43 @@ static JSValueRef require_callAsFunction(JSContextRef context, JSObjectRef objec _assert(count == 1); CYPool pool; - const char *name(CYPoolCString(pool, context, arguments[0])); - if (strchr(name, '/') == NULL && ( + CYUTF8String name(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0]))); + if (memchr(name.data, '/', name.size) == NULL && ( #ifdef __APPLE__ - dlopen(pool.strcat("/System/Library/Frameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL || - dlopen(pool.strcat("/System/Library/PrivateFrameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL || + dlopen(pool.strcat("/System/Library/Frameworks/", name.data, ".framework/", name.data, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL || + dlopen(pool.strcat("/System/Library/PrivateFrameworks/", name.data, ".framework/", name.data, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL || #endif false)) return CYJSUndefined(context); - JSObjectRef resolve(CYCastJSObject(context, CYGetProperty(context, object, CYJSString("resolve")))); - CYJSString path(context, CYCallAsFunction(context, resolve, NULL, 1, arguments)); + CYJSString path; + CYUTF8String code; + + sqlite3_stmt *statement; + + _sqlcall(sqlite3_prepare(database_, + "select " + "\"module\".\"code\", " + "\"module\".\"flags\" " + "from \"module\" " + "where" + " \"module\".\"name\" = ?" + " limit 1" + , -1, &statement, NULL)); + + _sqlcall(sqlite3_bind_text(statement, 1, name.data, name.size, SQLITE_STATIC)); + + if (_sqlcall(sqlite3_step(statement)) != SQLITE_DONE) { + code.data = static_cast(sqlite3_column_blob(statement, 0)); + code.size = sqlite3_column_bytes(statement, 0); + path = CYJSString(name); + code = CYPoolUTF8String(pool, code); + } else { + JSObjectRef resolve(CYCastJSObject(context, CYGetProperty(context, object, CYJSString("resolve")))); + path = CYJSString(context, CYCallAsFunction(context, resolve, NULL, 1, arguments)); + } + + _sqlcall(sqlite3_finalize(statement)); CYJSString property("exports"); @@ -2274,11 +2300,13 @@ static JSValueRef require_callAsFunction(JSContextRef context, JSObjectRef objec JSObjectRef module(CYCastJSObject(context, cache)); result = CYGetProperty(context, module, property); } else { - CYUTF8String code(CYPoolFileUTF8String(pool, CYPoolCString(pool, context, path))); - _assert(code.data != NULL); + if (code.data == NULL) { + code = CYPoolFileUTF8String(pool, CYPoolCString(pool, context, path)); + _assert(code.data != NULL); + } - size_t length(strlen(name)); - if (length >= 5 && strcmp(name + length - 5, ".json") == 0) { + size_t length(name.size); + if (length >= 5 && strncmp(name.data + length - 5, ".json", 5) == 0) { JSObjectRef JSON(CYGetCachedObject(context, CYJSString("JSON"))); JSObjectRef parse(CYCastJSObject(context, CYGetProperty(context, JSON, CYJSString("parse")))); JSValueRef arguments[1] = { CYCastJSValue(context, CYJSString(code)) }; diff --git a/JavaScript.hpp b/JavaScript.hpp index 949d54e..47a9618 100644 --- a/JavaScript.hpp +++ b/JavaScript.hpp @@ -184,6 +184,11 @@ class CYJSString { } public: + CYJSString() : + string_(NULL) + { + } + CYJSString(const CYJSString &rhs) : string_(CYCopyJSString(rhs.string_)) { @@ -207,6 +212,11 @@ class CYJSString { return *this; } + CYJSString &operator =(CYJSString &&rhs) { + std::swap(string_, rhs.string_); + return *this; + } + ~CYJSString() { Clear_(); } diff --git a/Makefile.am b/Makefile.am index b80bb1e..75d25c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -85,8 +85,8 @@ AM_CPPFLAGS += -DCY_EXECUTE filters += C CLEANFILES += libcycript.db -libcycript.db: Bridge.def libcycript.sh - $(srcdir)/libcycript.sh $(CY_SYSTEM) $@ $< +libcycript.db: Bridge.def libcycript.py + $(srcdir)/libcycript.py $(CY_SYSTEM) $@ $(srcdir) <$< if CY_PRELINK CY_LANGFLAGS = -DCY_JAVA=$(CY_JAVA) -DCY_PYTHON=$(CY_PYTHON) -DCY_OBJECTIVEC=$(CY_OBJECTIVEC) diff --git a/Makefile.in b/Makefile.in index d9892a2..f0f8f72 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1426,8 +1426,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-datDATA \ .DELETE_ON_ERROR: -@CY_EXECUTE_TRUE@libcycript.db: Bridge.def libcycript.sh -@CY_EXECUTE_TRUE@ $(srcdir)/libcycript.sh $(CY_SYSTEM) $@ $< +@CY_EXECUTE_TRUE@libcycript.db: Bridge.def libcycript.py +@CY_EXECUTE_TRUE@ $(srcdir)/libcycript.py $(CY_SYSTEM) $@ $(srcdir) <$< @CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@Analyze: Analyze.cpp Error.cpp Output.cpp Replace.cpp Syntax.cpp @CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@ $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) -std=c++11 $(LDFLAGS_FOR_BUILD) $(CY_LANGFLAGS) -I$(srcdir)/extra -o $@ $^ $(CY_LIBCLANG) -Wno-bitwise-op-parentheses -Wno-dangling-else -Wno-logical-op-parentheses @CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@Bridge.def: Analysis.cpp Analyze diff --git a/build.mk b/build.mk index d415459..0aa2b59 100644 --- a/build.mk +++ b/build.mk @@ -92,7 +92,7 @@ $(deb): Cycript.lib/cycript-apl Cycript.lib/libcycript.dylib Cycript.lib/libcycr mkdir -p package/DEBIAN sed -e 's/#/$(version)/' control.in >package/DEBIAN/control mkdir -p package/usr/{bin,lib} - cp -a modules package/usr/lib/cycript0.9 + cp -a cycript0.9 package/usr/lib/cycript0.9 $(lipo) -extract armv6 -output package/usr/bin/cycript Cycript.lib/cycript-apl $(lipo) -extract armv6 -extract arm64 -output package/usr/lib/libcycript.dylib Cycript.lib/libcycript.dylib ln -s libcycript.dylib package/usr/lib/libcycript.0.dylib @@ -277,8 +277,7 @@ Cycript.lib/libcycript.cy: Cycript.lib/libcycript.db: $(db) @mkdir -p $(dir $@) - ./libcycript.sh 0 $@ - ./libcycript.py $@ $^ + ./libcycript.py 0 $@ $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) $^ dli_fname; +var slash = path.lastIndexOf('/'); +if (slash == -1) + return; + +var libsubstrate = dlopen(path.substr(0, slash) + "/libsubstrate.dylib", RTLD_GLOBAL | RTLD_LAZY); +if (libsubstrate == null) { + exports.error = dlerror(); + return; +} + +extern "C" void *MSGetImageByName(const char *); +extern "C" void *MSFindSymbol(void *, const char *); +extern "C" void MSHookFunction(void *, void *, void **); +extern "C" void MSHookMessageEx(Class, SEL, void *, void **); + +var slice = Array.prototype.slice; + +exports.getImageByName = MSGetImageByName; +exports.findSymbol = MSFindSymbol; + +exports.hookFunction = function(func, hook, old) { + var type = typeid(func); + + var pointer; + if (old == null || typeof old === "undefined") + pointer = null; + else { + pointer = new (typedef void **); + *old = function() { return type(*pointer).apply(null, arguments); }; + } + + MSHookFunction(func.valueOf(), type(hook), pointer); +}; + +exports.hookMessage = function(isa, sel, imp, old) { + var type = sel.type(isa); + + var pointer; + if (old == null || typeof old === "undefined") + pointer = null; + else { + pointer = new (typedef void **); + *old = function() { return type(*pointer).apply(null, [this, sel].concat(slice.call(arguments))); }; + } + + MSHookMessageEx(isa, sel, type(function(self, sel) { return imp.apply(self, slice.call(arguments, 2)); }), pointer); +}; + +})(exports); diff --git a/cycript0.9/org/cycript/NSLog.cy b/cycript0.9/org/cycript/NSLog.cy new file mode 100644 index 0000000..c2394f5 --- /dev/null +++ b/cycript0.9/org/cycript/NSLog.cy @@ -0,0 +1,28 @@ +/* Cycript - The Truly Universal Scripting Language + * Copyright (C) 2009-2016 Jay Freeman (saurik) +*/ + +/* GNU Lesser General Public License, Version 3 {{{ */ +/* + * Cycript is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Cycript is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Cycript. If not, see . +**/ +/* }}} */ + +var NSLog = dlsym(RTLD_DEFAULT, "NSLog"); +var slice = [].slice; + +module.exports = function(format) { + var args = slice.call(arguments); + new Functor(NSLog, "v" + ["@" for (x in args)].join("")).apply(null, args); +}; diff --git a/libcycript.py b/libcycript.py index cd69d28..e3859da 100755 --- a/libcycript.py +++ b/libcycript.py @@ -4,20 +4,59 @@ import os import sqlite3 import sys +system = sys.argv[1] +dbfile = sys.argv[2] +nodejs = sys.argv[3] +merges = sys.argv[4:] + +system = int(system) +nodejs += '/node/lib' + keys = {} -for db in sys.argv[2:]: +while True: + line = sys.stdin.readline() + if line == "": + break + elif line == "\n": + continue + assert line[-1] == '\n' + line = line[0:-1] + + pipe = line.index('|') + name = line[0:pipe] + line = line[pipe+1:] + + quote = line.index('"') + flags = int(line[0:quote]) + code = line[quote+1:-1] + + key = (name, flags, code) + keys[key] = system + +for db in merges: with sqlite3.connect(db) as sql: c = sql.cursor() for name, system, flags, code in c.execute('select name, system, flags, code from cache'): key = (name, flags, code) keys[key] = keys.get(key, 0) | system -db = sys.argv[1] -with sqlite3.connect(db) as sql: +if os.path.exists(dbfile): + os.unlink(dbfile) + +with sqlite3.connect(dbfile) as sql: + c = sql.cursor() + + c.execute("create table cache (name text not null, system int not null, flags int not null, code text not null, primary key (name, system))") + c.execute("create table module (name text not null, flags int not null, code blob not null, primary key (name))") + + for name in [js[0:-3] for js in os.listdir(nodejs) if js.endswith('.js')]: + with open(nodejs + '/' + name + '.js', 'r') as file: + code = file.read() + c.execute("insert into module (name, flags, code) values (?, ?, ?)", [name, 0, buffer(code)]) + many = [] for key, system in keys.items(): name, flags, code = key many.append((name, system, flags, code)) - c = sql.cursor() c.executemany("insert into cache (name, system, flags, code) values (?, ?, ?, ?)", many) diff --git a/libcycript.sh b/libcycript.sh deleted file mode 100755 index 095c8f1..0000000 --- a/libcycript.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -# Cycript - The Truly Universal Scripting Language -# Copyright (C) 2009-2016 Jay Freeman (saurik) - -# GNU Affero General Public License, Version 3 {{{ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# }}} - -set -e - -sys=$1 -sql=$2 - -rm -f "${sql}" -echo "create table cache (name text not null, system int not null, flags int not null, code text not null, primary key (name, system));" | sqlite3 "${sql}" - -def=$3 -if [[ -n "${def}" ]]; then - { echo "begin;"; cat "$def"; echo "commit;"; } | sed -e 's/^\([^|]*\)|\([0-9]*\)\"\(.*\)\"$/insert into cache (name, system, flags, code) values (<@<\1>@>, '"$sys"', \2, <@<\3>@>);/;s/'"'"'/'"'"''"'"'/g;s/\(<@<\|>@>\)/'"'"'/g' | sqlite3 "${sql}" -fi diff --git a/modules/com/saurik/substrate/MS.cy b/modules/com/saurik/substrate/MS.cy deleted file mode 100644 index 8d3418c..0000000 --- a/modules/com/saurik/substrate/MS.cy +++ /dev/null @@ -1,74 +0,0 @@ -/* Cydia Substrate - Powerful Code Insertion Platform - * Copyright (C) 2008-2015 Jay Freeman (saurik) -*/ - -(function(exports) { - -var libcycript = dlopen("/usr/lib/libcycript.dylib", RTLD_NOLOAD); -if (libcycript == null) { - exports.error = dlerror(); - return; -} - -var CYHandleServer = dlsym(libcycript, "CYHandleServer"); -if (CYHandleServer == null) { - exports.error = dlerror(); - return; -} - -var info = new Dl_info; -if (dladdr(CYHandleServer, info) == 0) { - exports.error = dlerror(); - return; -} - -var path = info->dli_fname; -var slash = path.lastIndexOf('/'); -if (slash == -1) - return; - -var libsubstrate = dlopen(path.substr(0, slash) + "/libsubstrate.dylib", RTLD_GLOBAL | RTLD_LAZY); -if (libsubstrate == null) { - exports.error = dlerror(); - return; -} - -extern "C" void *MSGetImageByName(const char *); -extern "C" void *MSFindSymbol(void *, const char *); -extern "C" void MSHookFunction(void *, void *, void **); -extern "C" void MSHookMessageEx(Class, SEL, void *, void **); - -var slice = Array.prototype.slice; - -exports.getImageByName = MSGetImageByName; -exports.findSymbol = MSFindSymbol; - -exports.hookFunction = function(func, hook, old) { - var type = typeid(func); - - var pointer; - if (old == null || typeof old === "undefined") - pointer = null; - else { - pointer = new (typedef void **); - *old = function() { return type(*pointer).apply(null, arguments); }; - } - - MSHookFunction(func.valueOf(), type(hook), pointer); -}; - -exports.hookMessage = function(isa, sel, imp, old) { - var type = sel.type(isa); - - var pointer; - if (old == null || typeof old === "undefined") - pointer = null; - else { - pointer = new (typedef void **); - *old = function() { return type(*pointer).apply(null, [this, sel].concat(slice.call(arguments))); }; - } - - MSHookMessageEx(isa, sel, type(function(self, sel) { return imp.apply(self, slice.call(arguments, 2)); }), pointer); -}; - -})(exports); diff --git a/modules/org/cycript/NSLog.cy b/modules/org/cycript/NSLog.cy deleted file mode 100644 index c2394f5..0000000 --- a/modules/org/cycript/NSLog.cy +++ /dev/null @@ -1,28 +0,0 @@ -/* Cycript - The Truly Universal Scripting Language - * Copyright (C) 2009-2016 Jay Freeman (saurik) -*/ - -/* GNU Lesser General Public License, Version 3 {{{ */ -/* - * Cycript is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Cycript is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Cycript. If not, see . -**/ -/* }}} */ - -var NSLog = dlsym(RTLD_DEFAULT, "NSLog"); -var slice = [].slice; - -module.exports = function(format) { - var args = slice.call(arguments); - new Functor(NSLog, "v" + ["@" for (x in args)].join("")).apply(null, args); -}; diff --git a/node b/node new file mode 160000 index 0000000..ed0d1c3 --- /dev/null +++ b/node @@ -0,0 +1 @@ +Subproject commit ed0d1c384cd4578f7168633c838f1252bddb260e