Make remove_unallowed_quote_entities private to MessageQuote.
This commit is contained in:
parent
02a99f3c50
commit
73ccba7f0f
@ -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) {
|
static int32 text_length(Slice text) {
|
||||||
return narrow_cast<int32>(utf8_utf16_length(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);
|
return std::move(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fix_entities(vector<MessageEntity> &entities) {
|
void fix_entities(vector<MessageEntity> &entities) {
|
||||||
sort_entities(entities);
|
sort_entities(entities);
|
||||||
|
|
||||||
if (are_entities_valid(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 &"e, 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, "e, &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
|
} // namespace td
|
||||||
|
@ -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_empty_entities(vector<MessageEntity> &entities);
|
||||||
|
|
||||||
void remove_unallowed_quote_entities(FormattedText &text);
|
|
||||||
|
|
||||||
int32 search_quote(FormattedText &&text, FormattedText &"e, int32 quote_position);
|
|
||||||
|
|
||||||
Slice get_first_url(const FormattedText &text);
|
Slice get_first_url(const FormattedText &text);
|
||||||
|
|
||||||
bool is_visible_url(const FormattedText &text, const string &url);
|
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,
|
telegram_api::object_ptr<telegram_api::textWithEntities> text_with_entities,
|
||||||
bool allow_empty, bool skip_media_timestamps, bool skip_trim, const char *source);
|
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
|
// like clean_input_string but also validates entities
|
||||||
Status fix_formatted_text(string &text, vector<MessageEntity> &entities, bool allow_empty, bool skip_new_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,
|
bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim,
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
#include "td/telegram/UserManager.h"
|
#include "td/telegram/UserManager.h"
|
||||||
|
|
||||||
|
#include "td/utils/algorithm.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/misc.h"
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
|
#include "td/utils/utf8.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@ -69,7 +73,6 @@ MessageQuote MessageQuote::clone(bool ignore_is_manual) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageQuote MessageQuote::create_automatic_quote(Td *td, FormattedText &&text) {
|
MessageQuote MessageQuote::create_automatic_quote(Td *td, FormattedText &&text) {
|
||||||
remove_unallowed_quote_entities(text);
|
|
||||||
truncate_formatted_text(
|
truncate_formatted_text(
|
||||||
text, static_cast<size_t>(td->option_manager_->get_option_integer("message_reply_quote_length_max")));
|
text, static_cast<size_t>(td->option_manager_->get_option_integer("message_reply_quote_length_max")));
|
||||||
return MessageQuote(std::move(text), 0, false);
|
return MessageQuote(std::move(text), 0, false);
|
||||||
@ -155,4 +158,81 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote &quo
|
|||||||
return string_builder;
|
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 &"e, 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, "e, &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
|
} // namespace td
|
||||||
|
@ -28,6 +28,8 @@ class MessageQuote {
|
|||||||
|
|
||||||
friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote "e);
|
friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote "e);
|
||||||
|
|
||||||
|
static void remove_unallowed_quote_entities(FormattedText &text);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MessageQuote() = default;
|
MessageQuote() = default;
|
||||||
MessageQuote(const MessageQuote &) = delete;
|
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 int need_quote_changed_warning(const MessageQuote &old_quote, const MessageQuote &new_quote);
|
||||||
|
|
||||||
|
static int32 search_quote(FormattedText &&text, FormattedText &"e, int32 quote_position);
|
||||||
|
|
||||||
bool is_empty() const {
|
bool is_empty() const {
|
||||||
return text_.text.empty();
|
return text_.text.empty();
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
#include "td/telegram/MessageId.h"
|
#include "td/telegram/MessageId.h"
|
||||||
#include "td/telegram/MessageImportManager.h"
|
#include "td/telegram/MessageImportManager.h"
|
||||||
#include "td/telegram/MessageLinkInfo.h"
|
#include "td/telegram/MessageLinkInfo.h"
|
||||||
|
#include "td/telegram/MessageQuote.h"
|
||||||
#include "td/telegram/MessageReaction.h"
|
#include "td/telegram/MessageReaction.h"
|
||||||
#include "td/telegram/MessageSearchFilter.h"
|
#include "td/telegram/MessageSearchFilter.h"
|
||||||
#include "td/telegram/MessageSender.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()) {
|
if (r_quote_entities.is_error()) {
|
||||||
return make_error(400, r_quote_entities.error().message());
|
return make_error(400, r_quote_entities.error().message());
|
||||||
}
|
}
|
||||||
auto position =
|
auto position = MessageQuote::search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()},
|
||||||
search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()},
|
{std::move(request.quote_->text_), r_quote_entities.move_as_ok()},
|
||||||
{std::move(request.quote_->text_), r_quote_entities.move_as_ok()}, request.quote_position_);
|
request.quote_position_);
|
||||||
if (position == -1) {
|
if (position == -1) {
|
||||||
return make_error(404, "Not Found");
|
return make_error(404, "Not Found");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user