mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:07:34 +00:00
LibPDF: Make Filter::decode() return ErrorOr
This commit is contained in:
parent
c388a879d7
commit
fa3c61cf5a
3 changed files with 33 additions and 41 deletions
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
namespace PDF {
|
namespace PDF {
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode(ReadonlyBytes bytes, FlyString const& encoding_type)
|
ErrorOr<ByteBuffer> Filter::decode(ReadonlyBytes bytes, FlyString const& encoding_type)
|
||||||
{
|
{
|
||||||
if (encoding_type == CommonNames::ASCIIHexDecode)
|
if (encoding_type == CommonNames::ASCIIHexDecode)
|
||||||
return decode_ascii_hex(bytes);
|
return decode_ascii_hex(bytes);
|
||||||
|
@ -34,34 +34,26 @@ Optional<ByteBuffer> Filter::decode(ReadonlyBytes bytes, FlyString const& encodi
|
||||||
if (encoding_type == CommonNames::Crypt)
|
if (encoding_type == CommonNames::Crypt)
|
||||||
return decode_crypt(bytes);
|
return decode_crypt(bytes);
|
||||||
|
|
||||||
return {};
|
return Error::from_string_literal("Unrecognized filter encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes bytes)
|
ErrorOr<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
if (bytes.size() % 2 == 0) {
|
if (bytes.size() % 2 == 0)
|
||||||
auto decode_result = decode_hex(bytes);
|
return decode_hex(bytes);
|
||||||
if (decode_result.is_error())
|
|
||||||
return {};
|
|
||||||
return decode_result.release_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Integrate this padding into AK/Hex?
|
// FIXME: Integrate this padding into AK/Hex?
|
||||||
|
|
||||||
auto output_result = ByteBuffer::create_zeroed(bytes.size() / 2 + 1);
|
auto output = TRY(ByteBuffer::create_zeroed(bytes.size() / 2 + 1));
|
||||||
if (output_result.is_error())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
auto output = output_result.release_value();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < bytes.size() / 2; ++i) {
|
for (size_t i = 0; i < bytes.size() / 2; ++i) {
|
||||||
const auto c1 = decode_hex_digit(static_cast<char>(bytes[i * 2]));
|
const auto c1 = decode_hex_digit(static_cast<char>(bytes[i * 2]));
|
||||||
if (c1 >= 16)
|
if (c1 >= 16)
|
||||||
return {};
|
return Error::from_string_literal("Hex string contains invalid digit");
|
||||||
|
|
||||||
const auto c2 = decode_hex_digit(static_cast<char>(bytes[i * 2 + 1]));
|
const auto c2 = decode_hex_digit(static_cast<char>(bytes[i * 2 + 1]));
|
||||||
if (c2 >= 16)
|
if (c2 >= 16)
|
||||||
return {};
|
return Error::from_string_literal("Hex string contains invalid digit");
|
||||||
|
|
||||||
output[i] = (c1 << 4) + c2;
|
output[i] = (c1 << 4) + c2;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +64,7 @@ Optional<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes bytes)
|
||||||
return { move(output) };
|
return { move(output) };
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_ascii85(ReadonlyBytes bytes)
|
ErrorOr<ByteBuffer> Filter::decode_ascii85(ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
Vector<u8> buff;
|
Vector<u8> buff;
|
||||||
buff.ensure_capacity(bytes.size());
|
buff.ensure_capacity(bytes.size());
|
||||||
|
@ -124,19 +116,16 @@ Optional<ByteBuffer> Filter::decode_ascii85(ReadonlyBytes bytes)
|
||||||
buff.append(reinterpret_cast<u8*>(&number)[3 - i]);
|
buff.append(reinterpret_cast<u8*>(&number)[3 - i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = ByteBuffer::copy(buff.span());
|
return ByteBuffer::copy(buff.span());
|
||||||
if (result.is_error())
|
|
||||||
return {};
|
|
||||||
return result.release_value();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_lzw(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_lzw(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
dbgln("LZW decoding is not supported");
|
dbgln("LZW decoding is not supported");
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_flate(ReadonlyBytes bytes)
|
ErrorOr<ByteBuffer> Filter::decode_flate(ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
// FIXME: The spec says Flate decoding is "based on" zlib, does that mean they
|
// FIXME: The spec says Flate decoding is "based on" zlib, does that mean they
|
||||||
// aren't exactly the same?
|
// aren't exactly the same?
|
||||||
|
@ -146,37 +135,37 @@ Optional<ByteBuffer> Filter::decode_flate(ReadonlyBytes bytes)
|
||||||
return buff.value();
|
return buff.value();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_run_length(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_run_length(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
// FIXME: Support RunLength decoding
|
// FIXME: Support RunLength decoding
|
||||||
TODO();
|
TODO();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_ccitt(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_ccitt(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
// FIXME: Support CCITT decoding
|
// FIXME: Support CCITT decoding
|
||||||
TODO();
|
TODO();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_jbig2(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_jbig2(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
// FIXME: Support JBIG2 decoding
|
// FIXME: Support JBIG2 decoding
|
||||||
TODO();
|
TODO();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_dct(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_dct(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
// FIXME: Support dct decoding
|
// FIXME: Support dct decoding
|
||||||
TODO();
|
TODO();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_jpx(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_jpx(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
// FIXME: Support JPX decoding
|
// FIXME: Support JPX decoding
|
||||||
TODO();
|
TODO();
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<ByteBuffer> Filter::decode_crypt(ReadonlyBytes)
|
ErrorOr<ByteBuffer> Filter::decode_crypt(ReadonlyBytes)
|
||||||
{
|
{
|
||||||
// FIXME: Support Crypt decoding
|
// FIXME: Support Crypt decoding
|
||||||
TODO();
|
TODO();
|
||||||
|
|
|
@ -7,25 +7,26 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
|
#include <AK/Error.h>
|
||||||
#include <AK/FlyString.h>
|
#include <AK/FlyString.h>
|
||||||
|
|
||||||
namespace PDF {
|
namespace PDF {
|
||||||
|
|
||||||
class Filter {
|
class Filter {
|
||||||
public:
|
public:
|
||||||
static Optional<ByteBuffer> decode(ReadonlyBytes bytes, FlyString const& encoding_type);
|
static ErrorOr<ByteBuffer> decode(ReadonlyBytes bytes, FlyString const& encoding_type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Optional<ByteBuffer> decode_ascii_hex(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_ascii_hex(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_ascii85(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_ascii85(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_lzw(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_lzw(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_flate(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_flate(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_run_length(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_run_length(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_ccitt(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_ccitt(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_jbig2(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_jbig2(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_dct(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_dct(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_jpx(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_jpx(ReadonlyBytes bytes);
|
||||||
static Optional<ByteBuffer> decode_crypt(ReadonlyBytes bytes);
|
static ErrorOr<ByteBuffer> decode_crypt(ReadonlyBytes bytes);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1071,8 +1071,10 @@ RefPtr<StreamObject> Parser::parse_stream(NonnullRefPtr<DictObject> dict)
|
||||||
if (dict->contains(CommonNames::Filter)) {
|
if (dict->contains(CommonNames::Filter)) {
|
||||||
auto filter_type = dict->get_name(m_document, CommonNames::Filter)->name();
|
auto filter_type = dict->get_name(m_document, CommonNames::Filter)->name();
|
||||||
auto maybe_bytes = Filter::decode(bytes, filter_type);
|
auto maybe_bytes = Filter::decode(bytes, filter_type);
|
||||||
if (!maybe_bytes.has_value())
|
if (maybe_bytes.is_error()) {
|
||||||
|
warnln("Failed to decode filter: {}", maybe_bytes.error().string_literal());
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
return make_object<EncodedStreamObject>(dict, move(maybe_bytes.value()));
|
return make_object<EncodedStreamObject>(dict, move(maybe_bytes.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue