LibPDF: Don't over-read in charset formats 1 and 2

`left` might be a number bigger than there are actually glyphs in the
CFF.

The spec says "The number of ranges is not explicitly specified in the
font. Instead, software utilizing this data simply processes ranges
until all glyphs in the font are covered." Apparently we have to check
for this within each range as well.

Needed for example in 0000054.pdf and 0000354.pdf in 0000.zip in the
pdfa dataset.

Together with the previous commit:

From 21 (7%) to 20 (6%) crashes on the 300 first PDFs, and from
41 (8.2%) to 39 (7.8%) on the 500-random PDFs test.
This commit is contained in:
Nico Weber 2023-10-22 22:53:47 -04:00 committed by Tim Flynn
parent 58ff7b5336
commit 52afa936c4
Notes: sideshowbarker 2024-07-17 01:28:15 +09:00

View file

@ -753,7 +753,7 @@ PDFErrorOr<Vector<DeprecatedFlyString>> CFF::parse_charset(Reader&& reader, size
// CFF spec, "Table 19 Range1 Format (Charset)"
auto first_sid = TRY(reader.try_read<BigEndian<SID>>());
int left = TRY(reader.try_read<Card8>());
for (SID sid = first_sid; left >= 0; left--, sid++)
for (SID sid = first_sid; left >= 0 && names.size() < glyph_count - 1; left--, sid++)
TRY(names.try_append(resolve_sid(sid, strings)));
}
} else if (format == 2) {
@ -764,7 +764,7 @@ PDFErrorOr<Vector<DeprecatedFlyString>> CFF::parse_charset(Reader&& reader, size
// CFF spec, "Table 21 Range2 Format"
auto first_sid = TRY(reader.try_read<BigEndian<SID>>());
int left = TRY(reader.try_read<Card16>());
for (SID sid = first_sid; left >= 0; left--, sid++)
for (SID sid = first_sid; left >= 0 && names.size() < glyph_count - 1; left--, sid++)
TRY(names.try_append(resolve_sid(sid, strings)));
}
} else {