Author: ken
Date: 2009-04-15 16:59:27 -0600 (Wed, 15 Apr 2009)
New Revision: 2062

Added:
   trunk/ghostscript/ghostscript-8.64-security_fixes-1.patch
Log:
All the current CVE fixes for gs-8.64.

Added: trunk/ghostscript/ghostscript-8.64-security_fixes-1.patch
===================================================================
--- trunk/ghostscript/ghostscript-8.64-security_fixes-1.patch                   
        (rev 0)
+++ trunk/ghostscript/ghostscript-8.64-security_fixes-1.patch   2009-04-15 
22:59:27 UTC (rev 2062)
@@ -0,0 +1,1178 @@
+Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
+Date: 2009-04-15
+Initial Package Version: 8.64
+Upstream Status: Thought to all be applied.
+Origin: found in Fedora
+Description: Fixes for CVE-2009-{0196,0583,0584,0792}
+
+diff -Naur ghostscript-8.64.orig/icclib/icc.c ghostscript-8.64/icclib/icc.c
+--- ghostscript-8.64.orig/icclib/icc.c 2008-05-09 05:12:01.000000000 +0100
++++ ghostscript-8.64/icclib/icc.c      2009-04-15 23:29:42.000000000 +0100
+@@ -152,6 +152,8 @@
+  *      Various bug fixes and enhancements.
+  */
+ 
++#include <limits.h>
++#include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+@@ -313,8 +315,11 @@
+       icmFileMem *p = (icmFileMem *)pp;
+       size_t len;
+ 
++      if (count > 0 && size > SIZE_MAX / count)
++              return 0;
++
+       len = size * count;
+-      if ((p->cur + len) >= p->end) {         /* Too much */
++      if (len > (p->end - p->cur)) { /* Too much */
+               if (size > 0)
+                       count = (p->end - p->cur)/size;
+               else
+@@ -1634,6 +1639,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmUInt8Array_write malloc() failed");
+               return icp->errc = 2;
+@@ -1698,7 +1705,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (unsigned int *) icp->al->malloc(icp->al, 
p->size * sizeof(unsigned int))) == NULL) {
++              if ((p->data = (unsigned int *) icp->al->calloc(icp->al, 
p->size, sizeof(unsigned int))) == NULL) {
+                       sprintf(icp->err,"icmUInt8Array_alloc: malloc() of 
icmUInt8Array data failed");
+                       return icp->errc = 2;
+               }
+@@ -1749,6 +1756,10 @@
+       icmUInt16Array *p = (icmUInt16Array *)pp;
+       unsigned int len = 0;
+       len += 8;                       /* 8 bytes for tag and padding */
++      if (p->size > (UINT_MAX - len) / 2) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += p->size * 2;     /* 2 bytes for each UInt16 */
+       return len;
+ }
+@@ -1821,6 +1832,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmUInt16Array_write malloc() failed");
+               return icp->errc = 2;
+@@ -1885,7 +1898,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (unsigned int *) icp->al->malloc(icp->al, 
p->size * sizeof(unsigned int))) == NULL) {
++              if ((p->data = (unsigned int *) icp->al->calloc(icp->al, 
p->size, sizeof(unsigned int))) == NULL) {
+                       sprintf(icp->err,"icmUInt16Array_alloc: malloc() of 
icmUInt16Array data failed");
+                       return icp->errc = 2;
+               }
+@@ -1936,6 +1949,10 @@
+       icmUInt32Array *p = (icmUInt32Array *)pp;
+       unsigned int len = 0;
+       len += 8;                       /* 8 bytes for tag and padding */
++      if (p->size > (UINT_MAX - len) / 4) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += p->size * 4;     /* 4 bytes for each UInt32 */
+       return len;
+ }
+@@ -2008,6 +2025,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmUInt32Array_write malloc() failed");
+               return icp->errc = 2;
+@@ -2072,7 +2091,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (unsigned int *) icp->al->malloc(icp->al, 
p->size * sizeof(unsigned int))) == NULL) {
++              if ((p->data = (unsigned int *) icp->al->calloc(icp->al, 
p->size, sizeof(unsigned int))) == NULL) {
+                       sprintf(icp->err,"icmUInt32Array_alloc: malloc() of 
icmUInt32Array data failed");
+                       return icp->errc = 2;
+               }
+@@ -2123,6 +2142,10 @@
+       icmUInt64Array *p = (icmUInt64Array *)pp;
+       unsigned int len = 0;
+       len += 8;                       /* 8 bytes for tag and padding */
++      if (p->size > (UINT_MAX - len) / 8) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += p->size * 8;     /* 8 bytes for each UInt64 */
+       return len;
+ }
+@@ -2195,6 +2218,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmUInt64Array_write malloc() failed");
+               return icp->errc = 2;
+@@ -2259,7 +2284,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (icmUint64 *) icp->al->malloc(icp->al, p->size * 
sizeof(icmUint64))) == NULL) {
++              if ((p->data = (icmUint64 *) icp->al->calloc(icp->al, p->size, 
sizeof(icmUint64))) == NULL) {
+                       sprintf(icp->err,"icmUInt64Array_alloc: malloc() of 
icmUInt64Array data failed");
+                       return icp->errc = 2;
+               }
+@@ -2310,6 +2335,10 @@
+       icmU16Fixed16Array *p = (icmU16Fixed16Array *)pp;
+       unsigned int len = 0;
+       len += 8;                       /* 8 bytes for tag and padding */
++      if (p->size > (UINT_MAX - len) / 4) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += p->size * 4;     /* 4 byte for each U16Fixed16 */
+       return len;
+ }
+@@ -2382,6 +2411,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmU16Fixed16Array_write malloc() failed");
+               return icp->errc = 2;
+@@ -2446,7 +2477,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (double *) icp->al->malloc(icp->al, p->size * 
sizeof(double))) == NULL) {
++              if ((p->data = (double *) icp->al->calloc(icp->al, p->size, 
sizeof(double))) == NULL) {
+                       sprintf(icp->err,"icmU16Fixed16Array_alloc: malloc() of 
icmU16Fixed16Array data failed");
+                       return icp->errc = 2;
+               }
+@@ -2497,6 +2528,10 @@
+       icmS15Fixed16Array *p = (icmS15Fixed16Array *)pp;
+       unsigned int len = 0;
+       len += 8;                       /* 8 bytes for tag and padding */
++      if (p->size > (UINT_MAX - len) / 4) {
++              p->icp->errc = 1;
++              return (unsigned int) - 1;
++      }
+       len += p->size * 4;     /* 4 byte for each S15Fixed16 */
+       return len;
+ }
+@@ -2569,6 +2604,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmS15Fixed16Array_write malloc() failed");
+               return icp->errc = 2;
+@@ -2633,7 +2670,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (double *) icp->al->malloc(icp->al, p->size * 
sizeof(double))) == NULL) {
++              if ((p->data = (double *) icp->al->calloc(icp->al, p->size, 
sizeof(double))) == NULL) {
+                       sprintf(icp->err,"icmS15Fixed16Array_alloc: malloc() of 
icmS15Fixed16Array data failed");
+                       return icp->errc = 2;
+               }
+@@ -2726,6 +2763,10 @@
+       icmXYZArray *p = (icmXYZArray *)pp;
+       unsigned int len = 0;
+       len += 8;                               /* 8 bytes for tag and padding 
*/
++      if (p->size > (UINT_MAX - len) / 12) {
++              p->icp->errc = 1;
++              return (unsigned int) - 1;
++      }
+       len += p->size * 12;    /* 12 bytes for each XYZ */
+       return len;
+ }
+@@ -2798,6 +2839,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmXYZArray_write malloc() failed");
+               return icp->errc = 2;
+@@ -2865,7 +2908,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (icmXYZNumber *) icp->al->malloc(icp->al, 
p->size * sizeof(icmXYZNumber))) == NULL) {
++              if ((p->data = (icmXYZNumber *) icp->al->calloc(icp->al, 
p->size, sizeof(icmXYZNumber))) == NULL) {
+                       sprintf(icp->err,"icmXYZArray_alloc: malloc() of 
icmXYZArray data failed");
+                       return icp->errc = 2;
+               }
+@@ -2939,7 +2982,7 @@
+                       rv |= 1;
+               }
+               ix = (int)floor(val);           /* Coordinate */
+-              if (ix > (p->size-2))
++              if (ix < 0 || ix > (p->size-2))
+                       ix = (p->size-2);
+               w = val - (double)ix;           /* weight */
+               val = p->data[ix];
+@@ -2961,6 +3004,11 @@
+ ) {
+       int i;
+ 
++      if (size > INT_MAX - 2)
++              /* Although rt->size is unsigned long, the rt data
++               * structure uses int data types to store indices. */
++              return 2;
++
+       rt->size = size;                /* Stash pointers to these away */
+       rt->data = data;
+       
+@@ -2979,7 +3027,7 @@
+       rt->qscale = (double)rt->rsize/(rt->rmax - rt->rmin);   /* Scale factor 
to quantize to */
+       
+       /* Initialize the reverse lookup structures, and get overall min/max */
+-      if ((rt->rlists = (int **) icp->al->calloc(icp->al, 1, rt->rsize * 
sizeof(int *))) == NULL) {
++      if ((rt->rlists = (int **) icp->al->calloc(icp->al, rt->rsize, 
sizeof(int *))) == NULL) {
+               return 2;
+       }
+ 
+@@ -2992,6 +3040,15 @@
+                       int t;
+                       t = s; s = e; e = t;
+               }
++              /* s and e should both be in the range [0,rt->rsize]
++               * now, but let's not rely on floating point
++               * calculations -- double-check. */
++              if (s < 0)
++                      s = 0;
++              if (e < 0)
++                      e = 0;
++              if (s >= rt->rsize)
++                      s = rt->rsize-1;
+               if (e >= rt->rsize)
+                       e = rt->rsize-1;
+ 
+@@ -3001,7 +3058,7 @@
+                       int nf;                 /* Next free slot */
+                       if (rt->rlists[j] == NULL) {    /* No allocation */
+                               as = 5;                                         
/* Start with space for 5 */
+-                              if ((rt->rlists[j] = (int *) 
icp->al->malloc(icp->al, sizeof(int) * as)) == NULL) {
++                              if ((rt->rlists[j] = (int *) 
icp->al->calloc(icp->al, sizeof(int), as)) == NULL) {
+                                       return 2;
+                               }
+                               rt->rlists[j][0] = as;
+@@ -3010,6 +3067,9 @@
+                               as = rt->rlists[j][0];  /* Allocate space for 
this list */
+                               nf = rt->rlists[j][1];  /* Next free location 
in list */
+                               if (nf >= as) {                 /* need to 
expand space */
++                                      if (as > INT_MAX / 2 / sizeof (int))
++                                              return 2;
++
+                                       as *= 2;
+                                       rt->rlists[j] = (int *) 
icp->al->realloc(icp->al,rt->rlists[j], sizeof(int) * as);
+                                       if (rt->rlists[j] == NULL) {
+@@ -3061,7 +3121,7 @@
+               val = rsize_1;
+       ix = (int)floor(val);           /* Coordinate */
+ 
+-      if (ix > (rt->size-2))
++      if (ix < 0 || ix > (rt->size-2))
+               ix = (rt->size-2);
+       if (rt->rlists[ix] != NULL)  {          /* There is a list of fwd 
candidates */
+               /* For each candidate forward range */
+@@ -3088,6 +3148,7 @@
+       /* We have failed to find an exact value, so return the nearest value */
+       /* (This is slow !) */
+       val = fabs(ival - rt->data[0]);
++      /* rt->size is known to be < INT_MAX */
+       for (k = 0, i = 1; i < rt->size; i++) {
+               double er;
+               er = fabs(ival - rt->data[i]);
+@@ -3141,6 +3202,10 @@
+       icmCurve *p = (icmCurve *)pp;
+       unsigned int len = 0;
+       len += 12;                      /* 12 bytes for tag, padding and count 
*/
++      if (p->size > (UINT_MAX - len) / 2) {
++              p->icp->errc = 1;
++              return (unsigned int) - 1;
++      }
+       len += p->size * 2;     /* 2 bytes for each UInt16 */
+       return len;
+ }
+@@ -3238,6 +3303,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmCurve_write malloc() failed");
+               return icp->errc = 2;
+@@ -3347,7 +3414,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (double *) icp->al->malloc(icp->al, p->size * 
sizeof(double))) == NULL) {
++              if ((p->data = (double *) icp->al->calloc(icp->al, p->size, 
sizeof(double))) == NULL) {
+                       sprintf(icp->err,"icmCurve_alloc: malloc() of icmCurve 
data failed");
+                       return icp->errc = 2;
+               }
+@@ -3493,6 +3560,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmData_write malloc() failed");
+               return icp->errc = 2;
+@@ -3620,7 +3689,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (unsigned char *) icp->al->malloc(icp->al, 
p->size * sizeof(unsigned char))) == NULL) {
++              if ((p->data = (unsigned char *) icp->al->calloc(icp->al, 
p->size, sizeof(unsigned char))) == NULL) {
+                       sprintf(icp->err,"icmData_alloc: malloc() of icmData 
data failed");
+                       return icp->errc = 2;
+               }
+@@ -3745,6 +3814,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmText_write malloc() failed");
+               return icp->errc = 2;
+@@ -3834,7 +3905,7 @@
+       if (p->size != p->_size) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (char *) icp->al->malloc(icp->al, p->size * 
sizeof(char))) == NULL) {
++              if ((p->data = (char *) icp->al->calloc(icp->al, p->size, 
sizeof(char))) == NULL) {
+                       sprintf(icp->err,"icmText_alloc: malloc() of icmText 
data failed");
+                       return icp->errc = 2;
+               }
+@@ -4038,6 +4109,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmDateTimeNumber_write malloc() failed");
+               return icp->errc = 2;
+@@ -4128,11 +4201,15 @@
+ /* icmLut object */
+ 
+ /* Utility function - raise one integer to an integer power */
+-static unsigned int uipow(unsigned int a, unsigned int b) {
++static int uipow(unsigned int a, unsigned int b, unsigned int *ret) {
+       unsigned int rv = 1;
+-      for (; b > 0; b--)
++      for (; b > 0; b--) {
++              if (a > 0 && rv > UINT_MAX / a)
++                      return 1;
+               rv *= a;
+-      return rv;
++      }
++      *ret = rv;
++      return 0;
+ }
+ 
+ /* - - - - - - - - - - - - - - - - */
+@@ -4242,7 +4319,7 @@
+                       rv |= 1;
+               }
+               ix = (int)floor(val);           /* Grid coordinate */
+-              if (ix > (p->inputEnt-2))
++              if (ix < 0 || ix > (p->inputEnt-2))
+                       ix = (p->inputEnt-2);
+               w = val - (double)ix;           /* weight */
+               val = table[ix];
+@@ -4268,7 +4345,7 @@
+       if (p->inputChan <= 8) {
+               gw = GW;                                /* Use stack allocation 
*/
+       } else {
+-              if ((gw = (double *) icp->al->malloc(icp->al, (1 << 
p->inputChan) * sizeof(double))) == NULL) {
++              if ((gw = (double *) icp->al->calloc(icp->al, (1 << 
p->inputChan), sizeof(double))) == NULL) {
+                       sprintf(icp->err,"icmLut_lookup_clut: malloc() failed");
+                       return icp->errc = 2;
+               }
+@@ -4301,7 +4378,7 @@
+                               rv |= 1;
+                       }
+                       x = (int)floor(val);            /* Grid coordinate */
+-                      if (x > clutPoints_2)
++                      if (x < 0 || x > clutPoints_2)
+                               x = clutPoints_2;
+                       co[e] = val - (double)x;        /* 1.0 - weight */
+                       gp += x * p->dinc[e];           /* Add index offset for 
base of cube */
+@@ -4374,7 +4451,7 @@
+                               rv |= 1;
+                       }
+                       x = (int)floor(val);            /* Grid coordinate */
+-                      if (x > clutPoints_2)
++                      if (x < 0 || x > clutPoints_2)
+                               x = clutPoints_2;
+                       co[e] = val - (double)x;        /* 1.0 - weight */
+                       gp += x * p->dinc[e];           /* Add index offset for 
base of cube */
+@@ -4447,7 +4524,7 @@
+                       rv |= 1;
+               }
+               ix = (int)floor(val);           /* Grid coordinate */
+-              if (ix > (p->outputEnt-2))
++              if (ix < 0 || ix > (p->outputEnt-2))
+                       ix = (p->outputEnt-2);
+               w = val - (double)ix;           /* weight */
+               val = table[ix];
+@@ -4819,19 +4896,50 @@
+ ) {
+       icmLut *p = (icmLut *)pp;
+       unsigned int len = 0;
++      unsigned int pw;
+ 
+       if (p->ttype == icSigLut8Type) {
+               len += 48;                      /* tag and header */
++              if (p->inputChan > 0 &&
++                  p->inputEnt > (UINT_MAX - len) / p->inputChan / 1)
++                      goto overflow;
++
+               len += 1 * (p->inputChan * p->inputEnt);
+-              len += 1 * (p->outputChan * uipow(p->clutPoints,p->inputChan));
++              if (uipow(p->clutPoints,p->inputChan, &pw) ||
++                  (p->outputChan > 0 &&
++                   pw > (UINT_MAX - len) / p->outputChan / 1))
++                      goto overflow;
++
++              len += 1 * (p->outputChan * pw);
++              if (p->outputChan > 0 &&
++                  p->outputEnt > (UINT_MAX - len) / p->outputChan / 1)
++                      goto overflow;
++
+               len += 1 * (p->outputChan * p->outputEnt);
+       } else {
+               len += 52;                      /* tag and header */
++              if (p->inputChan > 0 &&
++                  p->inputEnt > (UINT_MAX - len) / p->inputChan / 2)
++                      goto overflow;
++
+               len += 2 * (p->inputChan * p->inputEnt);
+-              len += 2 * (p->outputChan * uipow(p->clutPoints,p->inputChan));
++              if (uipow(p->clutPoints,p->inputChan, &pw) ||
++                  (p->outputChan > 0 &&
++                   pw > (UINT_MAX - len) / p->outputChan / 2))
++                      goto overflow;
++
++              len += 2 * (p->outputChan * pw);
++              if (p->outputChan > 0 &&
++                  p->outputEnt > (UINT_MAX - len) / p->outputChan / 2)
++                      goto overflow;
++
+               len += 2 * (p->outputChan * p->outputEnt);
+       }
+       return len;
++
++  overflow:
++      p->icp->errc = 1;
++      return (unsigned int) -1;
+ }
+ 
+ /* read the object, return 0 on success, error code on fail */
+@@ -4844,6 +4952,7 @@
+       icc *icp = p->icp;
+       int rv = 0;
+       unsigned long i, j, g, size;
++      unsigned int pw;
+       char *bp, *buf;
+ 
+       if (len < 4) {
+@@ -4904,6 +5013,11 @@
+               return icp->errc = 1;
+       }
+ 
++      if (p->clutPoints > 100) {
++              sprintf(icp->err,"icmLut_read: too many clutPoints");
++              return icp->errc = 1;
++      }
++
+       /* Read 3x3 transform matrix */
+       for (j = 0; j < 3; j++) {               /* Rows */
+               for (i = 0; i < 3; i++) {       /* Columns */
+@@ -4921,13 +5035,18 @@
+               bp = buf+52;
+       }
+ 
+-      if (len < icmLut_get_size((icmBase *)p)) {
++      if (len < icmLut_get_size((icmBase *)p) || icp->errc) {
+               sprintf(icp->err,"icmLut_read: Tag too small for contents");
+               icp->al->free(icp->al, buf);
+               return icp->errc = 1;
+       }
+ 
+       /* Read the input tables */
++      if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) {
++              sprintf(icp->err,"icmLut_read: overflow");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
+       size = (p->inputChan * p->inputEnt);
+       if ((rv = p->allocate((icmBase *)p)) != 0) {
+               icp->al->free(icp->al, buf);
+@@ -4942,7 +5061,14 @@
+       }
+ 
+       /* Read the clut table */
+-      size = (p->outputChan * uipow(p->clutPoints,p->inputChan));
++      if (uipow(p->clutPoints,p->inputChan,&pw) ||
++          (p->outputChan > 0 &&
++           pw > UINT_MAX / p->outputChan)) {
++              sprintf(icp->err,"icmLut_read: overflow");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
++      size = (p->outputChan * pw);
+       if ((rv = p->allocate((icmBase *)p)) != 0) {
+               icp->al->free(icp->al, buf);
+               return rv;
+@@ -4956,6 +5082,11 @@
+       }
+ 
+       /* Read the output tables */
++      if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) {
++              sprintf(icp->err,"icmLut_read: overflow");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
+       size = (p->outputChan * p->outputEnt);
+       if ((rv = p->allocate((icmBase *)p)) != 0) {
+               icp->al->free(icp->al, buf);
+@@ -4995,12 +5126,14 @@
+       icmLut *p = (icmLut *)pp;
+       icc *icp = p->icp;
+       unsigned long i,j;
+-      unsigned int len, size;
++      unsigned int len, size, pw;
+       char *bp, *buf;         /* Buffer to write from */
+       int rv = 0;
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmLut_write malloc() failed");
+               return icp->errc = 2;
+@@ -5066,6 +5199,11 @@
+       }
+ 
+       /* Write the input tables */
++      if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) {
++              sprintf(icp->err,"icmLut_write: overflow");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
+       size = (p->inputChan * p->inputEnt);
+       if (p->ttype == icSigLut8Type) {
+               for (i = 0; i < size; i++, bp += 1) {
+@@ -5086,7 +5224,14 @@
+       }
+ 
+       /* Write the clut table */
+-      size = (p->outputChan * uipow(p->clutPoints,p->inputChan));
++      if (uipow(p->clutPoints,p->inputChan,&pw) ||
++          (p->outputChan > 0 &&
++           pw > UINT_MAX / p->outputChan)) {
++              sprintf(icp->err,"icmLut_write: overflow");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
++      size = (p->outputChan * pw);
+       if (p->ttype == icSigLut8Type) {
+               for (i = 0; i < size; i++, bp += 1) {
+                       if ((rv = write_DCS8Number(p->clutTable[i], bp)) != 0) {
+@@ -5106,6 +5251,11 @@
+       }
+ 
+       /* Write the output tables */
++      if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) {
++              sprintf(icp->err,"icmLut_write: overflow");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
+       size = (p->outputChan * p->outputEnt);
+       if (p->ttype == icSigLut8Type) {
+               for (i = 0; i < size; i++, bp += 1) {
+@@ -5177,7 +5327,14 @@
+               if (p->inputChan > MAX_CHAN) {
+                       fprintf(op,"  !!Can't dump > %d input channel CLUT 
table!!\n",MAX_CHAN);
+               } else {
+-                      size = (p->outputChan * 
uipow(p->clutPoints,p->inputChan));
++                      unsigned int pw;
++                      if (uipow(p->clutPoints,p->inputChan,&pw) ||
++                          (p->outputChan > 0 &&
++                           pw > UINT_MAX / p->outputChan)) {
++                              fprintf(op,"Would overflow.\n");
++                              return;
++                      }
++                      size = (p->outputChan * pw);
+                       for (j = 0; j < p->inputChan; j++)
+                               ii[j] = 0;
+                       for (i = 0; i < size;) {
+@@ -5216,7 +5373,7 @@
+ static int icmLut_allocate(
+       icmBase *pp
+ ) {
+-      unsigned int i, j, g, size;
++      unsigned int i, j, g, size, pw;
+       icmLut *p = (icmLut *)pp;
+       icc *icp = p->icp;
+ 
+@@ -5231,6 +5388,10 @@
+               return icp->errc = 1;
+       }
+ 
++      if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) {
++              sprintf(icp->err,"icmLut_alloc: too many entries");
++              return icp->errc = 1;
++      }
+       size = (p->inputChan * p->inputEnt);
+       if (size != p->inputTable_size) {
+               if (p->inputTable != NULL)
+@@ -5241,7 +5402,13 @@
+               }
+               p->inputTable_size = size;
+       }
+-      size = (p->outputChan * uipow(p->clutPoints,p->inputChan));
++      if (uipow(p->clutPoints,p->inputChan,&pw) ||
++          (p->outputChan > 0 &&
++           pw > UINT_MAX / p->outputChan)) {
++              sprintf(icp->err,"icmLut_alloc: overflow");
++              return icp->errc = 1;
++      }
++      size = (p->outputChan * pw);
+       if (size != p->clutTable_size) {
+               if (p->clutTable != NULL)
+                       icp->al->free(icp->al, p->clutTable);
+@@ -5251,6 +5418,10 @@
+               }
+               p->clutTable_size = size;
+       }
++      if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) {
++              sprintf(icp->err,"icmLut_alloc: overflow");
++              return icp->errc = 1;
++      }
+       size = (p->outputChan * p->outputEnt);
+       if (size != p->outputTable_size) {
+               if (p->outputTable != NULL)
+@@ -5441,6 +5612,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmMeasurement_write malloc() failed");
+               return icp->errc = 2;
+@@ -5712,13 +5885,20 @@
+                       len += p->nDeviceCoords * 1;    /* bytes for each named 
color */
+               }
+       } else {        /* Named Color 2 */
++              unsigned int col;
+               len += 8;                       /* 8 bytes for tag and padding 
*/
+               len += 4;                       /* 4 for vendor specific flags 
*/
+               len += 4;                       /* 4 for count of named colors 
*/
+               len += 4;                       /* 4 for number of device 
coords */
+               len += 32;                      /* 32 for prefix of color names 
*/
+               len += 32;                      /* 32 for suffix of color names 
*/
+-              len += p->count * (32 + 6 + p->nDeviceCoords * 2);      /* 
bytes for each named color */
++              col = 32 + 6 + p->nDeviceCoords * 2;
++              if (p->nDeviceCoords > (UINT_MAX - (32 + 6)) / 2 ||
++                  (p->count > 0 && col > (UINT_MAX - len) / p->count)) {
++                      p->icp->errc = 1;
++                      return (unsigned int) -1;
++              }
++              len += p->count * col;  /* bytes for each named color */
+       }
+       return len;
+ }
+@@ -5882,6 +6062,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmNamedColor_write malloc() failed");
+               return icp->errc = 2;
+@@ -6109,9 +6291,22 @@
+ ) {
+       icmTextDescription *p = (icmTextDescription *)pp;
+       unsigned int len = 0;
++      if (p->size > UINT_MAX - (8 + 4 + 8)) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += 8;                       /* 8 bytes for tag and padding */
+       len += 4 + p->size;     /* Ascii string length + ascii string */
+-      len += 8 + 2 * p->ucSize;       /* Unicode language code + length + 
string */
++      len += 8;               /* Unicode language code + length */
++      if (p->ucSize > (UINT_MAX - len) / 2) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
++      len += 2 * p->ucSize;    /* Unicode string */
++      if (len > (UINT_MAX - (3 + 67))) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += 3 + 67;          /* ScriptCode code, length string */
+       return len;
+ }
+@@ -6294,6 +6489,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmTextDescription_write malloc() failed");
+               return icp->errc = 2;
+@@ -6535,7 +6732,7 @@
+       if (p->size != p->_size) {
+               if (p->desc != NULL)
+                       icp->al->free(icp->al, p->desc);
+-              if ((p->desc = (char *) icp->al->malloc(icp->al, p->size * 
sizeof(char))) == NULL) {
++              if ((p->desc = (char *) icp->al->calloc(icp->al, p->size, 
sizeof(char))) == NULL) {
+                       sprintf(icp->err,"icmTextDescription_alloc: malloc() of 
Ascii description failed");
+                       return icp->errc = 2;
+               }
+@@ -6544,7 +6741,7 @@
+       if (p->ucSize != p->uc_size) {
+               if (p->ucDesc != NULL)
+                       icp->al->free(icp->al, p->ucDesc);
+-              if ((p->ucDesc = (ORD16 *) icp->al->malloc(icp->al, p->ucSize * 
sizeof(ORD16))) == NULL) {
++              if ((p->ucDesc = (ORD16 *) icp->al->calloc(icp->al, p->ucSize, 
sizeof(ORD16))) == NULL) {
+                       sprintf(icp->err,"icmTextDescription_alloc: malloc() of 
Unicode description failed");
+                       return icp->errc = 2;
+               }
+@@ -6820,6 +7017,12 @@
+       bp += 8;        /* Skip padding */
+ 
+       p->count = read_UInt32Number(bp);       /* Number of sequence 
descriptions */
++      if (p->count > 1000) {
++              sprintf(icp->err,"icmProfileSequenceDesc_read: too many 
sequence descriptions");
++              icp->al->free(icp->al, buf);
++              return icp->errc = 1;
++      }
++
+       bp += 4;
+ 
+       /* Read all the sequence descriptions */
+@@ -6852,6 +7055,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmProfileSequenceDesc_write malloc() 
failed");
+               return icp->errc = 2;
+@@ -6922,7 +7127,7 @@
+       if (p->count != p->_count) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (icmDescStruct *) icp->al->malloc(icp->al, 
p->count * sizeof(icmDescStruct))) == NULL) {
++              if ((p->data = (icmDescStruct *) icp->al->calloc(icp->al, 
p->count, sizeof(icmDescStruct))) == NULL) {
+                       sprintf(icp->err,"icmProfileSequenceDesc_allocate 
Allocation of DescStruct array failed");
+                       return icp->errc = 2;
+               }
+@@ -7041,6 +7246,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmSignature_write malloc() failed");
+               return icp->errc = 2;
+@@ -7156,6 +7363,10 @@
+       icmScreening *p = (icmScreening *)pp;
+       unsigned int len = 0;
+       len += 16;                              /* 16 bytes for tag, padding, 
flag & channeles */
++      if (p->channels > (UINT_MAX - len) / 12) {
++              p->icp->errc = 1;
++              return (unsigned int) -1;
++      }
+       len += p->channels * 12;        /* 12 bytes for each channel */
+       return len;
+ }
+@@ -7235,6 +7446,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmScreening_write malloc() failed");
+               return icp->errc = 2;
+@@ -7315,7 +7528,7 @@
+       if (p->channels != p->_channels) {
+               if (p->data != NULL)
+                       icp->al->free(icp->al, p->data);
+-              if ((p->data = (icmScreeningData *) icp->al->malloc(icp->al, 
p->channels * sizeof(icmScreeningData))) == NULL) {
++              if ((p->data = (icmScreeningData *) icp->al->calloc(icp->al, 
p->channels, sizeof(icmScreeningData))) == NULL) {
+                       sprintf(icp->err,"icmScreening_alloc: malloc() of 
icmScreening data failed");
+                       return icp->errc = 2;
+               }
+@@ -7366,10 +7579,20 @@
+       icmUcrBg *p = (icmUcrBg *)pp;
+       unsigned int len = 0;
+       len += 8;                       /* 8 bytes for tag and padding */
++      if (p->UCRcount > (UINT_MAX - len - 4) / 2)
++              goto overflow;
++
+       len += 4 + p->UCRcount * 2;     /* Undercolor Removal */
++      if (p->BGcount > (UINT_MAX - len - 4 - p->size) / 2)
++              goto overflow;
++
+       len += 4 + p->BGcount * 2;      /* Black Generation */
+       len += p->size;                         /* Description string */
+       return len;
++
++ overflow:
++      p->icp->errc = 1;
++      return (unsigned int) -1;
+ }
+ 
+ /* read the object, return 0 on success, error code on fail */
+@@ -7498,6 +7721,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmUcrBg_write malloc() failed");
+               return icp->errc = 2;
+@@ -7663,7 +7888,7 @@
+       if (p->UCRcount != p->UCR_count) {
+               if (p->UCRcurve != NULL)
+                       icp->al->free(icp->al, p->UCRcurve);
+-              if ((p->UCRcurve = (double *) icp->al->malloc(icp->al, 
p->UCRcount * sizeof(double))) == NULL) {
++              if ((p->UCRcurve = (double *) icp->al->calloc(icp->al, 
p->UCRcount, sizeof(double))) == NULL) {
+                       sprintf(icp->err,"icmUcrBg_allocate: malloc() of UCR 
curve data failed");
+                       return icp->errc = 2;
+               }
+@@ -7672,7 +7897,7 @@
+       if (p->BGcount != p->BG_count) {
+               if (p->BGcurve != NULL)
+                       icp->al->free(icp->al, p->BGcurve);
+-              if ((p->BGcurve = (double *) icp->al->malloc(icp->al, 
p->BGcount * sizeof(double))) == NULL) {
++              if ((p->BGcurve = (double *) icp->al->calloc(icp->al, 
p->BGcount, sizeof(double))) == NULL) {
+                       sprintf(icp->err,"icmUcrBg_allocate: malloc() of BG 
curve data failed");
+                       return icp->errc = 2;
+               }
+@@ -7681,7 +7906,7 @@
+       if (p->size != p->_size) {
+               if (p->string != NULL)
+                       icp->al->free(icp->al, p->string);
+-              if ((p->string = (char *) icp->al->malloc(icp->al, p->size * 
sizeof(char))) == NULL) {
++              if ((p->string = (char *) icp->al->calloc(icp->al, p->size, 
sizeof(char))) == NULL) {
+                       sprintf(icp->err,"icmUcrBg_allocate: malloc() of string 
data failed");
+                       return icp->errc = 2;
+               }
+@@ -7743,6 +7968,15 @@
+               len += 2;       /* 2 bytes for channels */
+               len += 2;       /* 2 for entry count */
+               len += 2;       /* 2 for entry size */
++              if (p->u.table.entryCount > 0 &&
++                  p->u.table.entrySize > 0 &&
++                  p->u.table.channels >
++                  (UINT_MAX - len) /
++                  p->u.table.entryCount /
++                  p->u.table.entrySize) {
++                      p->icp->errc = 1;
++                      return (unsigned int) -1;
++              }
+               len += ( p->u.table.channels *     /* compute table size */
+                                p->u.table.entryCount *
+                                p->u.table.entrySize );
+@@ -7762,10 +7996,11 @@
+ ) {
+       icmVideoCardGamma *p = (icmVideoCardGamma *)pp;
+       icc *icp = p->icp;
+-      int rv, c;
++      int rv;
+       char *bp, *buf;
+       unsigned char *pchar;
+       unsigned short *pshort;
++      unsigned long c;
+ 
+       if (len < 18) {
+               sprintf(icp->err,"icmVideoCardGamma_read: Tag too small to be 
legal");
+@@ -7803,6 +8038,16 @@
+               p->u.table.channels   = read_UInt16Number(bp+12);
+               p->u.table.entryCount = read_UInt16Number(bp+14);
+               p->u.table.entrySize  = read_UInt16Number(bp+16);
++              if (p->u.table.entrySize > 65530 || p->u.table.entrySize == 0) {
++                      sprintf(icp->err,"icmVideoCardGamma_read: Too many 
entries (or none)");
++                      return icp->errc = 1;
++              }
++              if (p->u.table.entryCount > 0 && p->u.table.entrySize > 0 &&
++                  p->u.table.channels >
++                  UINT_MAX / p->u.table.entryCount / p->u.table.entrySize) {
++                      sprintf(icp->err,"icmVideoCardGamma_read: Overflow 
reading tag");
++                      return icp->errc = 1;
++              }
+               if (len-18 < 
p->u.table.channels*p->u.table.entryCount*p->u.table.entrySize) {
+                       sprintf(icp->err,"icmVideoCardGamma_read: Tag too small 
to be legal");
+                       return icp->errc = 1;
+@@ -7871,6 +8116,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmViewingConditions_write malloc() failed");
+               return icp->errc = 2;
+@@ -8049,7 +8296,7 @@
+ ) {
+       icmVideoCardGamma *p = (icmVideoCardGamma *)pp;
+       icc *icp = p->icp;
+-      int size;
++      unsigned int size;
+ 
+       /* note: allocation is only relevant for table type
+        * and in that case the channels, entryCount, and entrySize
+@@ -8059,6 +8306,11 @@
+       if (p->tagType == icmVideoCardGammaTableType) {
+               if (p->u.table.data != NULL)
+                       icp->al->free(icp->al, p->u.table.data);
++              if (p->u.table.entryCount > 0 &&
++                  p->u.table.channels > UINT_MAX / p->u.table.entryCount) {
++                      sprintf(icp->err,"icmVideoCardGamma_alloc: table too 
large");
++                      return icp->errc = 1;
++              }
+               size = (p->u.table.channels *
+                               p->u.table.entryCount);
+               switch (p->u.table.entrySize) {
+@@ -8066,6 +8318,10 @@
+                       size *= sizeof(unsigned char);
+                       break;
+               case 2:
++                      if (size > UINT_MAX / sizeof(unsigned short)) {
++                              sprintf(icp->err,"icmVideoCardGamma_alloc: 
table too large");
++                              return icp->errc = 1;
++                      }
+                       size *= sizeof(unsigned short);
+                       break;
+               default:
+@@ -8201,6 +8457,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmViewingConditions_write malloc() failed");
+               return icp->errc = 2;
+@@ -8433,6 +8691,8 @@
+ 
+       /* Allocate a file write buffer */
+       len = p->get_size((icmBase *)p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) {
+               sprintf(icp->err,"icmCrdInfo_write malloc() failed");
+               return icp->errc = 2;
+@@ -8585,7 +8845,7 @@
+       if (p->ppsize != p->_ppsize) {
+               if (p->ppname != NULL)
+                       icp->al->free(icp->al, p->ppname);
+-              if ((p->ppname = (char *) icp->al->malloc(icp->al, p->ppsize * 
sizeof(char))) == NULL) {
++              if ((p->ppname = (char *) icp->al->calloc(icp->al, p->ppsize, 
sizeof(char))) == NULL) {
+                       sprintf(icp->err,"icmCrdInfo_alloc: malloc() of string 
data failed");
+                       return icp->errc = 2;
+               }
+@@ -8595,7 +8855,7 @@
+               if (p->crdsize[t] != p->_crdsize[t]) {
+                       if (p->crdname[t] != NULL)
+                               icp->al->free(icp->al, p->crdname[t]);
+-                      if ((p->crdname[t] = (char *) icp->al->malloc(icp->al, 
p->crdsize[t] * sizeof(char))) == NULL) {
++                      if ((p->crdname[t] = (char *) icp->al->calloc(icp->al, 
p->crdsize[t], sizeof(char))) == NULL) {
+                               sprintf(icp->err,"icmCrdInfo_alloc: malloc() of 
CRD%d name string failed",t);
+                               return icp->errc = 2;
+                       }
+@@ -8736,6 +8996,8 @@
+       int rv = 0;
+ 
+       len = p->get_size(p);
++      if (icp->errc)
++              return icp->errc;
+       if ((buf = (char *) icp->al->calloc(icp->al,1,len)) == NULL) {          
        /* Zero it - some CMS are fussy */
+               sprintf(icp->err,"icmHeader_write calloc() failed");
+               return icp->errc = 2;
+@@ -9245,13 +9507,23 @@
+       }
+ 
+       p->count = read_UInt32Number(tcbuf);            /* Tag count */
++      if (p->count > 100) {
++              sprintf(p->err,"icc_read: too many table tags");
++              return p->errc = 1;
++      }
+       if (p->count > 0) {
+               char *bp, *buf;
+-              if ((p->data = (icmTag *) p->al->malloc(p->al, p->count * 
sizeof(icmTag))) == NULL) {
++              if ((p->data = (icmTag *) p->al->calloc(p->al, p->count, 
sizeof(icmTag))) == NULL) {
+                       sprintf(p->err,"icc_read: Tag table malloc() failed");
+                       return p->errc = 2;
+               }
+       
++              if (p->count > (UINT_MAX - 4) / 12) {
++                      sprintf(p->err,"icc_read: overflow");
++                      p->al->free(p->al, p->data);
++                      p->data = NULL;
++                      return p->errc = 1;
++              }
+               len = 4 + p->count * 12;
+               if ((buf = (char *) p->al->malloc(p->al, len)) == NULL) {
+                       sprintf(p->err,"icc_read: Tag table read buffer 
malloc() failed");
+@@ -9281,6 +9553,14 @@
+                   return p->errc = 1;
+               }
+               p->data[i].size = read_UInt32Number(bp + 8);    
++                      if (p->data[i].offset + p->data[i].size >
++                          p->header->size) {
++                              sprintf(p->err,"icc_read: tag out of bounds");
++                              p->al->free(p->al, p->data);
++                              p->data = NULL;
++                              p->al->free(p->al, buf);
++                              return p->errc = 1;
++                      }
+                       if (   p->fp->seek(p->fp, of + p->data[i].offset) != 0
+                           || p->fp->read(p->fp, tcbuf, 1, 4) != 4) {
+                               sprintf(p->err,"icc_read: fseek() or fread() 
failed on tag headers");
+@@ -9321,8 +9601,14 @@
+       }
+ 
+       size += p->header->get_size(p->header);
++      if (p->errc)
++              return (unsigned int) -1;
+ 
+       size = DO_ALIGN(size);
++      if (size == 0 || p->count > (UINT_MAX - 4 - size) / 12) {
++              p->errc = 1;
++              return (unsigned int) -1;
++      }
+       size += 4 + p->count * 12;      /* Tag table length */
+       
+       /* Reset touched flag for each tag type */
+@@ -9337,8 +9623,13 @@
+       /* Get size for each tag type, skipping links */
+       for (i = 0; i < p->count; i++) {
+               if (p->data[i].objp->touched == 0) { /* Not alllowed for 
previously */
++                      unsigned int obj_size;
+                       size = DO_ALIGN(size);
+-                      size += p->data[i].objp->get_size(p->data[i].objp);
++                      obj_size = p->data[i].objp->get_size(p->data[i].objp);
++                      if (size == 0 || p->errc ||
++                          obj_size > UINT_MAX - size)
++                              return (unsigned int) -1;
++                      size += obj_size;
+                       p->data[i].objp->touched = 1;   /* Don't account for 
this again */
+               }
+       }
+@@ -9373,9 +9664,19 @@
+       }
+ 
+       size += p->header->get_size(p->header);
++      if (p->errc)
++              return p->errc;
+ 
++      if (p->count > (UINT_MAX - 4 - len) / 12) {
++              sprintf(p->err,"icc_write: too many tags");
++              return p->errc = 1;
++      }
+       len = 4 + p->count * 12;        /* Tag table length */
+       size = DO_ALIGN(size);
++      if (size == 0 || size > UINT_MAX - len) {
++              sprintf(p->err,"icc_write: overflow writing tag table");
++              return p->errc = 1;
++      }
+       size += len;
+       
+       /* Allocate memory buffer for tag table */
+@@ -9406,6 +9707,12 @@
+                       size = DO_ALIGN(size);
+                       p->data[i].offset = size;                       /* 
Profile relative target */
+                       p->data[i].size = 
p->data[i].objp->get_size(p->data[i].objp);
++                      if (size == 0 ||
++                          p->errc || p->data[i].size > UINT_MAX - size) {
++                              sprintf(p->err,"icc_write: internal error - 
overflow?");
++                              p->al->free(p->al, buf);
++                              return p->errc;
++                      }
+                       size += p->data[i].size;
+                       p->data[i].objp->touched = 1;   /* Allocated space for 
it */
+               } else { /* must be linked - copy allocation */
+@@ -9529,6 +9836,11 @@
+       }
+ 
+       /* Make space in tag table for new tag item */
++      if (p->count > (UINT_MAX / sizeof(icmTag)) - 1) {
++              sprintf(p->err,"icc_add_tag: overflow");
++              p->errc = 1;
++              return NULL;
++      }
+       if (p->data == NULL)
+               tp = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag));
+       else
+@@ -9612,6 +9924,11 @@
+       }
+ 
+       /* Make space in tag table for new tag item */
++      if (p->count > (UINT_MAX / sizeof(icmTag)) - 1) {
++              sprintf(p->err,"icc_link_tag: overflow");
++              p->errc = 1;
++              return NULL;
++      }
+       if (p->data == NULL)
+               tp = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag));
+       else
+diff -Naur ghostscript-8.64.orig/jbig2dec/jbig2_symbol_dict.c 
ghostscript-8.64/jbig2dec/jbig2_symbol_dict.c
+--- ghostscript-8.64.orig/jbig2dec/jbig2_symbol_dict.c 2007-12-11 
08:29:58.000000000 +0000
++++ ghostscript-8.64/jbig2dec/jbig2_symbol_dict.c      2009-04-15 
23:30:05.000000000 +0100
+@@ -699,6 +699,15 @@
+         exrunlength = params->SDNUMEXSYMS;
+       else
+         code = jbig2_arith_int_decode(IAEX, as, &exrunlength);
++      if (exrunlength > params->SDNUMEXSYMS - j) {
++        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++          "runlength too large in export symbol table (%d > %d - %d)\n",
++          exrunlength, params->SDNUMEXSYMS, j);
++        jbig2_sd_release(ctx, SDEXSYMS);
++        /* skip to the cleanup code and return SDEXSYMS = NULL */
++        SDEXSYMS = NULL;
++        break;
++      }
+       for(k = 0; k < exrunlength; k++)
+         if (exflag) {
+           SDEXSYMS->glyphs[j++] = (i < m) ? 

-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to