For all binary searches, handle the case where the number of items is 0.
authorOwen Taylor <otaylor@redhat.com>
Thu, 3 Mar 2005 19:38:02 +0000 (19:38 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 3 Mar 2005 19:38:02 +0000 (19:38 +0000)
2005-03-03  Owen Taylor  <otaylor@redhat.com>

        * pango/opentype/ftxopen.c (Coverage_Index1, Coverage_Index2,
        Get_Class2): For all binary searches, handle the case where
        the number of items is 0. (#162977, Nick Lamb)

        * pango/opentype/ftxgdef.c (TT_GDEF_Build_ClassDefinition):
        Handle the case where glyph_count == 0 properly. Fix a problem
        with cleanups on memory allocation failure.
        (Get_New_Count, Add_Glyph_Property): Avoid reading off the
        end of the ClassRangeRecord array.

src/ftxgdef.c
src/ftxopen.c

index 60ad581..7367be7 100644 (file)
                                   FT_UShort        glyphID,
                                   FT_UShort        index )
   {
-    FT_UShort              glyph_index, array_index;
+    FT_UShort              glyph_index, array_index, count;
     FT_UShort              byte, bits;
     
     TTO_ClassRangeRecord*  gcrr;
     if ( glyphID >= gdef->LastGlyph )
       return 0;
 
+    count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
     gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
     ngc  = gdef->NewGlyphClasses;
 
-    if ( glyphID < gcrr[index].Start )
+    if ( index < count && glyphID < gcrr[index].Start )
     {
       array_index = index;
       if ( index == 0 )
 
     if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
                       gcd->cd.cd2.ClassRangeCount + 1, FT_UShort* ) )
-      goto Fail2;
+      goto Fail3;
 
     count = gcd->cd.cd2.ClassRangeCount;
     gcrr  = gcd->cd.cd2.ClassRangeRecord;
     /* We allocate arrays for all glyphs not covered by the class range
        records.  Each element holds four class values.                  */
 
-    if ( gcrr[0].Start )
+    if ( count > 0 )
     {
-      if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, FT_UShort ) )
-        goto Fail1;
+       if ( gcrr[0].Start )
+       {
+         if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, FT_UShort ) )
+           goto Fail2;
+       }
+
+       for ( n = 1; n < count; n++ )
+       {
+         if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
+           if ( ALLOC_ARRAY( ngc[n],
+                             ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4,
+                             FT_UShort ) )
+             goto Fail1;
+       }
+
+       if ( gcrr[count - 1].End != num_glyphs - 1 )
+       {
+         if ( ALLOC_ARRAY( ngc[count],
+                           ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
+                           FT_UShort ) )
+             goto Fail1;
+       }
     }
-
-    for ( n = 1; n < count; n++ )
+    else if ( num_glyphs > 0 )
     {
-      if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
-        if ( ALLOC_ARRAY( ngc[n],
-                          ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4,
-                          FT_UShort ) )
-          goto Fail1;
+       if ( ALLOC_ARRAY( ngc[count],
+                         ( num_glyphs + 3 ) / 4,
+                         FT_UShort ) )
+           goto Fail2;
     }
-
-    if ( gcrr[count - 1].End != num_glyphs - 1 )
-    {
-      if ( ALLOC_ARRAY( ngc[count],
-                        ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
-                        FT_UShort ) )
-        goto Fail1;
-    }
-
+       
     gdef->LastGlyph = num_glyphs - 1;
 
     gdef->MarkAttachClassDef_offset = 0L;
     FT_Error               error;
     FT_UShort              class, new_class, index;
     FT_UShort              byte, bits, mask;
-    FT_UShort              array_index, glyph_index;
+    FT_UShort              array_index, glyph_index, count;
 
     TTO_ClassRangeRecord*  gcrr;
     FT_UShort**            ngc;
       return TT_Err_Invalid_Argument;
     }
 
+    count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
     gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
     ngc  = gdef->NewGlyphClasses;
 
-    if ( glyphID < gcrr[index].Start )
+    if ( index < count && glyphID < gcrr[index].Start )
     {
       array_index = index;
       if ( index == 0 )
index f2ebf87..ea38216 100644 (file)
 
     /* binary search */
 
+    if ( cf1->GlyphCount == 0 )
+      return TTO_Err_Not_Covered;
+
     new_min = 0;
     new_max = cf1->GlyphCount - 1;
 
 
     /* binary search */
 
+    if ( cf2->RangeCount == 0 )
+      return TTO_Err_Not_Covered;
+
     new_min = 0;
     new_max = cf2->RangeCount - 1;
 
 
     /* binary search */
 
+    if ( cdf2->ClassRangeCount == 0 )
+      {
+       *class = 0;
+       if ( index )
+         *index = 0;
+       
+       return TTO_Err_Not_Covered;
+      }
+
     new_min = 0;
     new_max = cdf2->ClassRangeCount - 1;