@@ -59,6 +59,42 @@ static_assert(
5959 kLevelToPal [size_t (LogLevel::Fatal)] == et_pal_log_level_t ::kFatal ,
6060 " " );
6161
62+ #if ET_LOG_ENABLED
63+ /* *
64+ * Returns the length of the longest valid UTF-8 prefix in a byte buffer.
65+ */
66+ static inline size_t get_valid_utf8_prefix_length (
67+ const char * bytes,
68+ size_t length) {
69+ if (!bytes || length == 0 ) {
70+ return 0 ;
71+ }
72+ const auto * data = reinterpret_cast <const unsigned char *>(bytes);
73+ auto index = size_t {0 };
74+ auto last_valid_length = size_t {0 };
75+ while (index < length) {
76+ const auto lead_byte = data[index];
77+ const size_t sequence_length = (lead_byte < 0x80 ) ? 1
78+ : ((lead_byte & 0xE0 ) == 0xC0 ) ? 2
79+ : ((lead_byte & 0xF0 ) == 0xE0 ) ? 3
80+ : ((lead_byte & 0xF8 ) == 0xF0 ) ? 4
81+ : 0 ;
82+ if (!sequence_length || index + sequence_length > length) {
83+ return last_valid_length;
84+ }
85+ for (size_t continuation_index = 1 ; continuation_index < sequence_length;
86+ ++continuation_index) {
87+ if ((data[index + continuation_index] & 0xC0 ) != 0x80 ) {
88+ return last_valid_length;
89+ }
90+ }
91+ index += sequence_length;
92+ last_valid_length = index;
93+ }
94+ return last_valid_length;
95+ }
96+ #endif // ET_LOG_ENABLED
97+
6298/* *
6399 * Log a string message.
64100 *
@@ -84,20 +120,24 @@ void vlogf(
84120
85121 // Maximum length of a log message.
86122 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 ;
123+ char buffer[kMaxLogMessageLength ];
124+
125+ const auto write_count =
126+ vsnprintf (buffer, kMaxLogMessageLength , format, args);
127+ const size_t used_length = (write_count < 0 )
128+ ? 0
129+ : (write_count >= static_cast <int >(kMaxLogMessageLength )
130+ ? kMaxLogMessageLength - 1
131+ : static_cast <size_t >(write_count));
132+ const auto valid_length = get_valid_utf8_prefix_length (buffer, used_length);
133+ buffer[valid_length] = ' \0 ' ;
94134
95- et_pal_log_level_t pal_level = (level < LogLevel::NumLevels)
135+ const auto pal_level = (level < LogLevel::NumLevels)
96136 ? kLevelToPal [size_t (level)]
97137 : et_pal_log_level_t ::kUnknown ;
98138
99139 pal_emit_log_message (
100- timestamp, pal_level, filename, function, line, buf, len );
140+ timestamp, pal_level, filename, function, line, buffer, valid_length );
101141
102142#endif // ET_LOG_ENABLED
103143}
0 commit comments