Fix various potential OOM crashes.

There were several potential OOM crashes in __imlib_ListFilters(),
__imlib_ListLoaders() and __imlib_TrimLoaderList().

The fix of __imlib_TrimLoaderList() is from patch by
Yuriy M. Kaminskiy <yumkam@gmail.com>.
This commit is contained in:
Kim Woelders 2016-04-14 21:45:06 +02:00
parent 5b54980364
commit a0259d5181
6 changed files with 93 additions and 125 deletions

View File

@ -47,6 +47,7 @@ image.c \
image.h \
line.c \
loaderpath.h \
modules.c \
polygon.c \
rectangle.c \
rend.c \

View File

@ -15,11 +15,8 @@
#include "dynamic_filters.h"
#include "file.h"
#include "image.h"
#include "loaderpath.h"
#include "script.h"
static char **__imlib_ListFilters(int *num_ret);
static ImlibExternalFilter *filters = NULL;
static int dyn_initialised = 0;
@ -101,7 +98,7 @@ __imlib_dynamic_filters_init()
#ifdef FDEBUG
printf("DEBUG: Loading Filters\n");
#endif
list = __imlib_ListFilters(&num_filters);
list = __imlib_ListModules("filters", &num_filters);
for (i = num_filters - 1; i >= 0; i--)
{
tptr = NULL;
@ -150,40 +147,3 @@ __imlib_get_dynamic_filter(char *name)
}
return NULL;
}
/* loader dir */
static char **
__imlib_ListFilters(int *num_ret)
{
char **list = NULL, **l, *s;
int num, i, pi = 0;
*num_ret = 0;
/* same for system loader path */
s = (char *)malloc(sizeof(SYS_LOADERS_PATH) + 8 + 1);
sprintf(s, SYS_LOADERS_PATH "/filters");
l = __imlib_FileDir(s, &num);
if (num > 0)
{
*num_ret += num;
list = realloc(list, sizeof(char *) * *num_ret);
for (i = 0; i < num; i++)
{
s = (char *)realloc(s,
sizeof(SYS_LOADERS_PATH) + 9 + strlen(l[i]) +
1);
sprintf(s, SYS_LOADERS_PATH "/filters/%s", l[i]);
list[pi + i] = strdup(s);
}
__imlib_FileFreeDirList(l, num);
}
free(s);
/* List currently contains *everything in there* we need to weed out
* the .so, .la, .a versions of the same loader or whatever else.
* dlopen can take an extension-less name and do the Right Thing
* with it, so that's what we'll give it. */
list = __imlib_TrimLoaderList(list, num_ret);
return list;
}

View File

@ -20,4 +20,6 @@ int __imlib_IsRealFile(const char *s);
int __imlib_ItemInList(char **list, int size, char *item);
char **__imlib_ListModules(const char *what, int *num_ret);
#endif

View File

@ -594,88 +594,6 @@ __imlib_ProduceLoader(char *file)
return l;
}
/* list all the filenames of loaders in the system loaders dir and the user */
/* loader dir */
static char **
__imlib_ListLoaders(int *num_ret)
{
char **list = NULL, **l, *s;
int num, i, pi = 0;
*num_ret = 0;
/* same for system loader path */
s = (char *)malloc(sizeof(SYS_LOADERS_PATH) + 8 + 1);
sprintf(s, SYS_LOADERS_PATH "/loaders");
l = __imlib_FileDir(s, &num);
if (num > 0)
{
*num_ret += num;
list = realloc(list, sizeof(char *) * *num_ret);
for (i = 0; i < num; i++)
{
s = (char *)realloc(s,
sizeof(SYS_LOADERS_PATH) + 9 + strlen(l[i]) +
1);
sprintf(s, SYS_LOADERS_PATH "/loaders/%s", l[i]);
list[pi + i] = strdup(s);
}
__imlib_FileFreeDirList(l, num);
}
free(s);
/* List currently contains *everything in there* we need to weed out
* the .so, .la, .a versions of the same loader or whatever else.
* dlopen can take an extension-less name and do the Right Thing
* with it, so that's what we'll give it. */
list = __imlib_TrimLoaderList(list, num_ret);
return list;
}
char **
__imlib_TrimLoaderList(char **list, int *num)
{
int i, n, size = 0;
char **ret = NULL;
if (!list)
return NULL;
if (*num == 0)
return list;
n = *num;
for (i = 0; i < n; i++)
{
char *ext;
if (!list[i])
continue;
ext = strrchr(list[i], '.');
if ((ext) && (
#ifdef __CYGWIN__
(!strcasecmp(ext, ".dll")) ||
#endif
(!strcasecmp(ext, ".so"))))
{
/* Don't add the same loader multiple times... */
if (!__imlib_ItemInList(ret, size, list[i]))
{
ret = realloc(ret, sizeof(char *) * (size + 1));
ret[size++] = strdup(list[i]);
}
}
if (list[i])
free(list[i]);
}
free(list);
*num = size;
return ret;
}
/* fre the struct for a loader and close its dlopen'd handle */
static void
__imlib_ConsumeLoader(ImlibLoader * l)
@ -753,7 +671,7 @@ __imlib_LoadAllLoaders(void)
char **list;
/* list all the loaders imlib can find */
list = __imlib_ListLoaders(&num);
list = __imlib_ListModules("loaders", &num);
/* no loaders? well don't load anything */
if (!list)
return;

View File

@ -135,7 +135,6 @@ void __imlib_AddImagePixmapToCache(ImlibImagePixmap * ip);
void __imlib_RemoveImagePixmapFromCache(ImlibImagePixmap * ip);
void __imlib_CleanupImagePixmapCache(void);
#endif
char **__imlib_TrimLoaderList(char **list, int *num);
void __imlib_RemoveAllLoaders(void);
ImlibLoader *__imlib_FindBestLoaderForFile(const char *file,
int for_save);

88
src/lib/modules.c Normal file
View File

@ -0,0 +1,88 @@
#include "config.h"
#include <stdlib.h>
#include "file.h"
#include "image.h"
#include "loaderpath.h"
static char **
__imlib_TrimLoaderList(char **list, int *num)
{
int i, n, size = 0;
if (!list)
return NULL;
n = *num;
for (i = 0; i < n; i++)
{
char *ext;
if (!list[i])
continue;
ext = strrchr(list[i], '.');
if ((ext) && (
#ifdef __CYGWIN__
(!strcasecmp(ext, ".dll")) ||
#endif
(!strcasecmp(ext, ".so"))))
{
/* Don't add the same loader multiple times... */
if (!__imlib_ItemInList(list, size, list[i]))
{
list[size++] = list[i];
continue;
}
}
free(list[i]);
}
if (!size)
{
free(list);
list = NULL;
}
else
{
list = realloc(list, size * sizeof(char *));
}
*num = size;
return list;
}
char **
__imlib_ListModules(const char *what, int *num_ret)
{
char **list = NULL, **l;
char path[1024];
int num, i;
*num_ret = 0;
snprintf(path, sizeof(path), "%s/%s", SYS_LOADERS_PATH, what);
l = __imlib_FileDir(path, &num);
if (num <= 0)
return NULL;
list = malloc(num * sizeof(char *));
if (list)
{
for (i = 0; i < num; i++)
{
snprintf(path, sizeof(path), "%s/%s/%s",
SYS_LOADERS_PATH, what, l[i]);
list[i] = strdup(path);
}
*num_ret = num;
}
__imlib_FileFreeDirList(l, num);
/* List currently contains *everything in there* we need to weed out
* the .so, .la, .a versions of the same loader or whatever else.
* dlopen can take an extension-less name and do the Right Thing
* with it, so that's what we'll give it. */
list = __imlib_TrimLoaderList(list, num_ret);
return list;
}