[sfnt] Additional guards on the POST table.

Fixes timeout (#1055) analyzed by Ben Wagner, reported as

  https://crbug.com/1194092

* src/sfnt/ttload.c (tt_face_load_post): Check POST format.
* src/sfnt/sfobjs.c (sfnt_load_face): Synthesize the missing unicode
charmap only if the glyph names exist.
* src/psnames/psmodule.c (ps_unicode_value): Short cut ".notdef" and
".null".
diff --git a/ChangeLog b/ChangeLog
index 2fdcce5..5a6132e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2021-05-16  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sfnt] Additional guards on the POST table.
+
+	Fixes timeout (#1055) analyzed by Ben Wagner, reported as
+
+	  https://crbug.com/1194092
+
+	* src/sfnt/ttload.c (tt_face_load_post): Check POST format.
+	* src/sfnt/sfobjs.c (sfnt_load_face): Synthesize the missing unicode
+	charmap only if the glyph names exist.
+	* src/psnames/psmodule.c (ps_unicode_value): Short cut ".notdef" and
+	".null".
+
 2021-05-13  Daniel McArdle  <dmcardle@chromium.org>
 
 	[psaux] Use doubling allocation strategy for CF2_ArrStack.
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 411b2e3..186e8ed 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -155,25 +155,24 @@
     /* Look for a non-initial dot in the glyph name in order to */
     /* find variants like `A.swash', `e.final', etc.            */
     {
-      const char*  p   = glyph_name;
-      const char*  dot = NULL;
+      FT_UInt32    value = 0;
+      const char*  p     = glyph_name;
 
 
-      for ( ; *p; p++ )
+      for ( ; *p && *p != '.'; p++ )
+        ;
+
+      /* now look up the glyph in the Adobe Glyph List;      */
+      /* `.notdef', `.null' and the empty name are short cut */
+      if ( p > glyph_name )
       {
-        if ( *p == '.' && p > glyph_name )
-        {
-          dot = p;
-          break;
-        }
+        value =  (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
+
+        if ( *p == '.' )
+          value |= (FT_UInt32)VARIANT_BIT;
       }
 
-      /* now look up the glyph in the Adobe Glyph List */
-      if ( !dot )
-        return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
-      else
-        return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
-                            VARIANT_BIT );
+      return value;
     }
   }
 
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 4b7cdd2..cf73071 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -1150,9 +1150,10 @@
         }
 
         /* synthesize Unicode charmap if one is missing */
-        if ( !has_unicode )
+        if ( !has_unicode                                &&
+             root->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
         {
-          FT_CharMapRec cmaprec;
+          FT_CharMapRec  cmaprec;
 
 
           cmaprec.face        = root;
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index ec66edc..d8ea9ea 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -1312,6 +1312,12 @@
     if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
       return error;
 
+    if ( post->FormatType != 0x00030000L &&
+         post->FormatType != 0x00025000L &&
+         post->FormatType != 0x00020000L &&
+         post->FormatType != 0x00010000L )
+      return FT_THROW( Invalid_Post_Table_Format );
+
     /* we don't load the glyph names, we do that in another */
     /* module (ttpost).                                     */