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