From deb32bded40c4c46ce57c729c303edcb1915458b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 8 Nov 2022 22:05:03 +0100 Subject: html parser: fix possible endless loop. Fixes matrix chat where parsing non-html as html happened --- src/plugins/Matrix.cpp | 71 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 22 deletions(-) (limited to 'src/plugins/Matrix.cpp') diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index d1a060d..31aab76 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -117,6 +117,34 @@ namespace QuickMedia { return colors[color_hash_code(user_id) % num_colors]; } + static std::string remove_reply_formatting(const std::string &str) { + if(strncmp(str.c_str(), "> <@", 4) == 0) { + size_t index = str.find("> ", 4); + if(index != std::string::npos) { + size_t msg_begin = str.find("\n\n", index + 2); + if(msg_begin != std::string::npos) + return str.substr(msg_begin + 2); + } + } else { + return formatted_text_to_qm_text(str.c_str(), str.size(), false); + } + return str; + } + + static std::string remove_reply_formatting(const Message *message) { + if(!message->body_is_formatted && strncmp(message->body.c_str(), "> <@", 4) == 0) { + size_t index = message->body.find("> ", 4); + if(index != std::string::npos) { + size_t msg_begin = message->body.find("\n\n", index + 2); + if(msg_begin != std::string::npos) + return message->body.substr(msg_begin + 2); + } + return message->body; + } else { + return formatted_text_to_qm_text(message->body.c_str(), message->body.size(), false); + } + } + bool TimestampedDisplayData::set_data_if_newer(std::string new_data, time_t new_timestamp) { if(new_timestamp == 0) { data = std::move(new_data); @@ -433,7 +461,7 @@ namespace QuickMedia { if(!sync_is_cache && message_dir == MessageDirection::AFTER) { for(auto &message : messages) { if(message->notification_mentions_me) { - std::string body = remove_reply_formatting(message->body); + std::string body = remove_reply_formatting(message.get()); bool read = true; // TODO: What if the message or username begins with "-"? also make the notification image be the avatar of the user if((!is_window_focused || room != current_room) && message->related_event_type != RelatedEventType::EDIT && message->related_event_type != RelatedEventType::REDACTION) { @@ -598,8 +626,15 @@ namespace QuickMedia { return nullptr; } + static std::string message_to_qm_text(const Message *message, bool allow_formatted_text = true) { + if(message->body_is_formatted) + return formatted_text_to_qm_text(message->body.c_str(), message->body.size(), allow_formatted_text); + else + return message->body; + } + static std::string message_to_room_description_text(Message *message) { - std::string body = strip(formatted_text_to_qm_text(message->body.c_str(), message->body.size(), true)); + std::string body = strip(message_to_qm_text(message)); if(message->type == MessageType::REACTION) return "Reacted with: " + body; else if(message->related_event_type == RelatedEventType::REPLY) @@ -2130,7 +2165,7 @@ namespace QuickMedia { } bool message_contains_user_mention(const Message *message, const std::string &username, const std::string &user_id) { - const std::string formatted_text = formatted_text_to_qm_text(message->body.c_str(), message->body.size(), false); + const std::string formatted_text = message_to_qm_text(message, false); return message_contains_user_mention(formatted_text, username) || message_contains_user_mention(formatted_text, user_id); } @@ -2197,7 +2232,7 @@ namespace QuickMedia { // TODO: Is @room ok? shouldn't we also check if the user has permission to do @room? (only when notifications are limited to @mentions) // TODO: Is comparing against read marker timestamp ok enough? if(me && message->timestamp > read_marker_message_timestamp) { - std::string message_str = formatted_text_to_qm_text(message->body.c_str(), message->body.size(), false); + std::string message_str = message_to_qm_text(message.get(), false); message->notification_mentions_me = message_contains_user_mention(message_str, my_display_name) || message_contains_user_mention(message_str, me->user_id) || message_contains_user_mention(message_str, "@room"); } } @@ -2370,8 +2405,10 @@ namespace QuickMedia { code_parse_userdata.allow_formatted_text = true; code_parse_userdata.inside_source_highlight = true; html_parser_parse(output.c_str(), output.size(), formattext_text_parser_callback, &code_parse_userdata); - text_to_add = std::move(code_parse_userdata.result); - formatted_text_flags = FORMATTED_TEXT_FLAG_NONE; + if(!code_parse_userdata.result.empty()) { + text_to_add = std::move(code_parse_userdata.result); + formatted_text_flags = FORMATTED_TEXT_FLAG_NONE; + } } } } @@ -2775,9 +2812,12 @@ namespace QuickMedia { if(!body_json.IsString()) return nullptr; + bool body_is_formatted = true; const rapidjson::Value *formatted_body_json = &GetMember(*content_json, "formatted_body"); - if(!formatted_body_json->IsString()) + if(!formatted_body_json->IsString()) { formatted_body_json = &body_json; + body_is_formatted = false; + } auto message = std::make_shared(); std::string prefix; @@ -2846,6 +2886,7 @@ namespace QuickMedia { message->user = user; message->event_id = event_id_str; message->body = prefix + std::string(formatted_body_json->GetString(), formatted_body_json->GetStringLength()); + message->body_is_formatted = body_is_formatted; message->related_event_id = std::move(related_event_id); message->related_event_type = related_event_type; message->timestamp = timestamp; @@ -3567,20 +3608,6 @@ namespace QuickMedia { return PluginResult::OK; } - std::string remove_reply_formatting(const std::string &str) { - if(strncmp(str.c_str(), "> <@", 4) == 0) { - size_t index = str.find("> ", 4); - if(index != std::string::npos) { - size_t msg_begin = str.find("\n\n", index + 2); - if(msg_begin != std::string::npos) - return str.substr(msg_begin + 2); - } - } else { - return formatted_text_to_qm_text(str.c_str(), str.size(), false); - } - return str; - } - static std::string block_quote(const std::string &str) { std::string result; for(char c : str) { @@ -3600,7 +3627,7 @@ namespace QuickMedia { switch(message->type) { case MessageType::TEXT: { if(message->related_event_type != RelatedEventType::NONE) - related_to_body = remove_reply_formatting(message->body); + related_to_body = remove_reply_formatting(message); else related_to_body = message->body; break; -- cgit v1.2.3