aboutsummaryrefslogtreecommitdiff
path: root/src/Text.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-11-05 23:59:18 +0100
committerdec05eba <dec05eba@protonmail.com>2022-11-05 23:59:18 +0100
commitf7246d83d2f43e0088e2a01ff6305ac7e25f21fe (patch)
tree293bb9545f85374885c478a04089c6c983b6194a /src/Text.cpp
parent5836c731bd57a6d892f77d7d0c52e6bf74bde0a1 (diff)
Fix possible crash on backspace in edit text with invalid utf8
Diffstat (limited to 'src/Text.cpp')
-rw-r--r--src/Text.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/Text.cpp b/src/Text.cpp
index 192061f..0b6347d 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -510,21 +510,11 @@ namespace QuickMedia
if(emoji_codepoint_combined == "1f441-fe0f-200d-1f5e8-fe0f")
emoji_codepoint_combined = "1f441-200d-1f5e8";
- std::string image_url;
- bool image_local = false;
- if(emoji_codepoint_combined != "1f3f3-fe0f-200d-26a7-fe0f") {
- image_url = "/usr/share/quickmedia/emoji/" + emoji_codepoint_combined + ".png";
- image_local = true;
- } else {
- image_url = "/usr/share/quickmedia/images/troonjak.png";
- image_local = true;
- }
-
text_element.create_text("E");
text_element.text_type = TextElement::TextType::EMOJI;
text_element.text = "E";
- text_element.url = std::move(image_url);
- text_element.local = image_local;
+ text_element.url = "/usr/share/quickmedia/emoji/" + emoji_codepoint_combined + ".png";
+ text_element.local = true;
text_element.size = { (int)vspace, (int)vspace };
text_element.text_num_bytes = emoji_byte_length;
text_elements.push_back(std::move(text_element));
@@ -602,6 +592,23 @@ namespace QuickMedia
static mgl::vec2f vec2f_floor(mgl::vec2f value) {
return mgl::vec2f((int)value.x, (int)value.y);
}
+
+ static size_t utf8_get_num_codepoints(const char *str, size_t size) {
+ size_t codepoint_index = 0;
+ for(size_t i = 0; i < size;) {
+ unsigned char *cp = (unsigned char*)&str[i];
+ uint32_t codepoint;
+ size_t clen;
+ if(!mgl::utf8_decode(cp, size - i, &codepoint, &clen)) {
+ codepoint = *cp;
+ clen = 1;
+ }
+
+ i += clen;
+ ++codepoint_index;
+ }
+ return codepoint_index;
+ }
void Text::updateGeometry(bool update_even_if_not_dirty) {
if(dirtyText) {
@@ -1183,6 +1190,9 @@ namespace QuickMedia
}
else if(event.key.code == mgl::Keyboard::Backspace && caretIndex > 0)
{
+ if(caretIndex < 0 || caretIndex > (int)vertices_linear.size())
+ return;
+
const size_t str_index = get_string_index_from_caret_index(caretIndex);
if(str_index > 0 && str_index <= str.size()) {
const size_t codepoint_start = str_index - vertices_linear[caretIndex - 1].text_num_bytes;
@@ -1195,6 +1205,9 @@ namespace QuickMedia
}
else if(event.key.code == mgl::Keyboard::Delete && !caretAtEnd)
{
+ if(caretIndex < 0 || caretIndex >= (int)vertices_linear.size())
+ return;
+
const size_t str_index = get_string_index_from_caret_index(caretIndex);
const size_t codepoint_end = str_index + vertices_linear[caretIndex].text_num_bytes;
if(str_index < str.size() && codepoint_end <= str.size()) {
@@ -1266,10 +1279,11 @@ namespace QuickMedia
std::vector<TextElement> new_text_elements;
split_text_by_type(new_text_elements, stringToAdd);
for(auto &text_element : new_text_elements) {
- if(text_element.type == TextElement::Type::IMAGE || text_element.text_type == TextElement::TextType::EMOJI)
+ if(text_element.type == TextElement::Type::IMAGE || text_element.text_type == TextElement::TextType::EMOJI) {
caretIndex += 1;
- else
- caretIndex += text_element.text_num_bytes;
+ } else {
+ caretIndex += utf8_get_num_codepoints(text_element.text.data(), text_element.text.size());
+ }
}
dirty = true;
dirtyText = true;