Fix memory leaks after FcFini()
Reported by Jia Wang https://bugs.freedesktop.org/show_bug.cgi?id=83770
This commit is contained in:
parent
bcfe167e3d
commit
fa6c6b53c5
|
@ -217,7 +217,7 @@ typedef struct _FcMatrix {
|
|||
typedef struct _FcCharSet FcCharSet;
|
||||
|
||||
typedef struct _FcObjectType {
|
||||
const char *object;
|
||||
char *object;
|
||||
FcType type;
|
||||
} FcObjectType;
|
||||
|
||||
|
|
|
@ -192,6 +192,8 @@ FcFini (void)
|
|||
FcConfigFini ();
|
||||
FcCacheFini ();
|
||||
FcDefaultFini ();
|
||||
FcObjectFini ();
|
||||
FcConfigPathFini ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -880,6 +880,9 @@ FcPrivate FcConfig *
|
|||
FcInitLoadOwnConfigAndFonts (FcConfig *config);
|
||||
|
||||
/* fcxml.c */
|
||||
FcPrivate void
|
||||
FcConfigPathFini (void);
|
||||
|
||||
FcPrivate void
|
||||
FcTestDestroy (FcTest *test);
|
||||
|
||||
|
@ -1192,6 +1195,9 @@ FcStrSerialize (FcSerialize *serialize, const FcChar8 *str);
|
|||
|
||||
/* fcobjs.c */
|
||||
|
||||
FcPrivate void
|
||||
FcObjectFini (void);
|
||||
|
||||
FcPrivate FcObject
|
||||
FcObjectLookupIdByName (const char *str);
|
||||
|
||||
|
|
25
src/fcobjs.c
25
src/fcobjs.c
|
@ -44,6 +44,26 @@ struct FcObjectOtherTypeInfo {
|
|||
FcObject id;
|
||||
} *other_types;
|
||||
|
||||
void
|
||||
FcObjectFini (void)
|
||||
{
|
||||
struct FcObjectOtherTypeInfo *ots, *ot;
|
||||
|
||||
retry:
|
||||
ots = fc_atomic_ptr_get (&other_types);
|
||||
if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL))
|
||||
goto retry;
|
||||
|
||||
while (ots)
|
||||
{
|
||||
ot = ots->next;
|
||||
if (ots->object.object)
|
||||
free (ots->object.object);
|
||||
free (ots);
|
||||
ots = ot;
|
||||
}
|
||||
}
|
||||
|
||||
static FcObjectType *
|
||||
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
|
||||
{
|
||||
|
@ -62,13 +82,16 @@ retry:
|
|||
if (!ot)
|
||||
return NULL;
|
||||
|
||||
ot->object.object = (const char *) FcStrdup (str);
|
||||
ot->object.object = (char *) FcStrdup (str);
|
||||
ot->object.type = FcTypeUnknown;
|
||||
ot->id = fc_atomic_int_add (next_id, +1);
|
||||
ot->next = ots;
|
||||
|
||||
if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) {
|
||||
if (ot->object.object)
|
||||
free (ot->object.object);
|
||||
free (ot);
|
||||
fc_atomic_int_add (next_id, -1);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
|
47
src/fcxml.c
47
src/fcxml.c
|
@ -57,6 +57,9 @@
|
|||
extern FcChar8 fontconfig_instprefix[];
|
||||
#endif
|
||||
|
||||
static FcChar8 *__fc_userdir = NULL;
|
||||
static FcChar8 *__fc_userconf = NULL;
|
||||
|
||||
static void
|
||||
FcExprDestroy (FcExpr *e);
|
||||
|
||||
|
@ -2262,6 +2265,24 @@ FcParseCacheDir (FcConfigParse *parse)
|
|||
FcStrFree (data);
|
||||
}
|
||||
|
||||
void
|
||||
FcConfigPathFini (void)
|
||||
{
|
||||
FcChar8 *s;
|
||||
|
||||
retry_dir:
|
||||
s = fc_atomic_ptr_get (&__fc_userdir);
|
||||
if (!fc_atomic_ptr_cmpexch (&__fc_userdir, s, NULL))
|
||||
goto retry_dir;
|
||||
free (s);
|
||||
|
||||
retry_conf:
|
||||
s = fc_atomic_ptr_get (&__fc_userconf);
|
||||
if (!fc_atomic_ptr_cmpexch (&__fc_userconf, s, NULL))
|
||||
goto retry_conf;
|
||||
free (s);
|
||||
}
|
||||
|
||||
static void
|
||||
FcParseInclude (FcConfigParse *parse)
|
||||
{
|
||||
|
@ -2272,8 +2293,7 @@ FcParseInclude (FcConfigParse *parse)
|
|||
FcBool deprecated = FcFalse;
|
||||
#endif
|
||||
FcChar8 *prefix = NULL, *p;
|
||||
static FcChar8 *userdir = NULL;
|
||||
static FcChar8 *userconf = NULL;
|
||||
FcChar8 userdir, userconf;
|
||||
|
||||
s = FcStrBufDoneStatic (&parse->pstack->str);
|
||||
if (!s)
|
||||
|
@ -2303,6 +2323,7 @@ FcParseInclude (FcConfigParse *parse)
|
|||
{
|
||||
size_t plen = strlen ((const char *)prefix);
|
||||
size_t dlen = strlen ((const char *)s);
|
||||
FcChar8 *u;
|
||||
|
||||
p = realloc (prefix, plen + 1 + dlen + 1);
|
||||
if (!p)
|
||||
|
@ -2318,14 +2339,32 @@ FcParseInclude (FcConfigParse *parse)
|
|||
if (FcFileIsDir (s))
|
||||
{
|
||||
userdir:
|
||||
userdir = fc_atomic_ptr_get (&__fc_userdir);
|
||||
if (!userdir)
|
||||
userdir = FcStrdup (s);
|
||||
{
|
||||
u = FcStrdup (s);
|
||||
if (!fc_atomic_ptr_cmpexch (&__fc_userdir, userdir, u))
|
||||
{
|
||||
free (u);
|
||||
goto userdir;
|
||||
}
|
||||
userdir = u;
|
||||
}
|
||||
}
|
||||
else if (FcFileIsFile (s))
|
||||
{
|
||||
userconf:
|
||||
userconf = fc_atomic_ptr_get (&__fc_userconf);
|
||||
if (!userconf)
|
||||
userconf = FcStrdup (s);
|
||||
{
|
||||
u = FcStrdup (s);
|
||||
if (!fc_atomic_ptr_cmpexch (&__fc_userconf, userconf, u))
|
||||
{
|
||||
free (u);
|
||||
goto userconf;
|
||||
}
|
||||
userconf = u;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue