@@ -59,6 +59,37 @@ static_assert(
5959 kLevelToPal [size_t (LogLevel::Fatal)] == et_pal_log_level_t ::kFatal ,
6060 " " );
6161
62+ /* *
63+ * Returns the length of the longest valid UTF-8 prefix in a byte buffer.
64+ */
65+ static inline size_t get_valid_utf8_prefix_length (const char * bytes, size_t length) {
66+ if (!bytes || length == 0 ) {
67+ return 0 ;
68+ }
69+ const auto * data = reinterpret_cast <const unsigned char *>(bytes);
70+ auto index = size_t {0 };
71+ auto last_valid_length = size_t {0 };
72+ while (index < length) {
73+ const auto lead_byte = data[index];
74+ const size_t sequence_length =
75+ (lead_byte < 0x80 ) ? 1 :
76+ ((lead_byte & 0xE0 ) == 0xC0 ) ? 2 :
77+ ((lead_byte & 0xF0 ) == 0xE0 ) ? 3 :
78+ ((lead_byte & 0xF8 ) == 0xF0 ) ? 4 : 0 ;
79+ if (!sequence_length || index + sequence_length > length) {
80+ return last_valid_length;
81+ }
82+ for (size_t continuation_index = 1 ; continuation_index < sequence_length; ++continuation_index) {
83+ if ((data[index + continuation_index] & 0xC0 ) != 0x80 ) {
84+ return last_valid_length;
85+ }
86+ }
87+ index += sequence_length;
88+ last_valid_length = index;
89+ }
90+ return last_valid_length;
91+ }
92+
6293/* *
6394 * Log a string message.
6495 *
@@ -84,20 +115,23 @@ void vlogf(
84115
85116 // Maximum length of a log message.
86117 static constexpr size_t kMaxLogMessageLength = 256 ;
87- char buf[kMaxLogMessageLength ];
88- size_t len = vsnprintf (buf, kMaxLogMessageLength , format, args);
89- if (len >= kMaxLogMessageLength - 1 ) {
90- buf[kMaxLogMessageLength - 2 ] = ' $' ;
91- len = kMaxLogMessageLength - 1 ;
92- }
93- buf[kMaxLogMessageLength - 1 ] = 0 ;
118+ char buffer[kMaxLogMessageLength ];
119+
120+ const auto write_count = vsnprintf (buffer, kMaxLogMessageLength , format, args);
121+ const size_t used_length = (write_count < 0 )
122+ ? 0
123+ : (write_count >= static_cast <int >(kMaxLogMessageLength )
124+ ? kMaxLogMessageLength - 1
125+ : static_cast <size_t >(write_count));
126+ const auto valid_length = get_valid_utf8_prefix_length (buffer, used_length);
127+ buffer[valid_length] = ' \0 ' ;
94128
95- et_pal_log_level_t pal_level = (level < LogLevel::NumLevels)
129+ const auto pal_level = (level < LogLevel::NumLevels)
96130 ? kLevelToPal [size_t (level)]
97131 : et_pal_log_level_t ::kUnknown ;
98132
99133 pal_emit_log_message (
100- timestamp, pal_level, filename, function, line, buf, len );
134+ timestamp, pal_level, filename, function, line, buffer, valid_length );
101135
102136#endif // ET_LOG_ENABLED
103137}
0 commit comments