@@ -66,6 +66,8 @@ int32_t FOSSIL_IO_COLOR_ENABLE = 1; // Flag to enable/disable color output
6666
6767// Function to apply color
6868void fossil_io_apply_color (const char * color ) {
69+ if (!FOSSIL_IO_COLOR_ENABLE || !color ) return ;
70+
6971 if (strcmp (color , "red" ) == 0 ) {
7072 printf (FOSSIL_IO_COLOR_RED );
7173 } else if (strcmp (color , "green" ) == 0 ) {
@@ -103,6 +105,8 @@ void fossil_io_apply_color(const char *color) {
103105
104106// Function to apply text attributes (e.g., bold, underline)
105107void fossil_io_apply_attribute (const char * attribute ) {
108+ if (!attribute ) return ;
109+
106110 if (strcmp (attribute , "bold" ) == 0 ) {
107111 printf (FOSSIL_IO_ATTR_BOLD );
108112 } else if (strcmp (attribute , "underline" ) == 0 ) {
@@ -124,28 +128,30 @@ void fossil_io_apply_attribute(const char *attribute) {
124128
125129// Function to handle named positions (like top, bottom, left, right)
126130void fossil_io_apply_position (const char * pos ) {
131+ if (!pos ) return ;
132+
127133 if (strcmp (pos , "top" ) == 0 ) {
128134 printf ("\033[1;1H" ); // Move to top
129135 } else if (strcmp (pos , "bottom" ) == 0 ) {
130- printf ("\033[1000 ;1H" ); // Move cursor to bottom-left
136+ printf ("\033[999 ;1H" ); // Move cursor to bottom-left (reduced from 1000)
131137 } else if (strcmp (pos , "left" ) == 0 ) {
132138 printf ("\033[1;1H" ); // Move to top-left (as a general left start)
133139 } else if (strcmp (pos , "right" ) == 0 ) {
134- printf ("\033[1;1000H " ); // Move to top-right
140+ printf ("\033[1;999H " ); // Move to top-right (reduced from 1000)
135141 } else if (strcmp (pos , "center" ) == 0 ) {
136142 printf ("\033[25;40H" ); // Approximate center for 80x50 terminal
137143 } else if (strcmp (pos , "top-left" ) == 0 ) {
138144 printf ("\033[1;1H" );
139145 } else if (strcmp (pos , "top-right" ) == 0 ) {
140- printf ("\033[1;1000H " );
146+ printf ("\033[1;999H " );
141147 } else if (strcmp (pos , "bottom-left" ) == 0 ) {
142- printf ("\033[1000 ;1H" );
148+ printf ("\033[999 ;1H" );
143149 } else if (strcmp (pos , "bottom-right" ) == 0 ) {
144- printf ("\033[1000;1000H " );
150+ printf ("\033[999;999H " );
145151 } else if (strcmp (pos , "middle-left" ) == 0 ) {
146152 printf ("\033[25;1H" ); // Mid vertical, far left
147153 } else if (strcmp (pos , "middle-right" ) == 0 ) {
148- printf ("\033[25;1000H " ); // Mid vertical, far right
154+ printf ("\033[25;999H " ); // Mid vertical, far right
149155 } else {
150156 fprintf (stderr , "Unknown position: %s\n" , pos );
151157 }
@@ -164,41 +170,46 @@ void fossil_io_print_with_attributes(const char *str) {
164170
165171 while ((start = strchr (current_pos , '{' )) != NULL ) {
166172 // Output text before '{'
167- fwrite (current_pos , 1 , start - current_pos , stdout );
173+ size_t len = start - current_pos ;
174+ if (len > 0 ) {
175+ fwrite (current_pos , 1 , len , stdout );
176+ }
168177
169178 // Find the matching '}'
170179 end = strchr (start , '}' );
171180 if (end ) {
172181 // Extract attributes inside '{}'
173182 size_t length = end - start - 1 ;
174- char attributes [length + 1 ];
175- strncpy (attributes , start + 1 , length );
176- attributes [length ] = '\0' ;
177-
178- // Split by comma to separate color, attribute, or position
179- char * color = NULL ;
180- char * attribute = NULL ;
181- char * pos = NULL ;
182- char * comma_pos = strchr (attributes , ',' );
183- if (comma_pos ) {
184- * comma_pos = '\0' ; // Null-terminate the first part
185- color = attributes ; // Color or position part
186- attribute = comma_pos + 1 ; // Attribute part
187- } else {
188- color = attributes ; // Only one part (could be color, attribute, or position)
189- }
190-
191- // Handle positions (like {pos:name})
192- if (strstr (color , "pos:" ) == color ) {
193- pos = color + 4 ; // Skip the "pos:" prefix
194- fossil_io_apply_position (pos );
195- } else {
196- // Apply color and/or attribute based on flags
197- if (FOSSIL_IO_COLOR_ENABLE && color ) {
198- fossil_io_apply_color (color );
183+ if (length > 0 && length < 256 ) { // Reasonable size limit
184+ char attributes [257 ];
185+ strncpy (attributes , start + 1 , length );
186+ attributes [length ] = '\0' ;
187+
188+ // Split by comma to separate color, attribute, or position
189+ char * color = NULL ;
190+ char * attribute = NULL ;
191+ char * pos = NULL ;
192+ char * comma_pos = strchr (attributes , ',' );
193+ if (comma_pos ) {
194+ * comma_pos = '\0' ; // Null-terminate the first part
195+ color = attributes ; // Color or position part
196+ attribute = comma_pos + 1 ; // Attribute part
197+ } else {
198+ color = attributes ; // Only one part (could be color, attribute, or position)
199199 }
200- if (attribute ) {
201- fossil_io_apply_attribute (attribute );
200+
201+ // Handle positions (like {pos:name})
202+ if (color && strncmp (color , "pos:" , 4 ) == 0 ) {
203+ pos = color + 4 ; // Skip the "pos:" prefix
204+ fossil_io_apply_position (pos );
205+ } else {
206+ // Apply color and/or attribute based on flags
207+ if (FOSSIL_IO_COLOR_ENABLE && color ) {
208+ fossil_io_apply_color (color );
209+ }
210+ if (attribute ) {
211+ fossil_io_apply_attribute (attribute );
212+ }
202213 }
203214 }
204215
@@ -212,15 +223,17 @@ void fossil_io_print_with_attributes(const char *str) {
212223 }
213224
214225 // Output remaining text after last '}'
215- fputs (current_pos , stdout );
226+ if (current_pos && * current_pos ) {
227+ fputs (current_pos , stdout );
228+ }
216229 fflush (stdout );
217230}
218231
219232// Function to print a sanitized formatted string to a specific file stream with attributes
220233void fossil_io_fprint_with_attributes (fossil_fstream_t * stream , const char * str ) {
221- if (str != NULL && stream != NULL ) {
234+ if (str != NULL && stream != NULL && stream -> file != NULL ) {
222235 char sanitized_str [FOSSIL_IO_BUFFER_SIZE ];
223- strncpy (sanitized_str , str , sizeof (sanitized_str ));
236+ strncpy (sanitized_str , str , sizeof (sanitized_str ) - 1 );
224237 sanitized_str [sizeof (sanitized_str ) - 1 ] = '\0' ; // Ensure null termination
225238
226239 // Remove attribute/color escape codes for file output
@@ -229,7 +242,10 @@ void fossil_io_fprint_with_attributes(fossil_fstream_t *stream, const char *str)
229242 const char * end = NULL ;
230243 while ((start = strchr (current_pos , '{' )) != NULL ) {
231244 // Write text before '{' to the file
232- fwrite (current_pos , 1 , start - current_pos , stream -> file );
245+ size_t len = start - current_pos ;
246+ if (len > 0 ) {
247+ fwrite (current_pos , 1 , len , stream -> file );
248+ }
233249 end = strchr (start , '}' );
234250 if (end ) {
235251 // Skip the attribute section
@@ -241,9 +257,9 @@ void fossil_io_fprint_with_attributes(fossil_fstream_t *stream, const char *str)
241257 }
242258 }
243259 // Write remaining text after last '}'
244- fputs (current_pos , stream -> file );
245- } else {
246- //fputs("cnullptr\n", stderr);
260+ if (current_pos && * current_pos ) {
261+ fputs ( current_pos , stream -> file );
262+ }
247263 }
248264}
249265
@@ -255,7 +271,7 @@ void fossil_io_fprint_with_attributes(fossil_fstream_t *stream, const char *str)
255271void fossil_io_puts (const char * str ) {
256272 if (str != NULL ) {
257273 char sanitized_str [FOSSIL_IO_BUFFER_SIZE ];
258- strncpy (sanitized_str , str , sizeof (sanitized_str ));
274+ strncpy (sanitized_str , str , sizeof (sanitized_str ) - 1 );
259275 sanitized_str [sizeof (sanitized_str ) - 1 ] = '\0' ; // Ensure null termination
260276
261277 // Print the sanitized string with attributes
@@ -272,24 +288,28 @@ void fossil_io_putchar(char c) {
272288
273289// Function to print sanitized formatted output with attributes
274290void fossil_io_printf (const char * format , ...) {
291+ if (!format ) return ;
292+
275293 va_list args ;
276294 va_start (args , format );
277295
278296 // Create a buffer to hold the formatted string
279297 char buffer [FOSSIL_IO_BUFFER_SIZE ];
280- vsnprintf (buffer , sizeof (buffer ), format , args );
281-
282- // Print the sanitized output with attributes
283- fossil_io_print_with_attributes (buffer );
298+ int result = vsnprintf (buffer , sizeof (buffer ), format , args );
299+
300+ if (result > 0 && result < (int )sizeof (buffer )) {
301+ // Print the sanitized output with attributes
302+ fossil_io_print_with_attributes (buffer );
303+ }
284304
285305 va_end (args );
286306}
287307
288308// Function to print a sanitized string to a specific file stream
289309void fossil_io_fputs (fossil_fstream_t * stream , const char * str ) {
290- if (str != NULL && stream != NULL ) {
310+ if (str != NULL && stream != NULL && stream -> file != NULL ) {
291311 char sanitized_str [FOSSIL_IO_BUFFER_SIZE ];
292- strncpy (sanitized_str , str , sizeof (sanitized_str ));
312+ strncpy (sanitized_str , str , sizeof (sanitized_str ) - 1 );
293313 sanitized_str [sizeof (sanitized_str ) - 1 ] = '\0' ; // Ensure null termination
294314
295315 // Apply color/attributes and sanitize the string before printing
@@ -301,15 +321,19 @@ void fossil_io_fputs(fossil_fstream_t *stream, const char *str) {
301321
302322// Function to print a sanitized formatted string to a specific file stream
303323void fossil_io_fprintf (fossil_fstream_t * stream , const char * format , ...) {
324+ if (!format || !stream || !stream -> file ) return ;
325+
304326 va_list args ;
305327 va_start (args , format );
306328
307329 // Create a buffer to hold the formatted string
308330 char buffer [FOSSIL_IO_BUFFER_SIZE ];
309- vsnprintf (buffer , sizeof (buffer ), format , args );
331+ int result = vsnprintf (buffer , sizeof (buffer ), format , args );
310332
311- // Print the sanitized formatted string with attributes to the specified stream
312- fossil_io_fprint_with_attributes (stream , buffer );
333+ if (result > 0 && result < (int )sizeof (buffer )) {
334+ // Print the sanitized formatted string with attributes to the specified stream
335+ fossil_io_fprint_with_attributes (stream , buffer );
336+ }
313337
314338 va_end (args );
315339}
0 commit comments