]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfs.c
Include $(top_srcdir), $(top_srcdir)/src before anything else.
[fontconfig.git] / src / fcfs.c
index 90e858082f13d1483b96f744e3fddfd906e5b8f3..fdc15d7c2f7ed2d1cb8ed7af03795c0314e8a3d2 100644 (file)
@@ -22,8 +22,8 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <stdlib.h>
 #include "fcint.h"
+#include <stdlib.h>
 
 FcFontSet *
 FcFontSetCreate (void)
@@ -108,17 +108,27 @@ FcFontSetNeededBytes (FcFontSet *s)
        return 0;
 }
 
+/* Returns an overestimate of the number of bytes that
+ * might later get eaten up by padding in the ALIGN macro. */
+int
+FcFontSetNeededBytesAlign (void)
+{
+    return fc_alignof (int) + 
+       FcPatternNeededBytesAlign () + FcObjectNeededBytesAlign ();
+}
+
 void *
 FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr)
 {
+    block_ptr = ALIGN (block_ptr, int);
     fcfs_pat_count = (int *)block_ptr;
     block_ptr = (int *)block_ptr + 1;
-    // we don't consume any bytes for the fontset itself,
-    // since we don't allocate it statically.
+    /* we don't consume any bytes for the fontset itself, */
+    /* since we don't allocate it statically. */
     block_ptr = FcPatternDistributeBytes (metadata, block_ptr);
 
-    // for good measure, write out the object ids used for
-    // this bank to the file.
+    /* for good measure, write out the object ids used for */
+    /* this bank to the file. */
     return FcObjectDistributeBytes (metadata, block_ptr);
 }
 
@@ -133,9 +143,6 @@ FcFontSetSerialize (int bank, FcFontSet * s)
     {
        p = FcPatternSerialize (bank, s->fonts[i]);
        if (!p) return FcFalse;
-       FcPatternDestroy (s->fonts[i]);
-
-       s->fonts[i] = p;
     }
     FcObjectSerialize();
 
@@ -143,36 +150,48 @@ FcFontSetSerialize (int bank, FcFontSet * s)
 }
 
 FcBool
-FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr)
+FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr)
 {
     int nfont;
     int i, n;
 
+    block_ptr = ALIGN (block_ptr, int);
     nfont = *(int *)block_ptr;
     block_ptr = (int *)block_ptr + 1;
 
-    if (s->sfont < s->nfont + nfont)
-    {
-       int sfont = s->nfont + nfont;
-       FcPattern ** pp;
-       pp = realloc (s->fonts, sfont * sizeof (FcPattern));
-       if (!pp)
-           return FcFalse;
-       s->fonts = pp;
-       s->sfont = sfont;
-    }
-    n = s->nfont;
-    s->nfont += nfont;
-
-    if (nfont > 0)
+    /* comparing nfont and metadata.count is a bit like comparing
+       apples and oranges. Its just for rejecting totally insane
+       nfont values, and for that its good enough */
+    if (nfont > 0 && nfont < metadata->count / sizeof(void*))
     {
        FcPattern * p = (FcPattern *)block_ptr;
-       block_ptr = FcPatternUnserialize (metadata, block_ptr);
+
+       if (s->sfont < s->nfont + nfont)
+       {
+           int sfont = s->nfont + nfont;
+           FcPattern ** pp;
+           pp = realloc (s->fonts, sfont * sizeof (FcPattern));
+           if (!pp)
+               return FcFalse;
+           s->fonts = pp;
+           s->sfont = sfont;
+       }
+       n = s->nfont;
+       s->nfont += nfont;
+
+        /* The following line is a bit counterintuitive.  The usual
+         * convention is that FcPatternUnserialize is responsible for
+         * aligning the FcPattern.  However, the FontSet also stores
+         * the FcPatterns in its own array, so we need to align here
+         * too. */
+        p = ALIGN(p, FcPattern);
        for (i = 0; i < nfont; i++)
            s->fonts[n + i] = p+i;
 
+       block_ptr = FcPatternUnserialize (metadata, block_ptr);
        block_ptr = FcObjectUnserialize (metadata, block_ptr);
+       return block_ptr != 0;
     }
 
-    return block_ptr != 0;
+    return FcFalse;
 }