+++ /dev/null
-Fix integer overflow vulnerabilities in the handling of Type1 fonts.
-
-*** xc/lib/font/Type1/AFM.h Sun May 2 23:58:44 1999
---- xc/lib/font/Type1/AFM.h Wed Sep 6 17:37:56 2006
-*************** typedef struct
-*** 47,52 ****
---- 47,54 ----
- BBox charBBox; /* key: B */
- } Metrics;
-
-+ #define MAX_CID_METRICS ((int)((unsigned int)(-1) / (2 * sizeof(Metrics))))
-+
- typedef struct
- {
- int nChars; /* number of entries in char metrics array */
-*** xc/lib/font/Type1/afm.c Fri Oct 14 09:16:02 2005
---- xc/lib/font/Type1/afm.c Wed Sep 6 17:37:56 2006
-*************** int CIDAFM(FILE *fd, FontInfo **pfi) {
-*** 111,116 ****
---- 111,122 ----
-
- fi->nChars = atoi(p);
-
-+ if ((fi->nChars <= 0) || (fi->nChars > MAX_CID_METRICS)) {
-+ xfree(afmbuf);
-+ xfree(fi);
-+ return(1);
-+ }
-+
- fi->metrics = (Metrics *)xalloc(fi->nChars *
- sizeof(Metrics));
- if (fi->metrics == NULL) {
-*** xc/lib/font/Type1/range.h Tue May 4 03:35:22 1999
---- xc/lib/font/Type1/range.h Wed Sep 6 17:37:56 2006
-*************** typedef struct spacerange_code {
-*** 24,29 ****
---- 24,32 ----
- unsigned int srcCodeHi;
- } spacerangecode;
-
-+ #define MAX_CID_SPACERANGECODES \
-+ ((int)((unsigned int)(-1) / (2 * sizeof(spacerangecode))))
-+
- typedef struct space_range {
- struct space_range *next;
- int rangecnt;
-*************** typedef struct cidrange_code {
-*** 36,41 ****
---- 39,47 ----
- unsigned int dstCIDLo;
- } cidrangecode;
-
-+ #define MAX_CID_CIDRANGECODES \
-+ ((int)((unsigned int)(-1) / (2 * sizeof(cidrangecode))))
-+
- typedef struct cid_range {
- struct cid_range *next;
- int rangecnt;
-*** xc/lib/font/Type1/scanfont.c Fri Oct 14 09:16:02 2005
---- xc/lib/font/Type1/scanfont.c Wed Sep 6 17:37:56 2006
-*************** scan_cidfont(cidfont *CIDFontP, cmapres
-*** 1732,1737 ****
---- 1732,1741 ----
- break;
- case TOKEN_NAME:
- if (0 == strncmp(tokenStartP,"begincodespacerange",19)) {
-+ if ((rangecnt <= 0) || (rangecnt > MAX_CID_SPACERANGECODES)) {
-+ rc = SCAN_OUT_OF_MEMORY;
-+ break;
-+ }
- CIDFontP->spacerangecnt++;
- spacerangeP = (spacerange *)vm_alloc(sizeof(spacerange));
- if (!spacerangeP) {
-*************** scan_cidfont(cidfont *CIDFontP, cmapres
-*** 1787,1792 ****
---- 1791,1800 ----
- }
- }
- if (0 == strncmp(tokenStartP,"begincidrange",13)) {
-+ if ((rangecnt <= 0) || (rangecnt > MAX_CID_CIDRANGECODES)) {
-+ rc = SCAN_OUT_OF_MEMORY;
-+ break;
-+ }
- CIDFontP->cidrangecnt++;
- cidrangeP = (cidrange *)vm_alloc(sizeof(cidrange));
- if (!cidrangeP) {
-*************** scan_cidfont(cidfont *CIDFontP, cmapres
-*** 1868,1873 ****
---- 1876,1885 ----
- }
-
- if (0 == strncmp(tokenStartP,"beginnotdefrange",16)) {
-+ if ((rangecnt <= 0) || (rangecnt > MAX_CID_CIDRANGECODES)) {
-+ rc = SCAN_OUT_OF_MEMORY;
-+ break;
-+ }
- CIDFontP->notdefrangecnt++;
- notdefrangeP = (cidrange *)vm_alloc(sizeof(cidrange));
- if (!notdefrangeP) {
-*** xc/lib/font/Type1/util.c Fri Oct 14 09:16:03 2005
---- xc/lib/font/Type1/util.c Wed Sep 6 17:42:08 2006
-*************** vm_alloc(int bytes)
-*** 96,102 ****
- bytes = (bytes + 7) & ~7;
-
- /* Allocate the space, if it is available */
-! if (bytes <= vm_free) {
- answer = vm_next;
- vm_free -= bytes;
- vm_next += bytes;
---- 96,102 ----
- bytes = (bytes + 7) & ~7;
-
- /* Allocate the space, if it is available */
-! if ((bytes > 0) && (bytes <= vm_free)) {
- answer = vm_next;
- vm_free -= bytes;
- vm_next += bytes;
+++ /dev/null
---- XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.c.orig 2005-10-14 17:16:01.000000000 +0200
-+++ XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.c 2006-07-19 08:16:57.502772250 +0200
-@@ -50,10 +50,7 @@
- #include FT_TYPE1_TABLES_H
- #include FT_XFREE86_H
- #include FT_BBOX_H
--#include FT_INTERNAL_TRUETYPE_TYPES_H
- #include FT_TRUETYPE_TAGS_H
--#include FT_INTERNAL_SFNT_H
--#include FT_INTERNAL_STREAM_H
- /*
- * If you want to use FT_Outline_Get_CBox instead of
- * FT_Outline_Get_BBox, define here.
-@@ -119,6 +116,25 @@
- };
-
-
-+/* read 2-byte value from a SFNT table */
-+static FT_UShort
-+sfnt_get_ushort( FT_Face face,
-+ FT_ULong table_tag,
-+ FT_ULong table_offset )
-+{
-+ FT_Byte buff[2];
-+ FT_ULong len = sizeof(buff);
-+ FT_UShort result = 0;
-+
-+ if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) );
-+ result = (FT_UShort)( (buff[0] << 8) | buff[1] );
-+
-+ return result;
-+}
-+
-+#define sfnt_get_short(f,t,o) ((FT_Short)sfnt_get_ushort((f),(t),(o)))
-+
-+
- static int ftypeInitP = 0; /* is the engine initialised? */
- static FT_Library ftypeLibrary;
-
-@@ -207,6 +223,10 @@
- if(maxp && maxp->maxContours == 0)
- face->bitmap = 1;
- }
-+
-+ face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face,
-+ TTAG_hhea, 34 );
-+
- /* Insert face in hashtable and return it */
- face->next = faceTable[bucket];
- faceTable[bucket] = face;
-@@ -458,6 +478,34 @@
- }
-
- if( FT_IS_SFNT( face->face ) ) {
-+#if 1
-+ FT_F26Dot6 tt_char_width, tt_char_height, tt_dim_x, tt_dim_y;
-+ FT_UInt nn;
-+
-+ instance->strike_index=0xFFFFU;
-+
-+ tt_char_width = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
-+ tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
-+
-+ tt_dim_x = FLOOR64( ( tt_char_width * trans->xres + 36 ) / 72 + 32 );
-+ tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 );
-+
-+ if ( tt_dim_x && !tt_dim_y )
-+ tt_dim_y = tt_dim_x;
-+ else if ( !tt_dim_x && tt_dim_y )
-+ tt_dim_x = tt_dim_y;
-+
-+ for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ )
-+ {
-+ FT_Bitmap_Size* sz = &face->face->available_sizes[nn];
-+
-+ if ( tt_dim_x == FLOOR64(sz->x_ppem + 32) && tt_dim_y == FLOOR64(sz->y_ppem + 32) )
-+ {
-+ instance->strike_index = nn;
-+ break;
-+ }
-+ }
-+#else
- /* See Set_Char_Sizes() in ttdriver.c */
- FT_Error err;
- TT_Face tt_face;
-@@ -482,6 +530,7 @@
- sfnt = (SFNT_Service)tt_face->sfnt;
- err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index);
- if ( err ) instance->strike_index=0xFFFFU;
-+#endif
- }
-
- /* maintain a linked list of instances */
-@@ -799,31 +848,61 @@
- * parse the htmx field in TrueType font.
- */
-
--/* from src/truetype/ttgload.c */
- static void
--tt_get_metrics( TT_HoriHeader* header,
-+tt_get_metrics( FT_Face face,
- FT_UInt idx,
-+ FT_UInt num_hmetrics,
- FT_Short* bearing,
- FT_UShort* advance )
--/* Copyright 1996-2001, 2002 by */
--/* David Turner, Robert Wilhelm, and Werner Lemberg. */
- {
-- TT_LongMetrics longs_m;
-- FT_UShort k = header->number_Of_HMetrics;
-+ /* read the metrics directly from the horizontal header, we
-+ * parse the SFNT table directly through the standard FreeType API.
-+ * this works with any version of the library and doesn't need to
-+ * peek at its internals. Maybe a bit less
-+ */
-+ FT_UInt count = num_hmetrics;
-+ FT_ULong length = 0;
-+ FT_ULong offset = 0;
-+ FT_Error error;
-
-- if ( k == 0 ) {
-- *bearing = *advance = 0;
-- return;
-- }
-+ error = FT_Load_Sfnt_Table( face, TTAG_hmtx, 0, NULL, &length );
-
-- if ( idx < (FT_UInt)k ) {
-- longs_m = (TT_LongMetrics )header->long_metrics + idx;
-- *bearing = longs_m->bearing;
-- *advance = longs_m->advance;
-+ if ( count == 0 || error )
-+ {
-+ *advance = 0;
-+ *bearing = 0;
-+ }
-+ else if ( idx < count )
-+ {
-+ offset = idx * 4L;
-+ if ( offset + 4 > length )
-+ {
-+ *advance = 0;
-+ *bearing = 0;
-+ }
-+ else
-+ {
-+ *advance = sfnt_get_ushort( face, TTAG_hmtx, offset );
-+ *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 );
-+ }
-+ }
-+ else
-+ {
-+ offset = 4L * (count - 1);
-+ if ( offset + 4 > length )
-+ {
-+ *advance = 0;
-+ *bearing = 0;
-+ }
-+ else
-+ {
-+ *advance = sfnt_get_ushort ( face, TTAG_hmtx, offset );
-+ offset += 4 + 2 * ( idx - count );
-+ if ( offset + 2 > length)
-+ *bearing = 0;
-+ else
-+ *bearing = sfnt_get_short ( face, TTAG_hmtx, offset );
- }
-- else {
-- *bearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k];
-- *advance = ((TT_LongMetrics )header->long_metrics)[k - 1].advance;
- }
- }
-
-@@ -831,6 +910,7 @@
- ft_get_very_lazy_bbox( FT_UInt index,
- FT_Face face,
- FT_Size size,
-+ FT_UInt num_hmetrics,
- double slant,
- FT_Matrix *matrix,
- FT_BBox *bbox,
-@@ -838,15 +918,14 @@
- FT_Long *vertAdvance)
- {
- if ( FT_IS_SFNT( face ) ) {
-- TT_Face ttface = (TT_Face)face;
- FT_Size_Metrics *smetrics = &size->metrics;
- FT_Short leftBearing = 0;
- FT_UShort advance = 0;
- FT_Vector p0, p1, p2, p3;
-
- /* horizontal */
-- tt_get_metrics(&ttface->horizontal, index,
-- &leftBearing, &advance);
-+ tt_get_metrics( face, index, num_hmetrics,
-+ &leftBearing, &advance );
-
- #if 0
- fprintf(stderr,"x_scale=%f y_scale=%f\n",
-@@ -903,8 +982,30 @@
-
- static FT_Error
- FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index,
-- FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return )
-+ FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return,
-+ int *sbitchk_incomplete_but_exist )
- {
-+#if 1
-+ if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL )
-+ {
-+ FT_Error error;
-+ FT_Bitmap_Size* sz = &ft_face->available_sizes[strike_index];
-+
-+ error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 );
-+ if ( !error )
-+ {
-+ error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY );
-+ if ( !error )
-+ {
-+ if ( metrics_return != NULL )
-+ *metrics_return = ft_face->glyph->metrics;
-+
-+ return 0;
-+ }
-+ }
-+ }
-+ return -1;
-+#elif (FREETYPE_VERSION >= 2001008)
- SFNT_Service sfnt;
- TT_Face face;
- FT_Error error;
-@@ -925,7 +1026,8 @@
- face = (TT_Face)ft_face;
- sfnt = (SFNT_Service)face->sfnt;
-
-- if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
-+ if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image &&
-+ sfnt->load_sbits) {
- /* Check whether there is a glyph sbit for the current index */
- error = sfnt->find_sbit_image( face, glyph_index, strike_index,
- &range, &strike, &glyph_offset );
-@@ -968,6 +1070,17 @@
-
- Exit:
- return error;
-+#else /* if (FREETYPE_VERSION < 2001008) */
-+ TT_Face face;
-+ SFNT_Service sfnt;
-+ if ( ! FT_IS_SFNT( ft_face ) ) return -1;
-+ face = (TT_Face)ft_face;
-+ sfnt = (SFNT_Service)face->sfnt;
-+ if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
-+ if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1;
-+ }
-+ return -1;
-+#endif
- }
-
- int
-@@ -986,6 +1099,7 @@
- int dx, dy;
- int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth,
- ascent, descent;
-+ int sbitchk_incomplete_but_exist;
- double bbox_center_raw;
-
- face = instance->face;
-@@ -1014,15 +1128,17 @@
- int new_width;
- double ratio;
-
-+ sbitchk_incomplete_but_exist=0;
- if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) {
- if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index,
-- idx,&sbit_metrics)==0 ) {
-+ idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) {
- bitmap_metrics = &sbit_metrics;
- }
- }
- if( bitmap_metrics == NULL ) {
-- if ( instance->ttcap.flags & TTCAP_IS_VERY_LAZY ) {
-+ if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
- if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
-+ face->num_hmetrics,
- instance->ttcap.vl_slant,
- &instance->transformation.matrix,
- &bbox, &outline_hori_advance,
-@@ -1040,6 +1156,8 @@
- }
-
- if( bitmap_metrics ) {
-+ FT_Pos factor;
-+
- leftSideBearing = bitmap_metrics->horiBearingX / 64;
- rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64;
- bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0;
-@@ -1062,8 +1180,8 @@
- rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic;
- leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic;
- /* */
-- rawCharacterWidth =
-- (unsigned short)(short)(floor(1000 * bitmap_metrics->horiAdvance
-+ factor = bitmap_metrics->horiAdvance;
-+ rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor
- * instance->ttcap.scaleBBoxWidth * ratio / 64.
- / instance->pixel_size));
- }
-@@ -1155,14 +1273,16 @@
- else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1;
- else{
- int sbit_available=0;
-+ sbitchk_incomplete_but_exist=0;
- if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) {
- if( FT_Do_SBit_Metrics(face->face,instance->size,
-- instance->strike_index,idx,NULL)==0 ) {
-+ instance->strike_index,idx,NULL,
-+ &sbitchk_incomplete_but_exist)==0 ) {
- sbit_available=1;
- }
- }
- if( sbit_available == 0 ) {
-- if ( instance->ttcap.flags & TTCAP_IS_VERY_LAZY ) {
-+ if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
- if( FT_IS_SFNT(face->face) ) correct=1;
- }
- }
-@@ -1183,10 +1303,27 @@
- }
-
- if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
-+#ifdef USE_GET_CBOX
-+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
-+ ftrc = 0;
-+#else
-+ ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
-+#endif
-+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
-+ bbox.yMin = FLOOR64( bbox.yMin );
-+ bbox.yMax = CEIL64 ( bbox.yMax );
-+ ht_actual = ( bbox.yMax - bbox.yMin ) >> 6;
-+ /* FreeType think a glyph with 0 height control box is invalid.
-+ * So just let X to create a empty bitmap instead. */
-+ if ( ht_actual == 0 )
-+ is_outline = -1;
-+ else
-+ {
- ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO);
- if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
- is_outline = 1;
- }
-+ }
- else{
- is_outline=0;
- }
-@@ -1197,6 +1334,7 @@
- if( is_outline == 1 ){
- if( correct ){
- if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
-+ face->num_hmetrics,
- instance->ttcap.vl_slant,
- &instance->transformation.matrix,
- &bbox, &outline_hori_advance,
---- XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.h.orig 2004-04-14 17:32:43.000000000 +0200
-+++ XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.h 2006-07-19 08:17:53.774289000 +0200
-@@ -47,6 +47,7 @@
- char *filename;
- FT_Face face;
- int bitmap;
-+ FT_UInt num_hmetrics;
- struct _FTInstance *instances;
- struct _FTInstance *active_instance;
- struct _FTFace *next; /* link to next face in bucket */
---- XFree86-4.6.0/xc/programs/fonttosfnt/util.c.orig 2005-02-07 02:01:16.000000000 +0100
-+++ XFree86-4.6.0/xc/programs/fonttosfnt/util.c 2006-07-19 17:46:00.392569500 +0200
-@@ -34,7 +34,6 @@
-
- #include <ft2build.h>
- #include FT_FREETYPE_H
--#include FT_INTERNAL_OBJECTS_H
- #include FT_BDF_H
- #include "X11/Xos.h"
- #include "fonttosfnt.h"