mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 20:58:11 +00:00
LibPDF: Don't use unsanitized values in error messages
Previously, constructing error messages with unsanitized input could fail because error message strings must be UTF-8.
This commit is contained in:
parent
f8bf9c6506
commit
b4296e1c9b
9 changed files with 41 additions and 15 deletions
|
@ -11,6 +11,7 @@ set(TEST_FILES
|
||||||
encryption_nocopy.pdf
|
encryption_nocopy.pdf
|
||||||
linearized.pdf
|
linearized.pdf
|
||||||
non-linearized.pdf
|
non-linearized.pdf
|
||||||
|
oss-fuzz-testcase-62065.pdf
|
||||||
password-is-sup.pdf
|
password-is-sup.pdf
|
||||||
type1.pdf
|
type1.pdf
|
||||||
)
|
)
|
||||||
|
|
|
@ -73,3 +73,16 @@ TEST_CASE(encrypted_object_stream)
|
||||||
EXPECT_EQ(MUST(info_dict.author()).value(), "van der Knijff");
|
EXPECT_EQ(MUST(info_dict.author()).value(), "van der Knijff");
|
||||||
EXPECT_EQ(MUST(info_dict.creator()).value(), "Acrobat PDFMaker 9.1 voor Word");
|
EXPECT_EQ(MUST(info_dict.creator()).value(), "Acrobat PDFMaker 9.1 voor Word");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(malformed_pdf_document)
|
||||||
|
{
|
||||||
|
Array test_inputs = {
|
||||||
|
"oss-fuzz-testcase-62065.pdf"sv
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto test_input : test_inputs) {
|
||||||
|
auto file = MUST(Core::MappedFile::map(test_input));
|
||||||
|
auto document_or_error = PDF::Document::create(file->bytes());
|
||||||
|
EXPECT(document_or_error.is_error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1
Tests/LibPDF/oss-fuzz-testcase-62065.pdf
Normal file
1
Tests/LibPDF/oss-fuzz-testcase-62065.pdf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
%PDF-<2D><><EFBFBD>
|
|
@ -27,7 +27,8 @@ PDFErrorOr<ColorSpaceFamily> ColorSpaceFamily::get(DeprecatedFlyString const& fa
|
||||||
}
|
}
|
||||||
ENUMERATE_COLOR_SPACE_FAMILIES(ENUMERATE)
|
ENUMERATE_COLOR_SPACE_FAMILIES(ENUMERATE)
|
||||||
#undef ENUMERATE
|
#undef ENUMERATE
|
||||||
return Error(Error::Type::MalformedPDF, DeprecatedString::formatted("Unknown ColorSpace family {}", family_name));
|
dbgln_if(PDF_DEBUG, "Unknown ColorSpace family: {}", family_name);
|
||||||
|
return Error(Error::Type::MalformedPDF, "Unknown ColorSpace family"_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<NonnullRefPtr<ColorSpace>> ColorSpace::create(DeprecatedFlyString const& name)
|
PDFErrorOr<NonnullRefPtr<ColorSpace>> ColorSpace::create(DeprecatedFlyString const& name)
|
||||||
|
|
|
@ -81,15 +81,19 @@ PDFErrorOr<Version> DocumentParser::parse_header()
|
||||||
m_reader.move_by(5);
|
m_reader.move_by(5);
|
||||||
|
|
||||||
char major_ver = m_reader.read();
|
char major_ver = m_reader.read();
|
||||||
if (major_ver != '1' && major_ver != '2')
|
if (major_ver != '1' && major_ver != '2') {
|
||||||
return error(DeprecatedString::formatted("Unknown major version \"{}\"", major_ver));
|
dbgln_if(PDF_DEBUG, "Unknown major version \"{}\"", major_ver);
|
||||||
|
return error("Unknown major version");
|
||||||
|
}
|
||||||
|
|
||||||
if (m_reader.read() != '.')
|
if (m_reader.read() != '.')
|
||||||
return error("Malformed PDF version");
|
return error("Malformed PDF version");
|
||||||
|
|
||||||
char minor_ver = m_reader.read();
|
char minor_ver = m_reader.read();
|
||||||
if (minor_ver < '0' || minor_ver > '7')
|
if (minor_ver < '0' || minor_ver > '7') {
|
||||||
return error(DeprecatedString::formatted("Unknown minor version \"{}\"", minor_ver));
|
dbgln_if(PDF_DEBUG, "Unknown minor version \"{}\"", minor_ver);
|
||||||
|
return error("Unknown minor version");
|
||||||
|
}
|
||||||
|
|
||||||
m_reader.consume_eol();
|
m_reader.consume_eol();
|
||||||
m_reader.consume_whitespace();
|
m_reader.consume_whitespace();
|
||||||
|
|
|
@ -51,7 +51,8 @@ PDFErrorOr<ByteBuffer> Filter::decode(ReadonlyBytes bytes, DeprecatedFlyString c
|
||||||
if (encoding_type == CommonNames::Crypt)
|
if (encoding_type == CommonNames::Crypt)
|
||||||
return decode_crypt(bytes);
|
return decode_crypt(bytes);
|
||||||
|
|
||||||
return Error::malformed_error("Unrecognized filter encoding {}", encoding_type);
|
dbgln_if(PDF_DEBUG, "Unrecognized filter encoding {}", encoding_type);
|
||||||
|
return Error::malformed_error("Unrecognized filter encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes bytes)
|
PDFErrorOr<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes bytes)
|
||||||
|
|
|
@ -37,14 +37,16 @@ PDFErrorOr<NonnullRefPtr<PDFFont>> PDFFont::create(Document* document, NonnullRe
|
||||||
auto subtype = TRY(dict->get_name(document, CommonNames::Subtype))->name();
|
auto subtype = TRY(dict->get_name(document, CommonNames::Subtype))->name();
|
||||||
|
|
||||||
RefPtr<PDFFont> font;
|
RefPtr<PDFFont> font;
|
||||||
if (subtype == "Type1")
|
if (subtype == "Type1") {
|
||||||
font = adopt_ref(*new Type1Font());
|
font = adopt_ref(*new Type1Font());
|
||||||
else if (subtype == "TrueType")
|
} else if (subtype == "TrueType") {
|
||||||
font = adopt_ref(*new TrueTypeFont());
|
font = adopt_ref(*new TrueTypeFont());
|
||||||
else if (subtype == "Type0")
|
} else if (subtype == "Type0")
|
||||||
font = adopt_ref(*new Type0Font());
|
font = adopt_ref(*new Type0Font());
|
||||||
else
|
else {
|
||||||
return Error::internal_error("Unhandled font subtype: {}", subtype);
|
dbgln_if(PDF_DEBUG, "Unhandled font subtype: {}", subtype);
|
||||||
|
return Error::internal_error("Unhandled font subtype");
|
||||||
|
}
|
||||||
|
|
||||||
TRY(font->initialize(document, dict, font_size));
|
TRY(font->initialize(document, dict, font_size));
|
||||||
return font.release_nonnull();
|
return font.release_nonnull();
|
||||||
|
|
|
@ -284,7 +284,7 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
|
||||||
i += 2;
|
i += 2;
|
||||||
TRY(push(a));
|
TRY(push(a));
|
||||||
} else {
|
} else {
|
||||||
return error(DeprecatedString::formatted("CFF Subr command 28 only valid in type2 data"));
|
return error("CFF Subr command 28 only valid in type2 data");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not a parameter but a command byte.
|
// Not a parameter but a command byte.
|
||||||
|
@ -494,7 +494,8 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return error(DeprecatedString::formatted("Unhandled command: 12 {}", data[i]));
|
dbgln_if(PDF_DEBUG, "Unhandled command: 12 {}", data[i]);
|
||||||
|
return error("Unhandled command");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -578,7 +579,8 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return error(DeprecatedString::formatted("Unhandled command: {}", v));
|
dbgln_if(PDF_DEBUG, "Unhandled command: {}", v);
|
||||||
|
return error("Unhandled command");
|
||||||
}
|
}
|
||||||
|
|
||||||
is_first_command = false;
|
is_first_command = false;
|
||||||
|
|
|
@ -101,7 +101,8 @@ PDFErrorOr<Value> Parser::parse_value(CanBeIndirectValue can_be_indirect_value)
|
||||||
if (m_reader.matches('['))
|
if (m_reader.matches('['))
|
||||||
return TRY(parse_array());
|
return TRY(parse_array());
|
||||||
|
|
||||||
return error(DeprecatedString::formatted("Unexpected char \"{}\"", m_reader.peek()));
|
dbgln_if(PDF_DEBUG, "Unexpected char \"{}\"", m_reader.peek());
|
||||||
|
return error("Unexpected character");
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<Value> Parser::parse_possible_indirect_value_or_ref()
|
PDFErrorOr<Value> Parser::parse_possible_indirect_value_or_ref()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue