+#include <string>
+
+static bool cycript_;
+static bool jscript_;
+
+static void SetParser(bool cycript, bool jscript) {
+ cycript_ = cycript;
+ jscript_ = jscript;
+}
+
+static bool GetParser0() {
+ return cycript_;
+}
+
+static bool GetParser1() {
+ return jscript_;
+}
+
+static void Cycriptify(apr_pool_t *pool, const uint16_t *&data, size_t &size) {
+ if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL))
+ if (void (*CYParseUChar)(apr_pool_t *, const uint16_t **, size_t *) = reinterpret_cast<void (*)(apr_pool_t *, const uint16_t **, size_t *)>(dlsym(handle, "CYParseWebCore")))
+ CYParseUChar(pool, &data, &size);
+}
+
+MSHook(void, _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, JSC::SourceCode **_this, JSC::JSGlobalData *global, int *line, JSC::UString *message) {
+ if (!GetParser0())
+ return __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, global, line, message);
+ else {
+ SetParser(false, true);
+ JSC::SourceCode *source(*_this);
+ const uint16_t *data(source->data());
+ size_t size(source->length());
+ apr_pool_t *pool;
+ apr_pool_create(&pool, NULL);
+ Cycriptify(pool, data, size);
+ std::string stuff(data, data + size);
+ JSC::SourceCode code(JSC::makeSource(JSC::UString(data, size)));
+ *_this = &code;
+ __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, global, line, message);
+ apr_pool_destroy(pool);
+ *_this = source;
+ }
+}
+
+MSHook(void, _ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE, void *_this, int start, const UChar *code, unsigned length, int *source, int *line, JSC::UString *message) {
+ if (!GetParser0())
+ return __ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE(_this, start, code, length, source, line, message);
+ else {
+ const uint16_t *data(code);
+ size_t size(length);
+ apr_pool_t *pool;
+ apr_pool_create(&pool, NULL);
+ Cycriptify(pool, data, size);
+ __ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE(_this, start, data, size, source, line, message);
+ apr_pool_destroy(pool);
+ }
+}
+
+struct State {
+ unsigned state;
+};
+
+MSHook(State, _ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE, State state) {
+ SetParser(false, true);
+ state = __ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE(state);
+ SetParser(false, false);
+ return state;
+}
+
+MSHook(void, _ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE, void *resource) {
+ SetParser(false, true);
+ __ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE(resource);
+ SetParser(false, false);
+}
+
+MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, const WebCore::String &mime) {
+ bool jscript;
+
+ if (!GetParser1()) through:
+ jscript = __ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE(mime);
+ else if (mime == "text/cycript") {
+ SetParser(true, true);
+ jscript = true;
+ } else
+ goto through;
+
+ return jscript;
+}