11/*
22 *
3- * Copyright (C) 2024-2025 Intel Corporation
3+ * Copyright (C) 2024-2026 Intel Corporation
44 *
55 * Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -72,6 +72,46 @@ typedef struct {
7272utils_log_config_t loggerConfig = {false, false, LOG_ERROR ,
7373 LOG_ERROR , NULL , "" };
7474
75+ static void log_buffer_advance (char * * pos , size_t * size , size_t written ) {
76+ ASSERT (pos );
77+ ASSERT (size );
78+
79+ // do nothing if the size is 0 or can only hold the NULL terminator
80+ if (* size <= 1 ) {
81+ * size = 0 ;
82+ return ;
83+ }
84+
85+ size_t advance = utils_min (written , * size - 1 );
86+ * pos += advance ;
87+
88+ if (written >= * size ) {
89+ * size = 0 ;
90+ return ;
91+ }
92+
93+ * size -= advance ;
94+ }
95+
96+ static void log_buffer_append (char * * pos , size_t * size , const char * src ) {
97+ ASSERT (pos );
98+ ASSERT (size );
99+ ASSERT (src );
100+
101+ if (* size == 0 ) {
102+ return ;
103+ }
104+
105+ size_t src_len = strlen (src );
106+ size_t copy_len = utils_min (src_len , * size - 1 );
107+ memcpy (* pos , src , copy_len );
108+
109+ // copy_len excludes the trailing NULL, add it explicitly
110+ (* pos )[copy_len ] = '\0' ;
111+
112+ log_buffer_advance (pos , size , src_len );
113+ }
114+
75115static const char * level_to_str (utils_log_level_t l ) {
76116 switch (l ) {
77117 case LOG_DEBUG :
@@ -113,24 +153,29 @@ static void utils_log_internal(utils_log_level_t level, int perror,
113153
114154 char buffer [LOG_MAX ];
115155 char * b_pos = buffer ;
116- int b_size = sizeof (buffer );
156+ size_t b_size = sizeof (buffer );
117157
118158 int tmp = 0 ;
119159 if (fileline == NULL ) {
120160 tmp = snprintf (b_pos , b_size , "%s: " , func );
121161 } else {
122162 tmp = snprintf (b_pos , b_size , "%s %s: " , fileline , func );
123163 }
124- ASSERT (tmp > 0 );
125164
126- b_pos += (int )tmp ;
127- b_size -= (int )tmp ;
165+ if (tmp < 0 ) {
166+ return ; // snprintf error
167+ }
168+
169+ size_t written = (size_t )tmp ;
170+ log_buffer_advance (& b_pos , & b_size , written );
128171
129172 tmp = vsnprintf (b_pos , b_size , format , args );
130- ASSERT (tmp > 0 );
173+ if (tmp < 0 ) {
174+ return ; // vsnprintf error
175+ }
131176
132- b_pos + = (int )tmp ;
133- b_size -= ( int ) tmp ;
177+ written = (size_t )tmp ;
178+ log_buffer_advance ( & b_pos , & b_size , written ) ;
134179
135180 const char * postfix = "" ;
136181
@@ -139,10 +184,12 @@ static void utils_log_internal(utils_log_level_t level, int perror,
139184 strncat (b_pos , ": " , b_size );
140185 b_pos += 2 ;
141186 b_size -= 2 ;
187+ const char * err = "" ;
142188#if defined(_WIN32 )
143- char err [80 ]; // max size according to msdn
144- if (strerror_s (err , sizeof (err ), errno )) {
145- * err = '\0' ;
189+ char err_buff [80 ]; // max size according to msdn
190+ err = err_buff ;
191+ if (strerror_s (err_buff , sizeof (err_buff ), errno )) {
192+ * err_buff = '\0' ;
146193 postfix = "[strerror_s failed]" ;
147194 }
148195#else
@@ -151,33 +198,27 @@ static void utils_log_internal(utils_log_level_t level, int perror,
151198
152199#if defined(__APPLE__ ) || \
153200 ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 ) && !_GNU_SOURCE )
154- char err [1024 ];
155- int ret = strerror_r (saveno , err , sizeof (err ));
201+ char err_buff [1024 ];
202+ err = err_buff ;
203+ int ret = strerror_r (saveno , err_buff , sizeof (err_buff ));
156204 if (ret ) {
157- * err = '\0' ;
205+ * err_buff = '\0' ;
158206 postfix = "[strerror_r failed]" ;
159207 }
160208 if (errno == ERANGE ) {
161209 postfix = "[truncated...]" ;
162210 }
163211#else
164212 char err_buff [1024 ];
165- const char * err = strerror_r (saveno , err_buff , sizeof (err_buff ));
213+ err = strerror_r (saveno , err_buff , sizeof (err_buff ));
166214 if (errno == ERANGE ) {
167215 postfix = "[truncated...]" ;
168216 }
169217#endif
170218
171219 errno = saveno ;
172220#endif
173- strncpy (b_pos , err , b_size );
174- size_t err_size = strlen (err );
175- b_pos += err_size ;
176- b_size -= (int )err_size ;
177- if (b_size <= 0 ) {
178- buffer [LOG_MAX - 1 ] =
179- '\0' ; //strncpy do not add \0 in case of overflow
180- }
221+ log_buffer_append (& b_pos , & b_size , err );
181222 } else {
182223 postfix = "[truncated...]" ;
183224 }
@@ -190,7 +231,7 @@ static void utils_log_internal(utils_log_level_t level, int perror,
190231
191232 char header [LOG_HEADER ];
192233 char * h_pos = header ;
193- int h_size = sizeof (header );
234+ size_t h_size = sizeof (header );
194235 memset (header , 0 , sizeof (header ));
195236
196237 if (loggerConfig .enableTimestamp ) {
@@ -202,18 +243,22 @@ static void utils_log_internal(utils_log_level_t level, int perror,
202243 localtime_r (& now , & tm_info );
203244#endif
204245
205- ASSERT (h_size > 0 );
206- tmp = (int )strftime (h_pos , h_size , "%Y-%m-%dT%H:%M:%S " , & tm_info );
207- h_pos += tmp ;
208- h_size -= tmp ;
246+ written = strftime (h_pos , h_size , "%Y-%m-%dT%H:%M:%S " , & tm_info );
247+ if (written == 0 && h_size > 0 ) {
248+ h_pos [0 ] = '\0' ;
249+ }
250+ log_buffer_advance (& h_pos , & h_size , written );
209251 }
210252
211253 if (loggerConfig .enablePid ) {
212254 ASSERT (h_size > 0 );
213255 tmp = snprintf (h_pos , h_size , "PID:%-6lu TID:%-6lu " ,
214256 (unsigned long )pid , (unsigned long )tid );
215- h_pos += tmp ;
216- h_size -= tmp ;
257+ if (tmp < 0 ) {
258+ return ; // snprintf error
259+ }
260+ written = (size_t )tmp ;
261+ log_buffer_advance (& h_pos , & h_size , written );
217262 }
218263
219264 // We take twice header size here to ensure that
@@ -222,6 +267,7 @@ static void utils_log_internal(utils_log_level_t level, int perror,
222267 char logLine [LOG_MAX + LOG_HEADER * 2 ];
223268 snprintf (logLine , sizeof (logLine ), "[%s%-5s UMF] %s%s\n" , header ,
224269 level_to_str (level ), buffer , postfix );
270+
225271 FILE * out = loggerConfig .output ? loggerConfig .output : stderr ;
226272 fputs (logLine , out );
227273
0 commit comments