diff --git a/Common/Data/Encoding/Utf8.cpp b/Common/Data/Encoding/Utf8.cpp index 3ec3fc6ac6..00e2b70578 100644 --- a/Common/Data/Encoding/Utf8.cpp +++ b/Common/Data/Encoding/Utf8.cpp @@ -29,6 +29,7 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Encoding/Utf16.h" +#include "Common/Log.h" // is start of UTF sequence inline bool isutf(char c) { @@ -209,6 +210,7 @@ int u8_charnum(const char *s, int offset) /* reads the next utf-8 sequence out of a string, updating an index */ uint32_t u8_nextchar(const char *s, int *index, size_t size) { uint32_t ch = 0; + _dbg_assert_(*index >= 0 && *index < 100000000); int sz = 0; int i = *index; do { @@ -372,8 +374,6 @@ int u8_is_locale_utf8(const char *locale) return 0; } -UTF8::UTF8(const char *c) : c_(c), size_((int)strlen(c)), index_(0) {} - bool AnyEmojiInString(std::string_view str, size_t byteCount) { int i = 0; while (i < byteCount) { diff --git a/Common/Data/Encoding/Utf8.h b/Common/Data/Encoding/Utf8.h index 87ede82241..61b50cab6d 100644 --- a/Common/Data/Encoding/Utf8.h +++ b/Common/Data/Encoding/Utf8.h @@ -39,7 +39,7 @@ class UTF8 { public: static const uint32_t INVALID = (uint32_t)-1; // TODO: Try to get rid of this constructor. - explicit UTF8(const char *c); + explicit UTF8(const char *c) : c_(c), size_((int)strlen(c)), index_(0) {} explicit UTF8(std::string_view view) : c_(view.data()), size_((int)view.size()), index_(0) {} explicit UTF8(std::string_view view, int index) : c_(view.data()), size_((int)view.size()), index_(index) {} bool end() const { return index_ == size_; } diff --git a/Common/Data/Text/WrapText.cpp b/Common/Data/Text/WrapText.cpp index 68335db1a9..2cabc24232 100644 --- a/Common/Data/Text/WrapText.cpp +++ b/Common/Data/Text/WrapText.cpp @@ -219,7 +219,10 @@ void WordWrapper::Wrap() { } // Measure the entire word for kerning purposes. May not be 100% perfect. - float newWordWidth = MeasureWidth(str_.substr(lastIndex_, afterIndex - lastIndex_)); + float newWordWidth = 0.0f; + if (afterIndex <= str_.length()) { + newWordWidth = MeasureWidth(str_.substr(lastIndex_, afterIndex - lastIndex_)); + } // Is this the end of a word (space)? We'll also output up to a soft hyphen. if (wordWidth_ > 0.0f && IsSpaceOrShy(c)) { diff --git a/Common/Render/DrawBuffer.cpp b/Common/Render/DrawBuffer.cpp index bf646db680..5dc347c0fb 100644 --- a/Common/Render/DrawBuffer.cpp +++ b/Common/Render/DrawBuffer.cpp @@ -463,12 +463,15 @@ float AtlasWordWrapper::MeasureWidth(std::string_view str) { uint32_t c = utf.next(); if (c == '&') { // Skip ampersand prefixes ("&&" is an ampersand.) + if (utf.end()) { + break; + } c = utf.next(); } const AtlasChar *ch = atlasfont_.getChar(c); - if (!ch) + if (!ch) { ch = atlasfont_.getChar('?'); - + } w += ch->wx * scale_; } return w;