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
This commit is contained in:
Ben Wagner 2023-03-01 12:19:17 -05:00 committed by Werner Lemberg
parent e95e623471
commit 09b326fa2b
1 changed files with 12 additions and 6 deletions

View File

@ -214,18 +214,24 @@
cur <= limit - STARTDATA_LEN &&
ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
{
if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
T1_TokenRec type_token;
FT_Long binary_length;
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 )
{
FT_Long tmp = ft_strtol( (const char *)arg2, NULL, 10 );
if ( tmp < 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;