freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 09b326fa2: Avoid strtol on non-null-terminated data.


From: Werner Lemberg
Subject: [freetype2] master 09b326fa2: Avoid strtol on non-null-terminated data.
Date: Thu, 2 Mar 2023 14:57:20 -0500 (EST)

branch: master
commit 09b326fa2b3198e462fc75f98973981f23ec7382
Author: Ben Wagner <bungeman@chromium.org>
Commit: Werner Lemberg <wl@gnu.org>

    Avoid strtol on non-null-terminated data.
    
    Technically, `strtol` can only be used with C strings terminated with
    `\0`.  CID data is not generally null-terminated and often does not
    contain a `\0` if it is hex-encoded.  AddressSanitizer with `ASAN_OPTIONS`
    containing `strict_string_checks=1` verifies this by using an adversarial
    `strtol` that always reads to the terminating `\0`.
    
    To avoid undefined behavior from `strtol` in `cid_parser_new`, use the
    parser to parse the tokens instead of attempting to parse them ad-hoc.
    This will internally use `PS_Conv_Strtol` to parse the integer, which
    respects the parser's limits and directly implements the PostScript
    parsing rules for integers.
    
    * src/cid/cidparse.c (cid_parser_new): Use the parser to parse the
    tokens.
    
    Fixes: https://bugs.chromium.org/p/chromium/issues/detail?id=1420329
---
 src/cid/cidparse.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/cid/cidparse.c b/src/cid/cidparse.c
index 16889db9b..171a88621 100644
--- a/src/cid/cidparse.c
+++ b/src/cid/cidparse.c
@@ -214,18 +214,24 @@
            cur <= limit - STARTDATA_LEN                            &&
            ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
       {
-        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
-        {
-          FT_Long  tmp = ft_strtol( (const char *)arg2, NULL, 10 );
+        T1_TokenRec  type_token;
+        FT_Long      binary_length;
 
 
-          if ( tmp < 0 )
+        parser->root.cursor = arg1;
+        cid_parser_to_token( parser, &type_token );
+        if ( type_token.limit - type_token.start == 5              &&
+             ft_memcmp( (char*)type_token.start, "(Hex)", 5 ) == 0 )
+        {
+          parser->root.cursor = arg2;
+          binary_length = cid_parser_to_int( parser );
+          if ( binary_length < 0 )
           {
             FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
             error = FT_THROW( Invalid_File_Format );
           }
           else
-            parser->binary_length = (FT_ULong)tmp;
+            parser->binary_length = (FT_ULong)binary_length;
         }
 
         goto Exit;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]