Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal/catch_textflow.cpp
diff options
context:
space:
mode:
authorJan Niklas Hasse2026-03-28 16:02:01 +0100
committerMartin Hořeňovský2026-04-01 16:12:08 +0200
commit572f96b8febec9dd14ac5284e6a959a7246325c8 (patch)
tree542479ee537175e5a4c5787c953fb68109fd14e9 /src/catch2/internal/catch_textflow.cpp
parent8492fd444e42f331f48611d2b5ef11c8ce338423 (diff)
downloadcatch3-572f96b8febec9dd14ac5284e6a959a7246325c8.tar.gz
Fix counting of UTF-8 codepoints in TextFlow
For line-wrapping bytes were counted instead of codepoints. This resulted in line-breaks being inserted at the wrong position and also breaking UTF-8 characters. Fixes #1022.
Diffstat (limited to 'src/catch2/internal/catch_textflow.cpp')
-rw-r--r--src/catch2/internal/catch_textflow.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/catch2/internal/catch_textflow.cpp b/src/catch2/internal/catch_textflow.cpp
index 1c21d20e..3979048f 100644
--- a/src/catch2/internal/catch_textflow.cpp
+++ b/src/catch2/internal/catch_textflow.cpp
@@ -26,6 +26,10 @@ namespace {
return std::memchr( chars, c, sizeof( chars ) - 1 ) != nullptr;
}
+ bool isUtf8ContinuationByte( char c ) {
+ return ( static_cast<unsigned char>( c ) & 0xC0 ) == 0x80;
+ }
+
} // namespace
namespace Catch {
@@ -52,6 +56,11 @@ namespace Catch {
if ( it != m_string.end() ) {
++m_size;
++it;
+ // Skip UTF-8 continuation bytes
+ while ( it != m_string.end() &&
+ isUtf8ContinuationByte( *it ) ) {
+ ++it;
+ }
}
}
}
@@ -114,6 +123,11 @@ namespace Catch {
void AnsiSkippingString::const_iterator::advance() {
assert( m_it != m_string->end() );
m_it++;
+ // Skip UTF-8 continuation bytes
+ while ( m_it != m_string->end() &&
+ isUtf8ContinuationByte( *m_it ) ) {
+ m_it++;
+ }
tryParseAnsiEscapes();
}
@@ -133,6 +147,11 @@ namespace Catch {
assert( *m_it == '\033' );
m_it--;
}
+ // Skip back over UTF-8 continuation bytes to the leading byte
+ while ( isUtf8ContinuationByte( *m_it ) ) {
+ assert( m_it != m_string->begin() );
+ m_it--;
+ }
}
static bool isBoundary( AnsiSkippingString const& line,