Commit 2630e54d2aee2785196c8a04fee3e0d8898c04cc

Werner Lemberg 2004-03-20T14:26:38

* src/sfnt/ttload.c (tt_face_load_sfnt_header): Reject face_index values > 0 if loading non-TTC fonts. * src/base/ftmac.c (open_face_from_buffer): Set positive face_index to zero before calling FT_Open_Face. * docs/CHANGES: Updated.

diff --git a/ChangeLog b/ChangeLog
index de7b8f6..933b857 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-03-19  Steve Hartwell  <shspamsink@comcast.net>
+
+	* src/sfnt/ttload.c (tt_face_load_sfnt_header): Reject face_index
+	values > 0 if loading non-TTC fonts.
+
+	* src/base/ftmac.c (open_face_from_buffer): Set positive face_index
+	to zero before calling FT_Open_Face.
+
+	* docs/CHANGES: Updated.
+
 2004-03-04  Werner Lemberg  <wl@gnu.org>
 
 	* Jamfile, vms_make.com, builds/win32/visualc/freetype.dsp,
diff --git a/docs/CHANGES b/docs/CHANGES
index 75cbcba..6ca0e1c 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -140,6 +140,9 @@ LATEST CHANGES BETWEEN 2.1.8 and 2.1.7
       - The  demo programs  have been  updated to  the new  code.  The
         previous versions will not work with the current one.
 
+      - Using  an invalid face  index in FT_Open_Face and friends  now
+        causes an error even if the font contains a single face only.
+
 
   III. MISCELLANEOUS
 
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 02195b2..4837637 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -768,10 +768,12 @@ FT_BEGIN_HEADER
   /*                           collection (i.e., a file which embeds       */
   /*                           several faces), this is the total number of */
   /*                           faces found in the resource.  1 by default. */
+  /*                           Accessing non-existent face indices causes  */
+  /*                           an error.                                   */
   /*                                                                       */
   /*    face_index          :: The index of the face in its font file.     */
   /*                           Usually, this is 0 for all normal font      */
-  /*                           formats.  It can be more in the case of     */
+  /*                           formats.  It can be > 0 in the case of      */
   /*                           collections (which embed several fonts in a */
   /*                           single resource/file).                      */
   /*                                                                       */
@@ -1749,6 +1751,7 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    face_index :: The index of the face within the resource.  The      */
   /*                  first face has index 0.                              */
+  /*                                                                       */
   /* <Output>                                                              */
   /*    aface      :: A handle to a new face object.                       */
   /*                                                                       */
@@ -1762,9 +1765,9 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    @FT_New_Face can be used to determine and/or check the font format */
   /*    of a given font resource.  If the `face_index' field is negative,  */
-  /*    the function will _not_ return any face handle in `aface'.  Its    */
-  /*    return value should be 0 if the font format is recognized, or      */
-  /*    non-zero otherwise.                                                */
+  /*    the function will _not_ return any face handle in `aface';  the    */
+  /*    return value is 0 if the font format is recognized, or non-zero    */
+  /*    otherwise.                                                         */
   /*                                                                       */
   /*    Each new face object created with this function also owns a        */
   /*    default @FT_Size object, accessible as `face->size'.               */
@@ -1795,6 +1798,7 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    face_index :: The index of the face within the resource.  The      */
   /*                  first face has index 0.                              */
+  /*                                                                       */
   /* <Output>                                                              */
   /*    aface      :: A handle to a new face object.                       */
   /*                                                                       */
@@ -1814,8 +1818,8 @@ FT_BEGIN_HEADER
   /*    @FT_New_Memory_Face can be used to determine and/or check the font */
   /*    format of a given font resource.  If the `face_index' field is     */
   /*    negative, the function will _not_ return any face handle in        */
-  /*    `aface'.  Its return value should be 0 if the font format is       */
-  /*    recognized, or non-zero otherwise.                                 */
+  /*    `aface'; the return value is 0 if the font format is recognized,   */
+  /*    or non-zero otherwise.                                             */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_New_Memory_Face( FT_Library      library,
@@ -1844,6 +1848,7 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    face_index :: The index of the face within the resource.  The      */
   /*                  first face has index 0.                              */
+  /*                                                                       */
   /* <Output>                                                              */
   /*    aface      :: A handle to a new face object.                       */
   /*                                                                       */
@@ -1855,11 +1860,11 @@ FT_BEGIN_HEADER
   /*    slot for the face object which can be accessed directly through    */
   /*    `face->glyph'.                                                     */
   /*                                                                       */
-  /*    @FT_Open_Face can be used to determine and/or check the font      */
+  /*    @FT_Open_Face can be used to determine and/or check the font       */
   /*    format of a given font resource.  If the `face_index' field is     */
   /*    negative, the function will _not_ return any face handle in        */
-  /*    `*face'.  Its return value should be 0 if the font format is       */
-  /*    recognized, or non-zero otherwise.                                 */
+  /*    `*face'; the return value is 0 if the font format is recognized,   */
+  /*    or non-zero otherwise.                                             */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Open_Face( FT_Library           library,
diff --git a/src/base/ftmac.c b/src/base/ftmac.c
index 87c277a..d64f010 100644
--- a/src/base/ftmac.c
+++ b/src/base/ftmac.c
@@ -611,6 +611,14 @@
       args.driver = FT_Get_Module( library, driver_name );
     }
 
+    /* At this point, face_index has served its purpose;      */
+    /* whoever calls this function has already used it to     */
+    /* locate the correct font data.  We should not propagate */
+    /* this index to FT_Open_Face() (unless it is negative).  */
+
+    if ( face_index > 0 )
+      face_index = 0;
+
     error = FT_Open_Face( library, &args, face_index, aface );
     if ( error == FT_Err_Ok )
       (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 937cd02..12361fa 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -253,7 +253,7 @@
   /*    stream     :: The input stream.                                    */
   /*                                                                       */
   /*    face_index :: If the font is a collection, the number of the font  */
-  /*                  in the collection, ignored otherwise.                */
+  /*                  in the collection.  Must be zero otherwise.          */
   /*                                                                       */
   /* <Output>                                                              */
   /*    sfnt       :: The SFNT header.                                     */
@@ -313,10 +313,9 @@
 
     face->num_tables = 0;
 
-    /* first of all, read the first 4 bytes.  If it is `ttcf', then the */
-    /* file is a TrueType collection, otherwise it can be any other     */
-    /* kind of font.                                                    */
-    /*                                                                  */
+    /* First of all, read the first 4 bytes.  If it is `ttcf', then the   */
+    /* file is a TrueType collection, otherwise it is a single-face font. */
+    /*                                                                    */
     offset = FT_STREAM_POS();
 
     if ( FT_READ_ULONG( format_tag ) )
@@ -358,6 +357,11 @@
            FT_READ_LONG( format_tag )                             )
         goto Exit;
     }
+    else if ( face_index > 0 )
+    {
+      error = SFNT_Err_Bad_Argument;
+      goto Exit;
+    }
 
     /* the format tag was read, now check the rest of the header */
     sfnt->format_tag = format_tag;