mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:57: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:
parent
e7c8ff3839
commit
349996f7f2
2 changed files with 15 additions and 6 deletions
|
@ -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++) {
|
||||||
|
|
|
@ -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&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue