Commit 82fd32d67426f4d58663d3d382478473c95ac27c

Ben Wagner 2021-05-03T13:49:14

* src/cid/cidload.c (cid_hex_to_binary): Improve return value. Add argument to return the actual number of bytes that were decoded. The actual number of bytes decoded can be quite variable depending on the number of ignored 'whitespace' bytes or early termination with `>`. (cid_face_open): Updated to use this calculated value. This avoids trusting `parser->binary_length` is always be correct and reading uninitialized bits if fewer are actually decoded. First reported as https://crbug.com/1203240

diff --git a/ChangeLog b/ChangeLog
index 998155a..09521f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2021-05-04  Ben Wagner  <bungeman@chromium.org>
+
+	* src/cid/cidload.c (cid_hex_to_binary): Improve return value.
+
+	Add argument to return the actual number of bytes that were decoded.
+	The actual number of bytes decoded can be quite variable depending
+	on the number of ignored 'whitespace' bytes or early termination
+	with `>`.
+	(cid_face_open): Updated to use this calculated value.  This avoids
+	trusting `parser->binary_length` is always be correct and reading
+	uninitialized bits if fewer are actually decoded.
+
+	First reported as
+
+	  https://crbug.com/1203240
+
 2021-05-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	[sfnt] Streamline POST format 2.0 handing.
@@ -43,7 +59,7 @@
 	[truetype] Avoid some memory zeroing.
 
 	* src/truetype/ttinterp.c (Init_Context): Tweak allocation macro.
-	* src/truetype/ttpload.c (tt_face_load_cvt): Ditto. 
+	* src/truetype/ttpload.c (tt_face_load_cvt): Ditto.
 
 2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index a2e15fc..e5a4964 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -668,14 +668,15 @@
   cid_hex_to_binary( FT_Byte*  data,
                      FT_ULong  data_len,
                      FT_ULong  offset,
-                     CID_Face  face )
+                     CID_Face  face,
+                     FT_ULong* data_written )
   {
     FT_Stream  stream = face->root.stream;
     FT_Error   error;
 
     FT_Byte    buffer[256];
     FT_Byte   *p, *plimit;
-    FT_Byte   *d, *dlimit;
+    FT_Byte   *d = data, *dlimit;
     FT_Byte    val;
 
     FT_Bool    upper_nibble, done;
@@ -684,7 +685,6 @@
     if ( FT_STREAM_SEEK( offset ) )
       goto Exit;
 
-    d      = data;
     dlimit = d + data_len;
     p      = buffer;
     plimit = p;
@@ -758,6 +758,7 @@
     error = FT_Err_Ok;
 
   Exit:
+    *data_written = d - data;
     return error;
   }
 
@@ -816,11 +817,12 @@
            FT_SET_ERROR( cid_hex_to_binary( face->binary_data,
                                             parser->binary_length,
                                             parser->data_offset,
-                                            face ) )               )
+                                            face,
+                                            &binary_length ) )     )
         goto Exit;
 
       FT_Stream_OpenMemory( face->cid_stream,
-                            face->binary_data, parser->binary_length );
+                            face->binary_data, binary_length );
       cid->data_offset = 0;
     }
     else