@@ -59,6 +59,42 @@ static_assert(
59
59
kLevelToPal [size_t (LogLevel::Fatal)] == et_pal_log_level_t ::kFatal ,
60
60
" " );
61
61
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
+
62
98
/* *
63
99
* Log a string message.
64
100
*
@@ -84,20 +120,24 @@ void vlogf(
84
120
85
121
// Maximum length of a log message.
86
122
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 ' ;
94
134
95
- et_pal_log_level_t pal_level = (level < LogLevel::NumLevels)
135
+ const auto pal_level = (level < LogLevel::NumLevels)
96
136
? kLevelToPal [size_t (level)]
97
137
: et_pal_log_level_t ::kUnknown ;
98
138
99
139
pal_emit_log_message (
100
- timestamp, pal_level, filename, function, line, buf, len );
140
+ timestamp, pal_level, filename, function, line, buffer, valid_length );
101
141
102
142
#endif // ET_LOG_ENABLED
103
143
}
0 commit comments