From 03f32bdf8661560b5f108a0785f24e98322354c7 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 3 Mar 2023 12:03:22 -0500 Subject: [PATCH] LibUnicode: Validate that all emoji images in /res/emoji actually exist This will raise a compile error if an emoji image was neglected to be added to e.g. emoji-serenity.txt, or if the code points are not correct. --- .../LibUnicode/GenerateEmojiData.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp index 428aba0149..fa9ade687d 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -167,6 +168,45 @@ static ErrorOr parse_emoji_serenity_data(Core::BufferedFile& file, EmojiDa return {}; } +static ErrorOr validate_emoji(StringView emoji_resource_path, EmojiData& emoji_data) +{ + Core::DirIterator iterator(emoji_resource_path, Core::DirIterator::SkipDots); + + while (iterator.has_next()) { + auto filename = iterator.next_path(); + + auto lexical_path = LexicalPath(filename); + if (lexical_path.extension() != "png") + continue; + + auto basename = lexical_path.basename(); + if (!basename.starts_with("U+"sv)) + continue; + + basename = basename.substring_view(0, basename.length() - lexical_path.extension().length() - 1); + + Vector code_points; + TRY(basename.for_each_split_view('_', SplitBehavior::Nothing, [&](auto segment) -> ErrorOr { + auto code_point = AK::StringUtils::convert_to_uint_from_hex(segment.substring_view(2)); + VERIFY(code_point.has_value()); + + TRY(code_points.try_append(*code_point)); + return {}; + })); + + auto it = emoji_data.emojis.find_if([&](auto const& emoji) { + return emoji.code_points == code_points; + }); + + if (it == emoji_data.emojis.end()) { + warnln("\x1b[1;31mError!\x1b[0m Emoji data for \x1b[35m{}\x1b[0m not found. Please check emoji-test.txt and emoji-serenity.txt.", filename); + return Error::from_errno(ENOENT); + } + } + + return {}; +} + static ErrorOr generate_emoji_data_header(Core::BufferedFile& file, EmojiData const&) { StringBuilder builder; @@ -356,6 +396,8 @@ ErrorOr serenity_main(Main::Arguments arguments) if (!emoji_serenity_path.is_empty()) { auto emoji_serenity_file = TRY(open_file(emoji_serenity_path, Core::File::OpenMode::Read)); TRY(parse_emoji_serenity_data(*emoji_serenity_file, emoji_data)); + + TRY(validate_emoji(emoji_resource_path, emoji_data)); } size_t code_point_array_index { 0 };