Skip to content

Commit

Permalink
jscore: fix JSCoreGTK version conflict w/ loaded one by user app
Browse files Browse the repository at this point in the history
  • Loading branch information
sergio-nsk committed Dec 24, 2024
1 parent 2a58424 commit 0bd4cce
Showing 1 changed file with 138 additions and 130 deletions.
268 changes: 138 additions & 130 deletions execute_jscore.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <threads.h>

#include <dlfcn.h>
#ifndef __APPLE__
Expand Down Expand Up @@ -59,7 +60,8 @@ typedef struct g_proxy_execute_jscore_s {
void (*JSGarbageCollect)(JSContextRef ctx);
} g_proxy_execute_jscore_s;

g_proxy_execute_jscore_s g_proxy_execute_jscore;
static g_proxy_execute_jscore_s g_proxy_execute_jscore;
static once_flag g_proxy_execute_jscore_init_flag = ONCE_FLAG_INIT;

typedef struct proxy_execute_jscore_s {
// Execute error
Expand Down Expand Up @@ -139,6 +141,136 @@ static void js_print_exception(JSContextRef ctx, JSValueRef exception) {
}
}

void proxy_execute_jscore_delayed_init(void) {
#ifdef __APPLE__
g_proxy_execute_jscore.module = dlopen(
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/JavaScriptCore", RTLD_LAZY | RTLD_LOCAL);
#else
const char *library_names[] = {"libjavascriptcoregtk-4.1.so.0", "libjavascriptcoregtk-4.0.so.18",
"libjavascriptcoregtk-3.0.so.0", "libjavascriptcoregtk-1.0.so.0"};
const size_t library_names_size = sizeof(library_names) / sizeof(library_names[0]);

// Use existing JavaScriptCoreGTK if already loaded
struct link_map *map = NULL;
void *current_process = dlopen(0, RTLD_LAZY);
if (!current_process)
return;

Check warning on line 157 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L157

Added line #L157 was not covered by tests
if (dlinfo(current_process, RTLD_DI_LINKMAP, &map) == 0) {
while (map && !g_proxy_execute_jscore.module) {
for (size_t i = 0; i < library_names_size; i++) {
if (strstr(map->l_name, library_names[i])) {
g_proxy_execute_jscore.module = dlopen(map->l_name, RTLD_NOLOAD | RTLD_LAZY | RTLD_LOCAL);
break;

Check warning on line 163 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L162-L163

Added lines #L162 - L163 were not covered by tests
}
}
map = map->l_next;
}
}
dlclose(current_process);

// Load the first available version of the JavaScriptCoreGTK
for (size_t i = 0; !g_proxy_execute_jscore.module && i < library_names_size; i++) {
g_proxy_execute_jscore.module = dlopen(library_names[i], RTLD_LAZY | RTLD_LOCAL);
}
#endif

if (!g_proxy_execute_jscore.module)
return;

Check warning on line 178 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L178

Added line #L178 was not covered by tests

// Class functions
g_proxy_execute_jscore.JSClassCreate = dlsym(g_proxy_execute_jscore.module, "JSClassCreate");
if (!g_proxy_execute_jscore.JSClassCreate)
goto jscore_init_error;

Check warning on line 183 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L183

Added line #L183 was not covered by tests
// Object functions
g_proxy_execute_jscore.JSObjectMake = dlsym(g_proxy_execute_jscore.module, "JSObjectMake");
if (!g_proxy_execute_jscore.JSObjectMake)
goto jscore_init_error;

Check warning on line 187 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L187

Added line #L187 was not covered by tests
g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback =
dlsym(g_proxy_execute_jscore.module, "JSObjectMakeFunctionWithCallback");
if (!g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback)
goto jscore_init_error;

Check warning on line 191 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L191

Added line #L191 was not covered by tests
g_proxy_execute_jscore.JSObjectGetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectGetProperty");
if (!g_proxy_execute_jscore.JSObjectGetProperty)
goto jscore_init_error;

Check warning on line 194 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L194

Added line #L194 was not covered by tests
g_proxy_execute_jscore.JSObjectSetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectSetProperty");
if (!g_proxy_execute_jscore.JSObjectSetProperty)
goto jscore_init_error;

Check warning on line 197 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L197

Added line #L197 was not covered by tests
g_proxy_execute_jscore.JSObjectGetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectGetPrivate");
if (!g_proxy_execute_jscore.JSObjectGetPrivate)
goto jscore_init_error;

Check warning on line 200 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L200

Added line #L200 was not covered by tests
g_proxy_execute_jscore.JSObjectSetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectSetPrivate");
if (!g_proxy_execute_jscore.JSObjectSetPrivate)
goto jscore_init_error;

Check warning on line 203 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L203

Added line #L203 was not covered by tests
// Context functions
g_proxy_execute_jscore.JSContextGetGlobalObject = dlsym(g_proxy_execute_jscore.module, "JSContextGetGlobalObject");
if (!g_proxy_execute_jscore.JSContextGetGlobalObject)
goto jscore_init_error;

Check warning on line 207 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L207

Added line #L207 was not covered by tests
// Value functions
g_proxy_execute_jscore.JSValueIsString = dlsym(g_proxy_execute_jscore.module, "JSValueIsString");
if (!g_proxy_execute_jscore.JSValueIsString)
goto jscore_init_error;

Check warning on line 211 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L211

Added line #L211 was not covered by tests
g_proxy_execute_jscore.JSValueIsNumber = dlsym(g_proxy_execute_jscore.module, "JSValueIsNumber");
if (!g_proxy_execute_jscore.JSValueIsNumber)
goto jscore_init_error;

Check warning on line 214 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L214

Added line #L214 was not covered by tests
g_proxy_execute_jscore.JSValueToObject = dlsym(g_proxy_execute_jscore.module, "JSValueToObject");
if (!g_proxy_execute_jscore.JSValueToObject)
goto jscore_init_error;

Check warning on line 217 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L217

Added line #L217 was not covered by tests
g_proxy_execute_jscore.JSValueToStringCopy = dlsym(g_proxy_execute_jscore.module, "JSValueToStringCopy");
if (!g_proxy_execute_jscore.JSValueToStringCopy)
goto jscore_init_error;

Check warning on line 220 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L220

Added line #L220 was not covered by tests
g_proxy_execute_jscore.JSValueToNumber = dlsym(g_proxy_execute_jscore.module, "JSValueToNumber");
if (!g_proxy_execute_jscore.JSValueToNumber)
goto jscore_init_error;

Check warning on line 223 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L223

Added line #L223 was not covered by tests
g_proxy_execute_jscore.JSValueMakeNull = dlsym(g_proxy_execute_jscore.module, "JSValueMakeNull");
if (!g_proxy_execute_jscore.JSValueMakeNull)
goto jscore_init_error;

Check warning on line 226 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L226

Added line #L226 was not covered by tests
g_proxy_execute_jscore.JSValueMakeBoolean = dlsym(g_proxy_execute_jscore.module, "JSValueMakeBoolean");
if (!g_proxy_execute_jscore.JSValueMakeBoolean)
goto jscore_init_error;

Check warning on line 229 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L229

Added line #L229 was not covered by tests
g_proxy_execute_jscore.JSValueMakeString = dlsym(g_proxy_execute_jscore.module, "JSValueMakeString");
if (!g_proxy_execute_jscore.JSValueMakeString)
goto jscore_init_error;

Check warning on line 232 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L232

Added line #L232 was not covered by tests
// String functions
g_proxy_execute_jscore.JSStringCreateWithUTF8CString =
dlsym(g_proxy_execute_jscore.module, "JSStringCreateWithUTF8CString");
if (!g_proxy_execute_jscore.JSStringCreateWithUTF8CString)
goto jscore_init_error;

Check warning on line 237 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L237

Added line #L237 was not covered by tests
g_proxy_execute_jscore.JSStringGetUTF8CString = dlsym(g_proxy_execute_jscore.module, "JSStringGetUTF8CString");
if (!g_proxy_execute_jscore.JSStringGetUTF8CString)
goto jscore_init_error;

Check warning on line 240 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L240

Added line #L240 was not covered by tests
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
goto jscore_init_error;

Check warning on line 244 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L244

Added line #L244 was not covered by tests
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
goto jscore_init_error;

Check warning on line 248 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L248

Added line #L248 was not covered by tests
g_proxy_execute_jscore.JSStringRelease = dlsym(g_proxy_execute_jscore.module, "JSStringRelease");
if (!g_proxy_execute_jscore.JSStringRelease)
goto jscore_init_error;

Check warning on line 251 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L251

Added line #L251 was not covered by tests
// Global context functions
g_proxy_execute_jscore.JSGlobalContextCreate = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextCreate");
if (!g_proxy_execute_jscore.JSGlobalContextCreate)
goto jscore_init_error;

Check warning on line 255 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L255

Added line #L255 was not covered by tests
g_proxy_execute_jscore.JSGlobalContextRelease = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextRelease");
if (!g_proxy_execute_jscore.JSGlobalContextRelease)
goto jscore_init_error;

Check warning on line 258 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L258

Added line #L258 was not covered by tests
// Execute functions
g_proxy_execute_jscore.JSEvaluateScript = dlsym(g_proxy_execute_jscore.module, "JSEvaluateScript");
if (!g_proxy_execute_jscore.JSEvaluateScript)
goto jscore_init_error;

Check warning on line 262 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L262

Added line #L262 was not covered by tests
// Garbage collection functions
g_proxy_execute_jscore.JSGarbageCollect = dlsym(g_proxy_execute_jscore.module, "JSGarbageCollect");
if (!g_proxy_execute_jscore.JSGarbageCollect)
goto jscore_init_error;

Check warning on line 266 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L266

Added line #L266 was not covered by tests

return;

jscore_init_error:
proxy_execute_jscore_global_cleanup();

Check warning on line 271 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L271

Added line #L271 was not covered by tests
}

static JSValueRef proxy_execute_jscore_dns_resolve(JSContextRef ctx, JSObjectRef function, JSObjectRef object,
size_t argc, const JSValueRef argv[], JSValueRef *exception) {
if (argc != 1)
Expand Down Expand Up @@ -354,6 +486,9 @@ int32_t proxy_execute_jscore_get_error(void *ctx) {
}

void *proxy_execute_jscore_create(void) {
call_once(&g_proxy_execute_jscore_init_flag, proxy_execute_jscore_delayed_init);
if (!g_proxy_execute_jscore.module)
return NULL;

Check warning on line 491 in execute_jscore.c

View check run for this annotation

Codecov / codecov/patch

execute_jscore.c#L491

Added line #L491 was not covered by tests
proxy_execute_jscore_s *proxy_execute = (proxy_execute_jscore_s *)calloc(1, sizeof(proxy_execute_jscore_s));
return proxy_execute;
}
Expand All @@ -373,136 +508,9 @@ bool proxy_execute_jscore_delete(void **ctx) {
/*********************************************************************/

bool proxy_execute_jscore_global_init(void) {
if (g_proxy_execute_jscore.module)
return true;
#ifdef __APPLE__
g_proxy_execute_jscore.module = dlopen(
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/JavaScriptCore", RTLD_LAZY | RTLD_LOCAL);
#else
const char *library_names[] = {"libjavascriptcoregtk-4.1.so.0", "libjavascriptcoregtk-4.0.so.18",
"libjavascriptcoregtk-3.0.so.0", "libjavascriptcoregtk-1.0.so.0"};
const size_t library_names_size = sizeof(library_names) / sizeof(library_names[0]);

// Use existing JavaScriptCoreGTK if already loaded
struct link_map *map = NULL;
void *current_process = dlopen(0, RTLD_LAZY);
if (!current_process)
return false;
if (dlinfo(current_process, RTLD_DI_LINKMAP, &map) == 0) {
while (map && !g_proxy_execute_jscore.module) {
for (size_t i = 0; i < library_names_size; i++) {
if (strstr(map->l_name, library_names[i])) {
g_proxy_execute_jscore.module = dlopen(map->l_name, RTLD_NOLOAD | RTLD_LAZY | RTLD_LOCAL);
break;
}
}
map = map->l_next;
}
}
dlclose(current_process);

// Load the first available version of the JavaScriptCoreGTK
for (size_t i = 0; !g_proxy_execute_jscore.module && i < library_names_size; i++) {
g_proxy_execute_jscore.module = dlopen(library_names[i], RTLD_LAZY | RTLD_LOCAL);
}
#endif

if (!g_proxy_execute_jscore.module)
return false;

// Class functions
g_proxy_execute_jscore.JSClassCreate = dlsym(g_proxy_execute_jscore.module, "JSClassCreate");
if (!g_proxy_execute_jscore.JSClassCreate)
goto jscore_init_error;
// Object functions
g_proxy_execute_jscore.JSObjectMake = dlsym(g_proxy_execute_jscore.module, "JSObjectMake");
if (!g_proxy_execute_jscore.JSObjectMake)
goto jscore_init_error;
g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback =
dlsym(g_proxy_execute_jscore.module, "JSObjectMakeFunctionWithCallback");
if (!g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback)
goto jscore_init_error;
g_proxy_execute_jscore.JSObjectGetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectGetProperty");
if (!g_proxy_execute_jscore.JSObjectGetProperty)
goto jscore_init_error;
g_proxy_execute_jscore.JSObjectSetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectSetProperty");
if (!g_proxy_execute_jscore.JSObjectSetProperty)
goto jscore_init_error;
g_proxy_execute_jscore.JSObjectGetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectGetPrivate");
if (!g_proxy_execute_jscore.JSObjectGetPrivate)
goto jscore_init_error;
g_proxy_execute_jscore.JSObjectSetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectSetPrivate");
if (!g_proxy_execute_jscore.JSObjectSetPrivate)
goto jscore_init_error;
// Context functions
g_proxy_execute_jscore.JSContextGetGlobalObject = dlsym(g_proxy_execute_jscore.module, "JSContextGetGlobalObject");
if (!g_proxy_execute_jscore.JSContextGetGlobalObject)
goto jscore_init_error;
// Value functions
g_proxy_execute_jscore.JSValueIsString = dlsym(g_proxy_execute_jscore.module, "JSValueIsString");
if (!g_proxy_execute_jscore.JSValueIsString)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueIsNumber = dlsym(g_proxy_execute_jscore.module, "JSValueIsNumber");
if (!g_proxy_execute_jscore.JSValueIsNumber)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueToObject = dlsym(g_proxy_execute_jscore.module, "JSValueToObject");
if (!g_proxy_execute_jscore.JSValueToObject)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueToStringCopy = dlsym(g_proxy_execute_jscore.module, "JSValueToStringCopy");
if (!g_proxy_execute_jscore.JSValueToStringCopy)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueToNumber = dlsym(g_proxy_execute_jscore.module, "JSValueToNumber");
if (!g_proxy_execute_jscore.JSValueToNumber)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueMakeNull = dlsym(g_proxy_execute_jscore.module, "JSValueMakeNull");
if (!g_proxy_execute_jscore.JSValueMakeNull)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueMakeBoolean = dlsym(g_proxy_execute_jscore.module, "JSValueMakeBoolean");
if (!g_proxy_execute_jscore.JSValueMakeBoolean)
goto jscore_init_error;
g_proxy_execute_jscore.JSValueMakeString = dlsym(g_proxy_execute_jscore.module, "JSValueMakeString");
if (!g_proxy_execute_jscore.JSValueMakeString)
goto jscore_init_error;
// String functions
g_proxy_execute_jscore.JSStringCreateWithUTF8CString =
dlsym(g_proxy_execute_jscore.module, "JSStringCreateWithUTF8CString");
if (!g_proxy_execute_jscore.JSStringCreateWithUTF8CString)
goto jscore_init_error;
g_proxy_execute_jscore.JSStringGetUTF8CString = dlsym(g_proxy_execute_jscore.module, "JSStringGetUTF8CString");
if (!g_proxy_execute_jscore.JSStringGetUTF8CString)
goto jscore_init_error;
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
goto jscore_init_error;
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
goto jscore_init_error;
g_proxy_execute_jscore.JSStringRelease = dlsym(g_proxy_execute_jscore.module, "JSStringRelease");
if (!g_proxy_execute_jscore.JSStringRelease)
goto jscore_init_error;
// Global context functions
g_proxy_execute_jscore.JSGlobalContextCreate = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextCreate");
if (!g_proxy_execute_jscore.JSGlobalContextCreate)
goto jscore_init_error;
g_proxy_execute_jscore.JSGlobalContextRelease = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextRelease");
if (!g_proxy_execute_jscore.JSGlobalContextRelease)
goto jscore_init_error;
// Execute functions
g_proxy_execute_jscore.JSEvaluateScript = dlsym(g_proxy_execute_jscore.module, "JSEvaluateScript");
if (!g_proxy_execute_jscore.JSEvaluateScript)
goto jscore_init_error;
// Garbage collection functions
g_proxy_execute_jscore.JSGarbageCollect = dlsym(g_proxy_execute_jscore.module, "JSGarbageCollect");
if (!g_proxy_execute_jscore.JSGarbageCollect)
goto jscore_init_error;

// JSCoreGTK will be initialized with a delay to avoid conflicts with the
// loaded JSCoreGTK in a user application after this function.
return true;

jscore_init_error:
proxy_execute_jscore_global_cleanup();
return false;
}

bool proxy_execute_jscore_global_cleanup(void) {
Expand Down

0 comments on commit 0bd4cce

Please sign in to comment.