Check null value for given object to avoid possibly segfaulting

This commit is contained in:
Akira TAGOH 2012-03-07 17:56:39 +09:00
parent 1f01c4b60c
commit 0ca752dd25
1 changed files with 103 additions and 72 deletions

View File

@ -54,28 +54,31 @@ FcCharSetDestroy (FcCharSet *fcs)
{ {
int i; int i;
if (fcs->ref == FC_REF_CONSTANT) if (fcs)
{ {
FcCacheObjectDereference (fcs); if (fcs->ref == FC_REF_CONSTANT)
return; {
FcCacheObjectDereference (fcs);
return;
}
if (--fcs->ref > 0)
return;
for (i = 0; i < fcs->num; i++)
{
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
free (FcCharSetLeaf (fcs, i));
}
if (fcs->num)
{
/* the numbers here are estimates */
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
free (FcCharSetLeaves (fcs));
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
free (FcCharSetNumbers (fcs));
}
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
free (fcs);
} }
if (--fcs->ref > 0)
return;
for (i = 0; i < fcs->num; i++)
{
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
free (FcCharSetLeaf (fcs, i));
}
if (fcs->num)
{
/* the numbers here are estimates */
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
free (FcCharSetLeaves (fcs));
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
free (FcCharSetNumbers (fcs));
}
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
free (fcs);
} }
/* /*
@ -252,7 +255,7 @@ FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4)
FcCharLeaf *leaf; FcCharLeaf *leaf;
FcChar32 *b; FcChar32 *b;
if (fcs->ref == FC_REF_CONSTANT) if (fcs == NULL || fcs->ref == FC_REF_CONSTANT)
return FcFalse; return FcFalse;
leaf = FcCharSetFindLeafCreate (fcs, ucs4); leaf = FcCharSetFindLeafCreate (fcs, ucs4);
if (!leaf) if (!leaf)
@ -268,7 +271,7 @@ FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4)
FcCharLeaf *leaf; FcCharLeaf *leaf;
FcChar32 *b; FcChar32 *b;
if (fcs->ref == FC_REF_CONSTANT) if (fcs == NULL || fcs->ref == FC_REF_CONSTANT)
return FcFalse; return FcFalse;
leaf = FcCharSetFindLeaf (fcs, ucs4); leaf = FcCharSetFindLeaf (fcs, ucs4);
if (!leaf) if (!leaf)
@ -342,10 +345,13 @@ FcCharSetIterStart (const FcCharSet *fcs, FcCharSetIter *iter)
FcCharSet * FcCharSet *
FcCharSetCopy (FcCharSet *src) FcCharSetCopy (FcCharSet *src)
{ {
if (src->ref != FC_REF_CONSTANT) if (src)
src->ref++; {
else if (src->ref != FC_REF_CONSTANT)
FcCacheObjectReference (src); src->ref++;
else
FcCacheObjectReference (src);
}
return src; return src;
} }
@ -357,6 +363,8 @@ FcCharSetEqual (const FcCharSet *a, const FcCharSet *b)
if (a == b) if (a == b)
return FcTrue; return FcTrue;
if (!a || !b)
return FcFalse;
for (FcCharSetIterStart (a, &ai), FcCharSetIterStart (b, &bi); for (FcCharSetIterStart (a, &ai), FcCharSetIterStart (b, &bi);
ai.leaf && bi.leaf; ai.leaf && bi.leaf;
FcCharSetIterNext (a, &ai), FcCharSetIterNext (b, &bi)) FcCharSetIterNext (a, &ai), FcCharSetIterNext (b, &bi))
@ -394,6 +402,8 @@ FcCharSetOperate (const FcCharSet *a,
FcCharSet *fcs; FcCharSet *fcs;
FcCharSetIter ai, bi; FcCharSetIter ai, bi;
if (!a || !b)
goto bail0;
fcs = FcCharSetCreate (); fcs = FcCharSetCreate ();
if (!fcs) if (!fcs)
goto bail0; goto bail0;
@ -493,6 +503,9 @@ FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed)
int ai = 0, bi = 0; int ai = 0, bi = 0;
FcChar16 an, bn; FcChar16 an, bn;
if (!a || !b)
return FcFalse;
if (a->ref == FC_REF_CONSTANT) { if (a->ref == FC_REF_CONSTANT) {
if (changed) if (changed)
*changed = FcFalse; *changed = FcFalse;
@ -561,7 +574,11 @@ FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b)
FcBool FcBool
FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4) FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4)
{ {
FcCharLeaf *leaf = FcCharSetFindLeaf (fcs, ucs4); FcCharLeaf *leaf;
if (!fcs)
return FcFalse;
leaf = FcCharSetFindLeaf (fcs, ucs4);
if (!leaf) if (!leaf)
return FcFalse; return FcFalse;
return (leaf->map[(ucs4 & 0xff) >> 5] & (1 << (ucs4 & 0x1f))) != 0; return (leaf->map[(ucs4 & 0xff) >> 5] & (1 << (ucs4 & 0x1f))) != 0;
@ -586,28 +603,31 @@ FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b)
FcCharSetIter ai, bi; FcCharSetIter ai, bi;
FcChar32 count = 0; FcChar32 count = 0;
FcCharSetIterStart (a, &ai); if (a && b)
FcCharSetIterStart (b, &bi);
while (ai.leaf && bi.leaf)
{ {
if (ai.ucs4 == bi.ucs4) FcCharSetIterStart (a, &ai);
FcCharSetIterStart (b, &bi);
while (ai.leaf && bi.leaf)
{ {
FcChar32 *am = ai.leaf->map; if (ai.ucs4 == bi.ucs4)
FcChar32 *bm = bi.leaf->map; {
int i = 256/32; FcChar32 *am = ai.leaf->map;
while (i--) FcChar32 *bm = bi.leaf->map;
count += FcCharSetPopCount (*am++ & *bm++); int i = 256/32;
FcCharSetIterNext (a, &ai); while (i--)
} count += FcCharSetPopCount (*am++ & *bm++);
else if (ai.ucs4 < bi.ucs4) FcCharSetIterNext (a, &ai);
{ }
ai.ucs4 = bi.ucs4; else if (ai.ucs4 < bi.ucs4)
FcCharSetIterSet (a, &ai); {
} ai.ucs4 = bi.ucs4;
if (bi.ucs4 < ai.ucs4) FcCharSetIterSet (a, &ai);
{ }
bi.ucs4 = ai.ucs4; if (bi.ucs4 < ai.ucs4)
FcCharSetIterSet (b, &bi); {
bi.ucs4 = ai.ucs4;
FcCharSetIterSet (b, &bi);
}
} }
} }
return count; return count;
@ -619,13 +639,16 @@ FcCharSetCount (const FcCharSet *a)
FcCharSetIter ai; FcCharSetIter ai;
FcChar32 count = 0; FcChar32 count = 0;
for (FcCharSetIterStart (a, &ai); ai.leaf; FcCharSetIterNext (a, &ai)) if (a)
{ {
int i = 256/32; for (FcCharSetIterStart (a, &ai); ai.leaf; FcCharSetIterNext (a, &ai))
FcChar32 *am = ai.leaf->map; {
int i = 256/32;
FcChar32 *am = ai.leaf->map;
while (i--) while (i--)
count += FcCharSetPopCount (*am++); count += FcCharSetPopCount (*am++);
}
} }
return count; return count;
} }
@ -636,31 +659,34 @@ FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b)
FcCharSetIter ai, bi; FcCharSetIter ai, bi;
FcChar32 count = 0; FcChar32 count = 0;
FcCharSetIterStart (a, &ai); if (a && b)
FcCharSetIterStart (b, &bi);
while (ai.leaf)
{ {
if (ai.ucs4 <= bi.ucs4) FcCharSetIterStart (a, &ai);
FcCharSetIterStart (b, &bi);
while (ai.leaf)
{ {
FcChar32 *am = ai.leaf->map; if (ai.ucs4 <= bi.ucs4)
int i = 256/32;
if (ai.ucs4 == bi.ucs4)
{ {
FcChar32 *bm = bi.leaf->map; FcChar32 *am = ai.leaf->map;
while (i--) int i = 256/32;
count += FcCharSetPopCount (*am++ & ~*bm++); if (ai.ucs4 == bi.ucs4)
{
FcChar32 *bm = bi.leaf->map;
while (i--)
count += FcCharSetPopCount (*am++ & ~*bm++);
}
else
{
while (i--)
count += FcCharSetPopCount (*am++);
}
FcCharSetIterNext (a, &ai);
} }
else else if (bi.leaf)
{ {
while (i--) bi.ucs4 = ai.ucs4;
count += FcCharSetPopCount (*am++); FcCharSetIterSet (b, &bi);
} }
FcCharSetIterNext (a, &ai);
}
else if (bi.leaf)
{
bi.ucs4 = ai.ucs4;
FcCharSetIterSet (b, &bi);
} }
} }
return count; return count;
@ -675,7 +701,10 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
int ai, bi; int ai, bi;
FcChar16 an, bn; FcChar16 an, bn;
if (a == b) return FcTrue; if (a == b)
return FcTrue;
if (!a || !b)
return FcFalse;
bi = 0; bi = 0;
ai = 0; ai = 0;
while (ai < a->num && bi < b->num) while (ai < a->num && bi < b->num)
@ -734,6 +763,8 @@ FcCharSetNextPage (const FcCharSet *a,
FcCharSetIter ai; FcCharSetIter ai;
FcChar32 page; FcChar32 page;
if (!a)
return FC_CHARSET_DONE;
ai.ucs4 = *next; ai.ucs4 = *next;
FcCharSetIterSet (a, &ai); FcCharSetIterSet (a, &ai);
if (!ai.leaf) if (!ai.leaf)