]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcpat.c
Fix additional memory leaks reported by Ronny V. Vindenes: don't invoke
[fontconfig.git] / src / fcpat.c
index a626ab6b120256bbb094eecaf9381640126f8a86..0a6241b564184f37f9688487804f256a8762a871 100644 (file)
@@ -874,7 +874,14 @@ FcPatternAddWithBinding  (FcPattern            *p,
     new = FcValueListPtrCreateDynamic(newp);
     FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
     /* dup string */
-    value = FcValueSave (value);
+    if (value.type == FcTypeString)
+    {
+       value.u.s = FcStrStaticName (value.u.s);
+       if (!value.u.s)
+           value.type = FcTypeVoid;
+    }
+    else
+       value = FcValueSave (value);
     if (value.type == FcTypeVoid)
        goto bail1;
 
@@ -1029,6 +1036,13 @@ FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
 {
     FcValue    v;
 
+    if (!s)
+    {
+       v.type = FcTypeVoid;
+       v.u.s = 0;
+       return FcPatternAdd (p, object, v, FcTrue);
+    }
+
     v.type = FcTypeString;
     v.u.s = FcStrStaticName(s);
     return FcPatternAdd (p, object, v, FcTrue);
@@ -1881,6 +1895,7 @@ FcStrNeededBytes (const FcChar8 * s)
     struct objectBucket **p;
     struct objectBucket *b;
     int                 size;
+    FcChar8 *const null = 0;
 
     for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
         if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1)))
@@ -1898,7 +1913,8 @@ FcStrNeededBytes (const FcChar8 * s)
      * incorrect to replace the with a memset, because the C
      * specification doesn't guarantee that the null pointer is
      * the same as the zero bit pattern. */
-    *(char **)((char *) (b + 1) + strlen((char *)s) + 1) = 0;
+    /* Misaligned pointers are not guaranteed to work, either! */
+    memcpy (((char *) (b + 1) + strlen((char *)s) + 1), &null, sizeof (null));
     *p = b;
 
     fcstr_count += strlen((char *)s) + 1;
@@ -1961,13 +1977,15 @@ FcStrSerialize (int bank, const FcChar8 * s)
     for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
         if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1)))
        {
-           FcChar8 * t = *(FcChar8 **)(((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1);
+           FcChar8 * t;
+           memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *));
            if (!t)
            {
                strcpy((char *)(static_strs[bi] + fcstr_ptr), (char *)s);
-               *(FcChar8 **)((FcChar8 *) (b + 1) + strlen((char *)s) + 1) = (static_strs[bi] + fcstr_ptr);
+               t = static_strs[bi] + fcstr_ptr;
+               memcpy ((FcChar8 *) (b + 1) + strlen((char *)s) + 1, &t, sizeof (FcChar8 *));
                fcstr_ptr += strlen((char *)s) + 1;
-               t = *(FcChar8 **)(((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1);
+               memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *));
            }
            return t;
        }
@@ -1993,7 +2011,7 @@ FcStrUnserialize (FcCache * metadata, void *block_ptr)
 /* we don't store these in the FcPattern itself because
  * we don't want to serialize the directory names */
 
-/* I suppose this should be cleaned, too... */
+/* I suppose this should be cleaned upon termination, too... */
 typedef struct _FcPatternDirMapping {
     const FcPattern    *p;
     const char *fname;
@@ -2013,7 +2031,7 @@ FcPatternAddFullFname (const FcPattern *p, const char *fname)
     /* N.B. FcPatternHash fails, since it's contents-based, not
      * address-based, and we're in the process of mutating the FcPattern. */
     for (pb = &FcPatternDirBuckets
-             [((int)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE];
+             [((unsigned long)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE];
          pb->m.p != p && pb->next; 
          pb = pb->next)
         ;
@@ -2040,7 +2058,7 @@ FcPatternFindFullFname (const FcPattern *p)
     struct patternDirBucket    *pb;
 
     for (pb = &FcPatternDirBuckets
-             [((int)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE]; 
+             [((unsigned long)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE]; 
          pb; pb = pb->next)
        if (pb->m.p == p)
            return pb->m.fname;