Dynamic API: don't leak if a library loaded but didn't have the entry point.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c
index c378699..f14cda9 100644
--- a/src/dynapi/SDL_dynapi.c
+++ b/src/dynapi/SDL_dynapi.c
@@ -206,7 +206,14 @@ SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize)
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{
HANDLE lib = LoadLibraryA(fname);
- return lib ? GetProcAddress(lib, sym) : NULL;
+ void *retval = NULL;
+ if (lib) {
+ retval = GetProcAddress(lib, sym);
+ if (retval == NULL) {
+ FreeLibrary(lib);
+ }
+ }
+ return retval;
}
#elif defined(__HAIKU__)
@@ -215,8 +222,11 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{
image_id lib = load_add_on(fname);
void *retval = NULL;
- if ((lib < 0) || (get_image_symbol(lib, sym, B_SYMBOL_TYPE_TEXT, &retval) != B_NO_ERROR)) {
- retval = NULL;
+ if (lib >= 0) {
+ if (get_image_symbol(lib, sym, B_SYMBOL_TYPE_TEXT, &retval) != B_NO_ERROR) {
+ unload_add_on(lib);
+ retval = NULL;
+ }
}
return retval;
}
@@ -225,7 +235,14 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{
void *lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL);
- return lib ? dlsym(lib, sym) : NULL;
+ void *retval = NULL;
+ if (lib != NULL) {
+ retval = dlsym(lib, sym);
+ if (retval == NULL) {
+ dlclose(lib);
+ }
+ }
+ return retval;
}
#else
#error Please define your platform.