Make remove_unallowed_quote_entities private to MessageQuote.

This commit is contained in:
levlam 2024-04-25 16:30:33 +03:00
parent 02a99f3c50
commit 73ccba7f0f
5 changed files with 92 additions and 86 deletions

View File

@ -1416,24 +1416,6 @@ void remove_empty_entities(vector<MessageEntity> &entities) {
});
}
static bool is_allowed_quote_entity(const MessageEntity &entity) {
switch (entity.type) {
case MessageEntity::Type::Bold:
case MessageEntity::Type::Italic:
case MessageEntity::Type::Underline:
case MessageEntity::Type::Strikethrough:
case MessageEntity::Type::Spoiler:
case MessageEntity::Type::CustomEmoji:
return true;
default:
return false;
}
}
void remove_unallowed_quote_entities(FormattedText &text) {
td::remove_if(text.entities, [](const auto &entity) { return !is_allowed_quote_entity(entity); });
}
static int32 text_length(Slice text) {
return narrow_cast<int32>(utf8_utf16_length(text));
}
@ -4254,7 +4236,7 @@ static vector<MessageEntity> resplit_entities(vector<MessageEntity> &&splittable
return std::move(entities);
}
static void fix_entities(vector<MessageEntity> &entities) {
void fix_entities(vector<MessageEntity> &entities) {
sort_entities(entities);
if (are_entities_valid(entities)) {
@ -4744,63 +4726,4 @@ void remove_unallowed_entities(const Td *td, FormattedText &text, DialogId dialo
}
}
int32 search_quote(FormattedText &&text, FormattedText &&quote, int32 quote_position) {
auto process_quote_entities = [](FormattedText &text, int32 length) {
remove_unallowed_quote_entities(text);
td::remove_if(text.entities, [length](const MessageEntity &entity) {
if (entity.offset < 0 || entity.offset >= length) {
return true;
}
if (entity.length <= 0 || entity.length > length - entity.offset) {
return true;
}
return false;
});
remove_empty_entities(text.entities);
fix_entities(text.entities);
remove_empty_entities(text.entities);
};
int32 length = text_length(text.text);
int32 quote_length = text_length(quote.text);
if (quote_length == 0 || quote_length > length) {
return -1;
}
process_quote_entities(text, length);
process_quote_entities(quote, quote_length);
quote_position = clamp(quote_position, 0, length - 1);
vector<size_t> byte_positions;
byte_positions.reserve(length);
for (size_t i = 0; i < text.text.size(); i++) {
auto c = static_cast<unsigned char>(text.text[i]);
if (is_utf8_character_first_code_unit(c)) {
byte_positions.push_back(i);
if (c >= 0xf0) { // >= 4 bytes in symbol => surrogate pair
byte_positions.push_back(string::npos);
}
}
}
CHECK(byte_positions.size() == static_cast<size_t>(length));
auto check_position = [&text, &quote, &byte_positions, length, quote_length](int32 position) {
if (position < 0 || position > length - quote_length) {
return false;
}
auto byte_position = byte_positions[position];
if (byte_position == string::npos || text.text[byte_position] != quote.text[0] ||
Slice(text.text).substr(byte_position, quote.text.size()) != quote.text) {
return false;
}
return true;
};
for (int32 i = 0; quote_position - i >= 0 || quote_position + i + 1 <= length - quote_length; i++) {
if (check_position(quote_position - i)) {
return quote_position - i;
}
if (check_position(quote_position + i + 1)) {
return quote_position + i + 1;
}
}
return -1;
}
} // namespace td

View File

@ -183,10 +183,6 @@ vector<std::pair<Slice, int32>> find_media_timestamps(Slice str); // slice + me
void remove_empty_entities(vector<MessageEntity> &entities);
void remove_unallowed_quote_entities(FormattedText &text);
int32 search_quote(FormattedText &&text, FormattedText &&quote, int32 quote_position);
Slice get_first_url(const FormattedText &text);
bool is_visible_url(const FormattedText &text, const string &url);
@ -227,6 +223,8 @@ FormattedText get_formatted_text(const UserManager *user_manager,
telegram_api::object_ptr<telegram_api::textWithEntities> text_with_entities,
bool allow_empty, bool skip_media_timestamps, bool skip_trim, const char *source);
void fix_entities(vector<MessageEntity> &entities);
// like clean_input_string but also validates entities
Status fix_formatted_text(string &text, vector<MessageEntity> &entities, bool allow_empty, bool skip_new_entities,
bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim,

View File

@ -14,7 +14,11 @@
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserManager.h"
#include "td/utils/algorithm.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/Slice.h"
#include "td/utils/utf8.h"
namespace td {
@ -69,7 +73,6 @@ MessageQuote MessageQuote::clone(bool ignore_is_manual) const {
}
MessageQuote MessageQuote::create_automatic_quote(Td *td, FormattedText &&text) {
remove_unallowed_quote_entities(text);
truncate_formatted_text(
text, static_cast<size_t>(td->option_manager_->get_option_integer("message_reply_quote_length_max")));
return MessageQuote(std::move(text), 0, false);
@ -155,4 +158,81 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote &quo
return string_builder;
}
void MessageQuote::remove_unallowed_quote_entities(FormattedText &text) {
auto is_allowed_quote_entity = [](const MessageEntity &entity) {
switch (entity.type) {
case MessageEntity::Type::Bold:
case MessageEntity::Type::Italic:
case MessageEntity::Type::Underline:
case MessageEntity::Type::Strikethrough:
case MessageEntity::Type::Spoiler:
case MessageEntity::Type::CustomEmoji:
return true;
default:
return false;
}
};
td::remove_if(text.entities, [&](const auto &entity) { return !is_allowed_quote_entity(entity); });
}
int32 MessageQuote::search_quote(FormattedText &&text, FormattedText &&quote, int32 quote_position) {
auto process_quote_entities = [](FormattedText &text, int32 length) {
remove_unallowed_quote_entities(text);
td::remove_if(text.entities, [length](const MessageEntity &entity) {
if (entity.offset < 0 || entity.offset >= length) {
return true;
}
if (entity.length <= 0 || entity.length > length - entity.offset) {
return true;
}
return false;
});
remove_empty_entities(text.entities);
fix_entities(text.entities);
remove_empty_entities(text.entities);
};
int32 length = narrow_cast<int32>(utf8_utf16_length(text.text));
int32 quote_length = narrow_cast<int32>(utf8_utf16_length(quote.text));
if (quote_length == 0 || quote_length > length) {
return -1;
}
process_quote_entities(text, length);
process_quote_entities(quote, quote_length);
quote_position = clamp(quote_position, 0, length - 1);
vector<size_t> byte_positions;
byte_positions.reserve(length);
for (size_t i = 0; i < text.text.size(); i++) {
auto c = static_cast<unsigned char>(text.text[i]);
if (is_utf8_character_first_code_unit(c)) {
byte_positions.push_back(i);
if (c >= 0xf0) { // >= 4 bytes in symbol => surrogate pair
byte_positions.push_back(string::npos);
}
}
}
CHECK(byte_positions.size() == static_cast<size_t>(length));
auto check_position = [&text, &quote, &byte_positions, length, quote_length](int32 position) {
if (position < 0 || position > length - quote_length) {
return false;
}
auto byte_position = byte_positions[position];
if (byte_position == string::npos || text.text[byte_position] != quote.text[0] ||
Slice(text.text).substr(byte_position, quote.text.size()) != quote.text) {
return false;
}
return true;
};
for (int32 i = 0; quote_position - i >= 0 || quote_position + i + 1 <= length - quote_length; i++) {
if (check_position(quote_position - i)) {
return quote_position - i;
}
if (check_position(quote_position + i + 1)) {
return quote_position + i + 1;
}
}
return -1;
}
} // namespace td

View File

@ -28,6 +28,8 @@ class MessageQuote {
friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote &quote);
static void remove_unallowed_quote_entities(FormattedText &text);
public:
MessageQuote() = default;
MessageQuote(const MessageQuote &) = delete;
@ -51,6 +53,8 @@ class MessageQuote {
static int need_quote_changed_warning(const MessageQuote &old_quote, const MessageQuote &new_quote);
static int32 search_quote(FormattedText &&text, FormattedText &&quote, int32 quote_position);
bool is_empty() const {
return text_.text.empty();
}

View File

@ -92,6 +92,7 @@
#include "td/telegram/MessageId.h"
#include "td/telegram/MessageImportManager.h"
#include "td/telegram/MessageLinkInfo.h"
#include "td/telegram/MessageQuote.h"
#include "td/telegram/MessageReaction.h"
#include "td/telegram/MessageSearchFilter.h"
#include "td/telegram/MessageSender.h"
@ -9706,9 +9707,9 @@ td_api::object_ptr<td_api::Object> Td::do_static_request(td_api::searchQuote &re
if (r_quote_entities.is_error()) {
return make_error(400, r_quote_entities.error().message());
}
auto position =
search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()},
{std::move(request.quote_->text_), r_quote_entities.move_as_ok()}, request.quote_position_);
auto position = MessageQuote::search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()},
{std::move(request.quote_->text_), r_quote_entities.move_as_ok()},
request.quote_position_);
if (position == -1) {
return make_error(404, "Not Found");
}