ICC: Strip trailing nul characters from MultiLocalizedUnicodeTagData

Having those trailing nuls is invalid per spec, but it happens in
practice (in already checked-in test files, no less).
This commit is contained in:
Nico Weber 2023-06-26 13:44:13 -04:00 committed by Sam Atkins
parent dedbc17160
commit 3dd6638177
Notes: sideshowbarker 2024-07-17 03:03:37 +09:00
2 changed files with 19 additions and 0 deletions

View file

@ -8,6 +8,7 @@
#include <LibCore/MappedFile.h>
#include <LibGfx/ICC/BinaryWriter.h>
#include <LibGfx/ICC/Profile.h>
#include <LibGfx/ICC/Tags.h>
#include <LibGfx/ICC/WellKnownProfiles.h>
#include <LibGfx/ImageFormats/JPEGLoader.h>
#include <LibGfx/ImageFormats/PNGLoader.h>
@ -42,6 +43,17 @@ TEST_CASE(jpg)
auto icc_profile = MUST(Gfx::ICC::Profile::try_load_from_externally_owned_memory(icc_bytes.value()));
EXPECT(icc_profile->is_v4());
icc_profile->for_each_tag([](auto tag_signature, auto tag_data) {
if (tag_signature == Gfx::ICC::profileDescriptionTag) {
// Required per v4 spec, but in practice even v4 files sometimes have TextDescriptionTagData descriptions. Not icc-v4.jpg, though.
EXPECT_EQ(tag_data->type(), Gfx::ICC::MultiLocalizedUnicodeTagData::Type);
auto& multi_localized_unicode = static_cast<Gfx::ICC::MultiLocalizedUnicodeTagData&>(*tag_data);
EXPECT_EQ(multi_localized_unicode.records().size(), 1u);
auto& record = multi_localized_unicode.records()[0];
EXPECT_EQ(record.text, "sRGB built-in"sv);
}
});
}
TEST_CASE(webp_extended_lossless)

View file

@ -719,6 +719,13 @@ ErrorOr<NonnullRefPtr<MultiLocalizedUnicodeTagData>> MultiLocalizedUnicodeTagDat
return Error::from_string_literal("ICC::Profile: multiLocalizedUnicodeType string offset out of bounds");
StringView utf_16be_data { bytes.data() + record.string_offset_in_bytes, record.string_length_in_bytes };
// Despite the "should not be NULL terminated" in the spec, some files in the wild have trailing NULLs.
// Fix up this case here, so that application code doesn't have to worry about it.
// (If this wasn't hit in practice, we'd return an Error instead.)
while (utf_16be_data.length() >= 2 && utf_16be_data.ends_with(StringView("\0", 2)))
utf_16be_data = utf_16be_data.substring_view(0, utf_16be_data.length() - 2);
records[i].text = TRY(utf_16be_decoder.to_utf8(utf_16be_data));
}