mirror of https://github.com/procxx/kepka.git
Fix crash in case of incorrect Text entities.
This commit is contained in:
parent
7814ee0f7a
commit
f88cbf3d4b
|
@ -493,6 +493,31 @@ void SetAnnotation(const std::string &key, const QString &value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAnnotationHex(const std::string &key, const QString &value) {
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
return SetAnnotation(key, value);
|
||||||
|
}
|
||||||
|
const auto utf = value.toUtf8();
|
||||||
|
auto buffer = std::string();
|
||||||
|
buffer.reserve(4 * utf.size());
|
||||||
|
const auto hexDigit = [](std::uint8_t value) {
|
||||||
|
if (value >= 10) {
|
||||||
|
return 'A' + (value - 10);
|
||||||
|
}
|
||||||
|
return '0' + value;
|
||||||
|
};
|
||||||
|
const auto appendHex = [&](std::uint8_t value) {
|
||||||
|
buffer.push_back('\\');
|
||||||
|
buffer.push_back('x');
|
||||||
|
buffer.push_back(hexDigit(value / 16));
|
||||||
|
buffer.push_back(hexDigit(value % 16));
|
||||||
|
};
|
||||||
|
for (const auto ch : utf) {
|
||||||
|
appendHex(ch);
|
||||||
|
}
|
||||||
|
ProcessAnnotations[key] = std::move(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void SetAnnotationRef(const std::string &key, const QString *valuePtr) {
|
void SetAnnotationRef(const std::string &key, const QString *valuePtr) {
|
||||||
if (valuePtr) {
|
if (valuePtr) {
|
||||||
ProcessAnnotationRefs[key] = valuePtr;
|
ProcessAnnotationRefs[key] = valuePtr;
|
||||||
|
|
|
@ -34,6 +34,7 @@ Status Restart(); // can be only CantOpen or Started
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
void SetAnnotation(const std::string &key, const QString &value);
|
void SetAnnotation(const std::string &key, const QString &value);
|
||||||
|
void SetAnnotationHex(const std::string &key, const QString &value);
|
||||||
inline void ClearAnnotation(const std::string &key) {
|
inline void ClearAnnotation(const std::string &key) {
|
||||||
SetAnnotation(key, QString());
|
SetAnnotation(key, QString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -496,7 +496,9 @@ HistoryMessage::HistoryMessage(
|
||||||
initMedia(msg.has_media() ? (&msg.vmedia) : nullptr);
|
initMedia(msg.has_media() ? (&msg.vmedia) : nullptr);
|
||||||
|
|
||||||
auto text = TextUtilities::Clean(qs(msg.vmessage));
|
auto text = TextUtilities::Clean(qs(msg.vmessage));
|
||||||
auto entities = msg.has_entities() ? TextUtilities::EntitiesFromMTP(msg.ventities.v) : EntitiesInText();
|
auto entities = msg.has_entities()
|
||||||
|
? TextUtilities::EntitiesFromMTP(msg.ventities.v)
|
||||||
|
: EntitiesInText();
|
||||||
setText({ text, entities });
|
setText({ text, entities });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include <private/qharfbuzz_p.h>
|
#include <private/qharfbuzz_p.h>
|
||||||
|
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "core/crash_reports.h"
|
||||||
#include "ui/text/text_block.h"
|
#include "ui/text/text_block.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
|
@ -293,19 +294,15 @@ public:
|
||||||
|
|
||||||
++waitingEntity;
|
++waitingEntity;
|
||||||
if (links.size() >= 0x7FFF) {
|
if (links.size() >= 0x7FFF) {
|
||||||
while (waitingEntity != entitiesEnd && (
|
while (waitingEntity != entitiesEnd
|
||||||
waitingEntity->type() == EntityInTextUrl ||
|
&& (isLinkEntity(*waitingEntity)
|
||||||
waitingEntity->type() == EntityInTextCustomUrl ||
|
|| isInvalidEntity(*waitingEntity))) {
|
||||||
waitingEntity->type() == EntityInTextEmail ||
|
|
||||||
waitingEntity->type() == EntityInTextHashtag ||
|
|
||||||
waitingEntity->type() == EntityInTextMention ||
|
|
||||||
waitingEntity->type() == EntityInTextMentionName ||
|
|
||||||
waitingEntity->type() == EntityInTextBotCommand ||
|
|
||||||
waitingEntity->length() <= 0)) {
|
|
||||||
++waitingEntity;
|
++waitingEntity;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (waitingEntity != entitiesEnd && waitingEntity->length() <= 0) ++waitingEntity;
|
while (waitingEntity != entitiesEnd && isInvalidEntity(*waitingEntity)) {
|
||||||
|
++waitingEntity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -479,10 +476,14 @@ public:
|
||||||
for (int l = len - emojiLookback - 1; l > 0; --l) {
|
for (int l = len - emojiLookback - 1; l > 0; --l) {
|
||||||
_t->_text.push_back(*++ptr);
|
_t->_text.push_back(*++ptr);
|
||||||
}
|
}
|
||||||
if (e->hasPostfix() && _t->_text.at(_t->_text.size() - 1).unicode() != Ui::Emoji::kPostfix) {
|
if (e->hasPostfix()) {
|
||||||
|
Assert(!_t->_text.isEmpty());
|
||||||
|
const auto last = _t->_text[_t->_text.size() - 1];
|
||||||
|
if (last.unicode() != Ui::Emoji::kPostfix) {
|
||||||
_t->_text.push_back(QChar(Ui::Emoji::kPostfix));
|
_t->_text.push_back(QChar(Ui::Emoji::kPostfix));
|
||||||
++len;
|
++len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createBlock(-len);
|
createBlock(-len);
|
||||||
emoji = e;
|
emoji = e;
|
||||||
|
@ -530,6 +531,25 @@ public:
|
||||||
parse(options);
|
parse(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isInvalidEntity(const EntityInText &entity) const {
|
||||||
|
const auto length = entity.length();
|
||||||
|
return (start + entity.offset() + length > end) || (length <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLinkEntity(const EntityInText &entity) const {
|
||||||
|
const auto type = entity.type();
|
||||||
|
const auto urls = {
|
||||||
|
EntityInTextUrl,
|
||||||
|
EntityInTextCustomUrl,
|
||||||
|
EntityInTextEmail,
|
||||||
|
EntityInTextHashtag,
|
||||||
|
EntityInTextMention,
|
||||||
|
EntityInTextMentionName,
|
||||||
|
EntityInTextBotCommand
|
||||||
|
};
|
||||||
|
return ranges::find(urls, type) != std::end(urls);
|
||||||
|
}
|
||||||
|
|
||||||
void parse(const TextParseOptions &options) {
|
void parse(const TextParseOptions &options) {
|
||||||
if (options.maxw > 0 && options.maxh > 0) {
|
if (options.maxw > 0 && options.maxh > 0) {
|
||||||
stopAfterWidth = ((options.maxh / _t->_st->font->height) + 1) * options.maxw;
|
stopAfterWidth = ((options.maxh / _t->_st->font->height) + 1) * options.maxw;
|
||||||
|
@ -540,7 +560,9 @@ public:
|
||||||
|
|
||||||
entitiesEnd = source.entities.cend();
|
entitiesEnd = source.entities.cend();
|
||||||
waitingEntity = source.entities.cbegin();
|
waitingEntity = source.entities.cbegin();
|
||||||
while (waitingEntity != entitiesEnd && waitingEntity->length() <= 0) ++waitingEntity;
|
while (waitingEntity != entitiesEnd && isInvalidEntity(*waitingEntity)) {
|
||||||
|
++waitingEntity;
|
||||||
|
}
|
||||||
int firstMonospaceOffset = EntityInText::firstMonospaceOffset(source.entities, end - start);
|
int firstMonospaceOffset = EntityInText::firstMonospaceOffset(source.entities, end - start);
|
||||||
|
|
||||||
ptr = start;
|
ptr = start;
|
||||||
|
|
Loading…
Reference in New Issue