diff options
author | Nico Weber <thakis@chromium.org> | 2023-01-06 13:46:18 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-01-06 20:26:14 +0100 |
commit | c00ce2fba0870fb25074216a86dd7888d2e0db35 (patch) | |
tree | 621e6920b8027ee1b79838d1afefdeb2892c34e9 /Userland | |
parent | 31af741c667a51a1a6a39b3a20bf2d47311c2750 (diff) | |
download | serenity-c00ce2fba0870fb25074216a86dd7888d2e0db35.zip |
LibGfx+icc: Verify ICCProfile ID at parse time instead of in icc
Always computing computing the md5 takes some time, but most
icc profiles are small. So that's probably fine.
If this ends up being a perf problem in the future, or if it ends up
rejecting tons of embedded proiles from images, we can row it back.
But let's see if we can get away with this first.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGfx/ICCProfile.cpp | 10 | ||||
-rw-r--r-- | Userland/Utilities/icc.cpp | 11 |
2 files changed, 9 insertions, 12 deletions
diff --git a/Userland/Libraries/LibGfx/ICCProfile.cpp b/Userland/Libraries/LibGfx/ICCProfile.cpp index 294a57fb6b..3b1e527085 100644 --- a/Userland/Libraries/LibGfx/ICCProfile.cpp +++ b/Userland/Libraries/LibGfx/ICCProfile.cpp @@ -244,18 +244,20 @@ bool all_bytes_are_zero(const u8 (&bytes)[N]) return true; } -Optional<Crypto::Hash::MD5::DigestType> parse_profile_id(ICCHeader const& header) +ErrorOr<Optional<Crypto::Hash::MD5::DigestType>> parse_profile_id(ICCHeader const& header, ReadonlyBytes icc_bytes) { // ICC v4, 7.2.18 Profile ID field // "A profile ID field value of zero (00h) shall indicate that a profile ID has not been calculated." if (all_bytes_are_zero(header.profile_id)) - return {}; + return Optional<Crypto::Hash::MD5::DigestType> {}; Crypto::Hash::MD5::DigestType id; static_assert(sizeof(id.data) == sizeof(header.profile_id)); memcpy(id.data, header.profile_id, sizeof(id.data)); - // FIXME: Consider comparing read id with compute_id() result and failing if they aren't equal. + auto computed_id = Profile::compute_id(icc_bytes); + if (id != computed_id) + return Error::from_string_literal("ICC::Profile: Invalid profile id"); return id; } @@ -399,7 +401,7 @@ ErrorOr<NonnullRefPtr<Profile>> Profile::try_load_from_externally_owned_memory(R profile->m_flags = Flags { header.profile_flags }; profile->m_rendering_intent = TRY(parse_rendering_intent(header)); profile->m_pcs_illuminant = TRY(parse_pcs_illuminant(header)); - profile->m_id = parse_profile_id(header); + profile->m_id = TRY(parse_profile_id(header, bytes)); TRY(parse_reserved(header)); return profile; diff --git a/Userland/Utilities/icc.cpp b/Userland/Utilities/icc.cpp index 67d0ced9d9..6c67b7fec1 100644 --- a/Userland/Utilities/icc.cpp +++ b/Userland/Utilities/icc.cpp @@ -40,14 +40,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) outln("pcs illuminant: {}", profile->pcs_illuminant()); out("id: "); - if (auto id = profile->id(); id.has_value()) { - out("{}", *id); - auto computed = Gfx::ICC::Profile::compute_id(icc_file->bytes()); - if (*id == computed) - outln(" (valid)"); - else - outln(" (invalid! valid would be {})", computed); - } else + if (auto id = profile->id(); id.has_value()) + outln("{}", *id); + else outln("(not set)"); return 0; |