From fe2bd4c4d8092646520e259bccf3a4ac11e79379 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sun, 9 Apr 2023 19:36:30 +0200 Subject: [PATCH] Make sure only UTF-8 encoded strings are getting logged This should fix all bugs and vulnerabilities to the ImGui console. This code has been fuzzed for hours without triggering any exceptions or assertions. --- r5dev/thirdparty/imgui/misc/imgui_logger.cpp | 42 +++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/r5dev/thirdparty/imgui/misc/imgui_logger.cpp b/r5dev/thirdparty/imgui/misc/imgui_logger.cpp index c873c078..25936377 100644 --- a/r5dev/thirdparty/imgui/misc/imgui_logger.cpp +++ b/r5dev/thirdparty/imgui/misc/imgui_logger.cpp @@ -138,6 +138,33 @@ static int UTF8CharLength(CTextLogger::Char c) return 1; } +bool UTF8StringValid(const char* pszString) +{ + unsigned int byteCount = 0; + unsigned char currentByte; + + while (*pszString) + { + currentByte = static_cast(*pszString); + if (byteCount) + { + if ((currentByte & 0xC0) != 0x80) + return false; + + byteCount--; + } + else + { + byteCount = UTF8CharLength(currentByte) - 1; + if (byteCount > 0 && (currentByte & (1 << (7 - byteCount))) == 0) + return false; + } + pszString++; + } + + return byteCount == 0; +} + void CTextLogger::Advance(Coordinates & aCoordinates) const { if (aCoordinates.m_nLine < static_cast(m_Lines.size())) @@ -208,6 +235,9 @@ void CTextLogger::MarkNewline(Coordinates& /* inout */ aWhere, const ImVec4& aCo } else line.push_back(Glyph('\n', aColor)); + + ++aWhere.m_nLine; + aWhere.m_nColumn = 0; } int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValue, const ImVec4& aColor) @@ -215,6 +245,12 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValu int cindex = GetCharacterIndex(aWhere); int totalLines = 0; + if (!UTF8StringValid(aValue)) + { + assert(0); + aValue = "Invalid UTF-8 string\n"; + } + while (*aValue != '\0') { assert(!m_Lines.empty()); @@ -227,8 +263,6 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValu else if (*aValue == '\n') { MarkNewline(aWhere, aColor, cindex); - ++aWhere.m_nLine; - aWhere.m_nColumn = 0; cindex = 0; ++totalLines; ++aValue; @@ -239,8 +273,6 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char* aValu if (!line.empty() && ImGui::ColorConvertFloat4ToU32(aColor) != ImGui::ColorConvertFloat4ToU32(line[0].m_Color)) { MarkNewline(aWhere, line[0].m_Color, cindex); - ++aWhere.m_nLine; - aWhere.m_nColumn = 0; cindex = 0; ++totalLines; continue; @@ -909,7 +941,7 @@ void CTextLogger::Render() ImGui::Dummy(ImVec2((longest + 2), m_Lines.size() * m_CharAdvance.y)); m_bScrolledToMax = ImGui::GetScrollY() >= ImGui::GetScrollMaxY(); - if (m_bScrollToBottom || (!m_bScrollToCursor && m_bAutoScroll && m_bScrolledToMax)) + if (m_bScrollToBottom || (m_bAutoScroll && m_bScrolledToMax && !m_bScrollToCursor)) { ImGui::SetScrollHereY(1.0f); m_bScrollToBottom = false;