Skip to content

Commit 7c9d8c6

Browse files
sergio-nsknmoinvaz
authored andcommitted
jscore: fix JSCoreGTK version conflict w/ loaded one by user app
1 parent 8b2f739 commit 7c9d8c6

File tree

1 file changed

+138
-130
lines changed

1 file changed

+138
-130
lines changed

execute_jscore.c

Lines changed: 138 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <stdlib.h>
44
#include <stdio.h>
55
#include <string.h>
6+
#include <pthread.h>
67

78
#include <dlfcn.h>
89
#ifndef __APPLE__
@@ -59,7 +60,8 @@ typedef struct g_proxy_execute_jscore_s {
5960
void (*JSGarbageCollect)(JSContextRef ctx);
6061
} g_proxy_execute_jscore_s;
6162

62-
g_proxy_execute_jscore_s g_proxy_execute_jscore;
63+
static g_proxy_execute_jscore_s g_proxy_execute_jscore;
64+
static pthread_once_t g_proxy_execute_jscore_init_flag = PTHREAD_ONCE_INIT;
6365

6466
typedef struct proxy_execute_jscore_s {
6567
// Execute error
@@ -139,6 +141,136 @@ static void js_print_exception(JSContextRef ctx, JSValueRef exception) {
139141
}
140142
}
141143

144+
void proxy_execute_jscore_delayed_init(void) {
145+
#ifdef __APPLE__
146+
g_proxy_execute_jscore.module = dlopen(
147+
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/JavaScriptCore", RTLD_LAZY | RTLD_LOCAL);
148+
#else
149+
const char *library_names[] = {"libjavascriptcoregtk-4.1.so.0", "libjavascriptcoregtk-4.0.so.18",
150+
"libjavascriptcoregtk-3.0.so.0", "libjavascriptcoregtk-1.0.so.0"};
151+
const size_t library_names_size = sizeof(library_names) / sizeof(library_names[0]);
152+
153+
// Use existing JavaScriptCoreGTK if already loaded
154+
struct link_map *map = NULL;
155+
void *current_process = dlopen(0, RTLD_LAZY);
156+
if (!current_process)
157+
return;
158+
if (dlinfo(current_process, RTLD_DI_LINKMAP, &map) == 0) {
159+
while (map && !g_proxy_execute_jscore.module) {
160+
for (size_t i = 0; i < library_names_size; i++) {
161+
if (strstr(map->l_name, library_names[i])) {
162+
g_proxy_execute_jscore.module = dlopen(map->l_name, RTLD_NOLOAD | RTLD_LAZY | RTLD_LOCAL);
163+
break;
164+
}
165+
}
166+
map = map->l_next;
167+
}
168+
}
169+
dlclose(current_process);
170+
171+
// Load the first available version of the JavaScriptCoreGTK
172+
for (size_t i = 0; !g_proxy_execute_jscore.module && i < library_names_size; i++) {
173+
g_proxy_execute_jscore.module = dlopen(library_names[i], RTLD_LAZY | RTLD_LOCAL);
174+
}
175+
#endif
176+
177+
if (!g_proxy_execute_jscore.module)
178+
return;
179+
180+
// Class functions
181+
g_proxy_execute_jscore.JSClassCreate = dlsym(g_proxy_execute_jscore.module, "JSClassCreate");
182+
if (!g_proxy_execute_jscore.JSClassCreate)
183+
goto jscore_init_error;
184+
// Object functions
185+
g_proxy_execute_jscore.JSObjectMake = dlsym(g_proxy_execute_jscore.module, "JSObjectMake");
186+
if (!g_proxy_execute_jscore.JSObjectMake)
187+
goto jscore_init_error;
188+
g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback =
189+
dlsym(g_proxy_execute_jscore.module, "JSObjectMakeFunctionWithCallback");
190+
if (!g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback)
191+
goto jscore_init_error;
192+
g_proxy_execute_jscore.JSObjectGetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectGetProperty");
193+
if (!g_proxy_execute_jscore.JSObjectGetProperty)
194+
goto jscore_init_error;
195+
g_proxy_execute_jscore.JSObjectSetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectSetProperty");
196+
if (!g_proxy_execute_jscore.JSObjectSetProperty)
197+
goto jscore_init_error;
198+
g_proxy_execute_jscore.JSObjectGetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectGetPrivate");
199+
if (!g_proxy_execute_jscore.JSObjectGetPrivate)
200+
goto jscore_init_error;
201+
g_proxy_execute_jscore.JSObjectSetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectSetPrivate");
202+
if (!g_proxy_execute_jscore.JSObjectSetPrivate)
203+
goto jscore_init_error;
204+
// Context functions
205+
g_proxy_execute_jscore.JSContextGetGlobalObject = dlsym(g_proxy_execute_jscore.module, "JSContextGetGlobalObject");
206+
if (!g_proxy_execute_jscore.JSContextGetGlobalObject)
207+
goto jscore_init_error;
208+
// Value functions
209+
g_proxy_execute_jscore.JSValueIsString = dlsym(g_proxy_execute_jscore.module, "JSValueIsString");
210+
if (!g_proxy_execute_jscore.JSValueIsString)
211+
goto jscore_init_error;
212+
g_proxy_execute_jscore.JSValueIsNumber = dlsym(g_proxy_execute_jscore.module, "JSValueIsNumber");
213+
if (!g_proxy_execute_jscore.JSValueIsNumber)
214+
goto jscore_init_error;
215+
g_proxy_execute_jscore.JSValueToObject = dlsym(g_proxy_execute_jscore.module, "JSValueToObject");
216+
if (!g_proxy_execute_jscore.JSValueToObject)
217+
goto jscore_init_error;
218+
g_proxy_execute_jscore.JSValueToStringCopy = dlsym(g_proxy_execute_jscore.module, "JSValueToStringCopy");
219+
if (!g_proxy_execute_jscore.JSValueToStringCopy)
220+
goto jscore_init_error;
221+
g_proxy_execute_jscore.JSValueToNumber = dlsym(g_proxy_execute_jscore.module, "JSValueToNumber");
222+
if (!g_proxy_execute_jscore.JSValueToNumber)
223+
goto jscore_init_error;
224+
g_proxy_execute_jscore.JSValueMakeNull = dlsym(g_proxy_execute_jscore.module, "JSValueMakeNull");
225+
if (!g_proxy_execute_jscore.JSValueMakeNull)
226+
goto jscore_init_error;
227+
g_proxy_execute_jscore.JSValueMakeBoolean = dlsym(g_proxy_execute_jscore.module, "JSValueMakeBoolean");
228+
if (!g_proxy_execute_jscore.JSValueMakeBoolean)
229+
goto jscore_init_error;
230+
g_proxy_execute_jscore.JSValueMakeString = dlsym(g_proxy_execute_jscore.module, "JSValueMakeString");
231+
if (!g_proxy_execute_jscore.JSValueMakeString)
232+
goto jscore_init_error;
233+
// String functions
234+
g_proxy_execute_jscore.JSStringCreateWithUTF8CString =
235+
dlsym(g_proxy_execute_jscore.module, "JSStringCreateWithUTF8CString");
236+
if (!g_proxy_execute_jscore.JSStringCreateWithUTF8CString)
237+
goto jscore_init_error;
238+
g_proxy_execute_jscore.JSStringGetUTF8CString = dlsym(g_proxy_execute_jscore.module, "JSStringGetUTF8CString");
239+
if (!g_proxy_execute_jscore.JSStringGetUTF8CString)
240+
goto jscore_init_error;
241+
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
242+
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
243+
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
244+
goto jscore_init_error;
245+
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
246+
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
247+
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
248+
goto jscore_init_error;
249+
g_proxy_execute_jscore.JSStringRelease = dlsym(g_proxy_execute_jscore.module, "JSStringRelease");
250+
if (!g_proxy_execute_jscore.JSStringRelease)
251+
goto jscore_init_error;
252+
// Global context functions
253+
g_proxy_execute_jscore.JSGlobalContextCreate = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextCreate");
254+
if (!g_proxy_execute_jscore.JSGlobalContextCreate)
255+
goto jscore_init_error;
256+
g_proxy_execute_jscore.JSGlobalContextRelease = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextRelease");
257+
if (!g_proxy_execute_jscore.JSGlobalContextRelease)
258+
goto jscore_init_error;
259+
// Execute functions
260+
g_proxy_execute_jscore.JSEvaluateScript = dlsym(g_proxy_execute_jscore.module, "JSEvaluateScript");
261+
if (!g_proxy_execute_jscore.JSEvaluateScript)
262+
goto jscore_init_error;
263+
// Garbage collection functions
264+
g_proxy_execute_jscore.JSGarbageCollect = dlsym(g_proxy_execute_jscore.module, "JSGarbageCollect");
265+
if (!g_proxy_execute_jscore.JSGarbageCollect)
266+
goto jscore_init_error;
267+
268+
return;
269+
270+
jscore_init_error:
271+
proxy_execute_jscore_global_cleanup();
272+
}
273+
142274
static JSValueRef proxy_execute_jscore_dns_resolve(JSContextRef ctx, JSObjectRef function, JSObjectRef object,
143275
size_t argc, const JSValueRef argv[], JSValueRef *exception) {
144276
if (argc != 1)
@@ -354,6 +486,9 @@ int32_t proxy_execute_jscore_get_error(void *ctx) {
354486
}
355487

356488
void *proxy_execute_jscore_create(void) {
489+
pthread_once(&g_proxy_execute_jscore_init_flag, proxy_execute_jscore_delayed_init);
490+
if (!g_proxy_execute_jscore.module)
491+
return NULL;
357492
proxy_execute_jscore_s *proxy_execute = (proxy_execute_jscore_s *)calloc(1, sizeof(proxy_execute_jscore_s));
358493
return proxy_execute;
359494
}
@@ -373,136 +508,9 @@ bool proxy_execute_jscore_delete(void **ctx) {
373508
/*********************************************************************/
374509

375510
bool proxy_execute_jscore_global_init(void) {
376-
if (g_proxy_execute_jscore.module)
377-
return true;
378-
#ifdef __APPLE__
379-
g_proxy_execute_jscore.module = dlopen(
380-
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/JavaScriptCore", RTLD_LAZY | RTLD_LOCAL);
381-
#else
382-
const char *library_names[] = {"libjavascriptcoregtk-4.1.so.0", "libjavascriptcoregtk-4.0.so.18",
383-
"libjavascriptcoregtk-3.0.so.0", "libjavascriptcoregtk-1.0.so.0"};
384-
const size_t library_names_size = sizeof(library_names) / sizeof(library_names[0]);
385-
386-
// Use existing JavaScriptCoreGTK if already loaded
387-
struct link_map *map = NULL;
388-
void *current_process = dlopen(0, RTLD_LAZY);
389-
if (!current_process)
390-
return false;
391-
if (dlinfo(current_process, RTLD_DI_LINKMAP, &map) == 0) {
392-
while (map && !g_proxy_execute_jscore.module) {
393-
for (size_t i = 0; i < library_names_size; i++) {
394-
if (strstr(map->l_name, library_names[i])) {
395-
g_proxy_execute_jscore.module = dlopen(map->l_name, RTLD_NOLOAD | RTLD_LAZY | RTLD_LOCAL);
396-
break;
397-
}
398-
}
399-
map = map->l_next;
400-
}
401-
}
402-
dlclose(current_process);
403-
404-
// Load the first available version of the JavaScriptCoreGTK
405-
for (size_t i = 0; !g_proxy_execute_jscore.module && i < library_names_size; i++) {
406-
g_proxy_execute_jscore.module = dlopen(library_names[i], RTLD_LAZY | RTLD_LOCAL);
407-
}
408-
#endif
409-
410-
if (!g_proxy_execute_jscore.module)
411-
return false;
412-
413-
// Class functions
414-
g_proxy_execute_jscore.JSClassCreate = dlsym(g_proxy_execute_jscore.module, "JSClassCreate");
415-
if (!g_proxy_execute_jscore.JSClassCreate)
416-
goto jscore_init_error;
417-
// Object functions
418-
g_proxy_execute_jscore.JSObjectMake = dlsym(g_proxy_execute_jscore.module, "JSObjectMake");
419-
if (!g_proxy_execute_jscore.JSObjectMake)
420-
goto jscore_init_error;
421-
g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback =
422-
dlsym(g_proxy_execute_jscore.module, "JSObjectMakeFunctionWithCallback");
423-
if (!g_proxy_execute_jscore.JSObjectMakeFunctionWithCallback)
424-
goto jscore_init_error;
425-
g_proxy_execute_jscore.JSObjectGetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectGetProperty");
426-
if (!g_proxy_execute_jscore.JSObjectGetProperty)
427-
goto jscore_init_error;
428-
g_proxy_execute_jscore.JSObjectSetProperty = dlsym(g_proxy_execute_jscore.module, "JSObjectSetProperty");
429-
if (!g_proxy_execute_jscore.JSObjectSetProperty)
430-
goto jscore_init_error;
431-
g_proxy_execute_jscore.JSObjectGetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectGetPrivate");
432-
if (!g_proxy_execute_jscore.JSObjectGetPrivate)
433-
goto jscore_init_error;
434-
g_proxy_execute_jscore.JSObjectSetPrivate = dlsym(g_proxy_execute_jscore.module, "JSObjectSetPrivate");
435-
if (!g_proxy_execute_jscore.JSObjectSetPrivate)
436-
goto jscore_init_error;
437-
// Context functions
438-
g_proxy_execute_jscore.JSContextGetGlobalObject = dlsym(g_proxy_execute_jscore.module, "JSContextGetGlobalObject");
439-
if (!g_proxy_execute_jscore.JSContextGetGlobalObject)
440-
goto jscore_init_error;
441-
// Value functions
442-
g_proxy_execute_jscore.JSValueIsString = dlsym(g_proxy_execute_jscore.module, "JSValueIsString");
443-
if (!g_proxy_execute_jscore.JSValueIsString)
444-
goto jscore_init_error;
445-
g_proxy_execute_jscore.JSValueIsNumber = dlsym(g_proxy_execute_jscore.module, "JSValueIsNumber");
446-
if (!g_proxy_execute_jscore.JSValueIsNumber)
447-
goto jscore_init_error;
448-
g_proxy_execute_jscore.JSValueToObject = dlsym(g_proxy_execute_jscore.module, "JSValueToObject");
449-
if (!g_proxy_execute_jscore.JSValueToObject)
450-
goto jscore_init_error;
451-
g_proxy_execute_jscore.JSValueToStringCopy = dlsym(g_proxy_execute_jscore.module, "JSValueToStringCopy");
452-
if (!g_proxy_execute_jscore.JSValueToStringCopy)
453-
goto jscore_init_error;
454-
g_proxy_execute_jscore.JSValueToNumber = dlsym(g_proxy_execute_jscore.module, "JSValueToNumber");
455-
if (!g_proxy_execute_jscore.JSValueToNumber)
456-
goto jscore_init_error;
457-
g_proxy_execute_jscore.JSValueMakeNull = dlsym(g_proxy_execute_jscore.module, "JSValueMakeNull");
458-
if (!g_proxy_execute_jscore.JSValueMakeNull)
459-
goto jscore_init_error;
460-
g_proxy_execute_jscore.JSValueMakeBoolean = dlsym(g_proxy_execute_jscore.module, "JSValueMakeBoolean");
461-
if (!g_proxy_execute_jscore.JSValueMakeBoolean)
462-
goto jscore_init_error;
463-
g_proxy_execute_jscore.JSValueMakeString = dlsym(g_proxy_execute_jscore.module, "JSValueMakeString");
464-
if (!g_proxy_execute_jscore.JSValueMakeString)
465-
goto jscore_init_error;
466-
// String functions
467-
g_proxy_execute_jscore.JSStringCreateWithUTF8CString =
468-
dlsym(g_proxy_execute_jscore.module, "JSStringCreateWithUTF8CString");
469-
if (!g_proxy_execute_jscore.JSStringCreateWithUTF8CString)
470-
goto jscore_init_error;
471-
g_proxy_execute_jscore.JSStringGetUTF8CString = dlsym(g_proxy_execute_jscore.module, "JSStringGetUTF8CString");
472-
if (!g_proxy_execute_jscore.JSStringGetUTF8CString)
473-
goto jscore_init_error;
474-
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
475-
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
476-
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
477-
goto jscore_init_error;
478-
g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize =
479-
dlsym(g_proxy_execute_jscore.module, "JSStringGetMaximumUTF8CStringSize");
480-
if (!g_proxy_execute_jscore.JSStringGetMaximumUTF8CStringSize)
481-
goto jscore_init_error;
482-
g_proxy_execute_jscore.JSStringRelease = dlsym(g_proxy_execute_jscore.module, "JSStringRelease");
483-
if (!g_proxy_execute_jscore.JSStringRelease)
484-
goto jscore_init_error;
485-
// Global context functions
486-
g_proxy_execute_jscore.JSGlobalContextCreate = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextCreate");
487-
if (!g_proxy_execute_jscore.JSGlobalContextCreate)
488-
goto jscore_init_error;
489-
g_proxy_execute_jscore.JSGlobalContextRelease = dlsym(g_proxy_execute_jscore.module, "JSGlobalContextRelease");
490-
if (!g_proxy_execute_jscore.JSGlobalContextRelease)
491-
goto jscore_init_error;
492-
// Execute functions
493-
g_proxy_execute_jscore.JSEvaluateScript = dlsym(g_proxy_execute_jscore.module, "JSEvaluateScript");
494-
if (!g_proxy_execute_jscore.JSEvaluateScript)
495-
goto jscore_init_error;
496-
// Garbage collection functions
497-
g_proxy_execute_jscore.JSGarbageCollect = dlsym(g_proxy_execute_jscore.module, "JSGarbageCollect");
498-
if (!g_proxy_execute_jscore.JSGarbageCollect)
499-
goto jscore_init_error;
500-
511+
// JSCoreGTK will be initialized with a delay to avoid conflicts with the
512+
// loaded JSCoreGTK in a user application after this function.
501513
return true;
502-
503-
jscore_init_error:
504-
proxy_execute_jscore_global_cleanup();
505-
return false;
506514
}
507515

508516
bool proxy_execute_jscore_global_cleanup(void) {

0 commit comments

Comments
 (0)