summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2023-01-06 13:46:18 -0500
committerLinus Groh <mail@linusgroh.de>2023-01-06 20:26:14 +0100
commitc00ce2fba0870fb25074216a86dd7888d2e0db35 (patch)
tree621e6920b8027ee1b79838d1afefdeb2892c34e9 /Userland
parent31af741c667a51a1a6a39b3a20bf2d47311c2750 (diff)
downloadserenity-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.cpp10
-rw-r--r--Userland/Utilities/icc.cpp11
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;