1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:47:45 +00:00

LibPDF: Don't crash on files with float CFF defaultWidthX

We'd unconditionally get the int from a Variant<int, float> here,
but PDFs often have a float for defaultWidthX and nominalWidthX.

Fixes crash opening Bakke2010a.pdf from pdffiles (but while the
file loads ok, it looks completely busted).
This commit is contained in:
Nico Weber 2023-10-12 11:25:16 -04:00 committed by Jelle Raaijmakers
parent e7c8ff3839
commit 349996f7f2
2 changed files with 15 additions and 6 deletions

View file

@ -41,8 +41,8 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
Vector<u8> encoding_codes; Vector<u8> encoding_codes;
auto charstrings_offset = 0; auto charstrings_offset = 0;
Vector<ByteBuffer> subroutines; Vector<ByteBuffer> subroutines;
int defaultWidthX = 0; float defaultWidthX = 0;
int nominalWidthX = 0; float nominalWidthX = 0;
TRY(parse_index(reader, [&](ReadonlyBytes const& element_data) { TRY(parse_index(reader, [&](ReadonlyBytes const& element_data) {
Reader element_reader { element_data }; Reader element_reader { element_data };
return parse_dict<TopDictOperator>(element_reader, [&](TopDictOperator op, Vector<DictOperand> const& operands) -> PDFErrorOr<void> { return parse_dict<TopDictOperator>(element_reader, [&](TopDictOperator op, Vector<DictOperand> const& operands) -> PDFErrorOr<void> {
@ -80,10 +80,12 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
break; break;
} }
case PrivDictOperator::DefaultWidthX: case PrivDictOperator::DefaultWidthX:
defaultWidthX = operands[0].get<int>(); if (!operands.is_empty())
defaultWidthX = to_number(operands[0]);
break; break;
case PrivDictOperator::NominalWidthX: case PrivDictOperator::NominalWidthX:
nominalWidthX = operands[0].get<int>(); if (!operands.is_empty())
nominalWidthX = to_number(operands[0]);
break; break;
} }
return {}; return {};
@ -103,9 +105,9 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
// Adjust glyphs' widths as they are deltas from nominalWidthX // Adjust glyphs' widths as they are deltas from nominalWidthX
for (auto& glyph : glyphs) { for (auto& glyph : glyphs) {
if (!glyph.has_width()) if (!glyph.has_width())
glyph.set_width(float(defaultWidthX)); glyph.set_width(defaultWidthX);
else else
glyph.set_width(glyph.width() + float(nominalWidthX)); glyph.set_width(glyph.width() + nominalWidthX);
} }
for (size_t i = 0; i < glyphs.size(); i++) { for (size_t i = 0; i < glyphs.size(); i++) {

View file

@ -56,6 +56,13 @@ public:
using SID = u16; using SID = u16;
using DictOperand = Variant<int, float>; using DictOperand = Variant<int, float>;
static float to_number(DictOperand operand)
{
if (operand.has<int>())
return operand.get<int>();
return operand.get<float>();
}
static int load_int_dict_operand(u8 b0, Reader&); static int load_int_dict_operand(u8 b0, Reader&);
static float load_float_dict_operand(Reader&); static float load_float_dict_operand(Reader&);
static PDFErrorOr<DictOperand> load_dict_operand(u8, Reader&); static PDFErrorOr<DictOperand> load_dict_operand(u8, Reader&);