Skip to content

Commit 2ffe72b

Browse files
Make print methods in libnml/rcs/rcs_print.cc handle any size strings
Rewrite rcs_vprint(), rcs_print() and rcs_print_sys_error() to always print full string and drop use of static fixed size temp string. Also make sure trailing NUL is counted when copying strings into list of last errors. Set output limit to 2^16 to avoid any malloc bombs. This is the warning. Compiling libnml/rcs/rcs_print.cc In file included from /usr/include/string.h:495, from libnml/rcs/rcs_print.cc:21: In function ‘char* strncpy(char*, const char*, size_t)’, inlined from ‘int rcs_vprint(const char*, __va_list_tag*, int)’ at libnml/rcs/rcs_print.cc:311:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:34: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 99 bytes from a string of length 255 [-Wstringop-truncation] 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Compiling libnml/rcs/rcs_exit.cc
1 parent 4c34757 commit 2ffe72b

File tree

1 file changed

+93
-28
lines changed

1 file changed

+93
-28
lines changed

src/libnml/rcs/rcs_print.cc

Lines changed: 93 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ extern "C" {
3535
extern "C" double etime(void);
3636
#endif
3737

38+
#define MAX_PRINT_LINE (2^16)
39+
3840
LinkedList *rcs_print_list = NULL;
3941
char **rcs_lines_table = NULL;
4042
void (*rcs_print_notify) () = NULL;
@@ -287,15 +289,29 @@ int separate_words(char **_dest, int _max, char *_src)
287289

288290
int rcs_vprint(const char *_fmt, va_list _args, int save_string)
289291
{
290-
static char temp_string[256];
292+
char *temp_buffer = NULL;
293+
int retval;
294+
size_t size = 0;
295+
va_list argscopy;
291296

292297
if (NULL == _fmt) {
293298
return (EOF);
294299
}
295-
if (strlen(_fmt) > 200) { /* Might overflow temp_string. */
296-
return (EOF);
300+
/* Figure out string size */
301+
va_copy(argscopy, _args);
302+
size_t n = vsnprintf(temp_buffer, size, _fmt, argscopy);
303+
va_end(argscopy);
304+
if (n < 0 || MAX_PRINT_LINE <= n) { /* avoid malloc() bomb */
305+
return (EOF);
306+
}
307+
temp_buffer = (char*)malloc(n+1);
308+
if (!temp_buffer) {
309+
return (EOF);
297310
}
298-
if (EOF == (int) vsnprintf(temp_string, sizeof(temp_string), _fmt, _args)) {
311+
size = n + 1;
312+
313+
if (size != (size_t)vsnprintf(temp_buffer, size, _fmt, _args)) {
314+
free(temp_buffer);
299315
return (EOF);
300316
}
301317
if (save_string) {
@@ -308,9 +324,11 @@ int rcs_vprint(const char *_fmt, va_list _args, int save_string)
308324
}
309325
last_error_buf_filled++;
310326
last_error_buf_filled %= 4;
311-
strncpy(last_error_bufs[last_error_buf_filled], temp_string, 99);
327+
rtapi_strlcpy(last_error_bufs[last_error_buf_filled], temp_buffer, 100);
312328
}
313-
return (rcs_fputs(temp_string));
329+
retval = rcs_fputs(temp_buffer);
330+
free(temp_buffer);
331+
return (retval);
314332
}
315333

316334
int rcs_puts(const char *_str)
@@ -431,16 +449,36 @@ int set_rcs_print_file(char *_file_name)
431449

432450
int rcs_print(const char *_fmt, ...)
433451
{
434-
static char temp_buffer[400];
452+
char *temp_buffer = NULL;
435453
int retval;
436-
va_list args;
454+
va_list args, argscopy;
455+
size_t size = 0;
456+
457+
if (NULL == _fmt) {
458+
return (EOF);
459+
}
437460
va_start(args, _fmt);
438-
retval = vsnprintf(temp_buffer, sizeof(temp_buffer), _fmt, args);
461+
462+
/* Figure out string size */
463+
va_copy(argscopy, args);
464+
size_t n = vsnprintf(temp_buffer, size, _fmt, argscopy);
465+
va_end(argscopy);
466+
if (n < 0 || MAX_PRINT_LINE <= n) { /* avoid malloc() bomb */
467+
return (EOF);
468+
}
469+
temp_buffer = (char*)malloc(n+1);
470+
if (!temp_buffer) {
471+
return (EOF);
472+
}
473+
size = n + 1;
474+
retval = vsnprintf(temp_buffer, size, _fmt, args);
439475
va_end(args);
440-
if (retval == (EOF)) {
441-
return EOF;
476+
if (size != (size_t)retval) {
477+
free(temp_buffer);
478+
return (EOF);
442479
}
443480
retval = rcs_fputs(temp_buffer);
481+
free(temp_buffer);
444482
return (retval);
445483
}
446484

@@ -510,23 +548,34 @@ void clear_rcs_print_flag(long flag_to_clear)
510548

511549
int rcs_print_sys_error(int error_source, const char *_fmt, ...)
512550
{
513-
static char temp_string[256];
514-
static char message_string[512];
515-
va_list args;
516-
int r;
551+
static char *temp_buffer = NULL;
552+
static char *message_string = NULL;
553+
va_list args, argscopy;
554+
size_t size = 0;
555+
size_t msize = 0;
556+
int retval;
517557

518558
if (NULL == _fmt) {
519559
return (EOF);
520560
}
521-
if (strlen(_fmt) > 200) { /* Might overflow temp_string. */
522-
return (EOF);
523-
}
524-
525561
va_start(args, _fmt);
526-
r = vsnprintf(temp_string, sizeof(temp_string), _fmt, args);
562+
563+
/* Figure out string size */
564+
va_copy(argscopy, args);
565+
retval = vsnprintf(temp_buffer, size, _fmt, argscopy);
566+
va_end(argscopy);
567+
if (retval < 0 || MAX_PRINT_LINE <= retval) { /* avoid malloc() bomb */
568+
return (EOF);
569+
}
570+
temp_buffer = (char*)malloc(retval+1);
571+
if (!temp_buffer) {
572+
return (EOF);
573+
}
574+
size = retval + 1;
575+
retval = vsnprintf(temp_buffer, size, _fmt, args);
527576
va_end(args);
528577

529-
if (r < 0) {
578+
if (size != (size_t)retval) {
530579
return EOF;
531580
}
532581

@@ -537,22 +586,38 @@ int rcs_print_sys_error(int error_source, const char *_fmt, ...)
537586
rcs_errors_printed++;
538587
if (max_rcs_errors_to_print <= rcs_errors_printed &&
539588
max_rcs_errors_to_print >= 0) {
589+
free(temp_buffer);
540590
return (EOF);
541591
}
542592

543593
switch (error_source) {
544594
case ERRNO_ERROR_SOURCE:
545-
snprintf(message_string, sizeof(message_string),
546-
"%s %d %s\n", temp_string, errno,
547-
strerror(errno));
548-
rcs_puts(message_string);
549-
break;
595+
/* Figure out string size */
596+
retval = snprintf(message_string, msize,
597+
"%s %d %s\n", temp_buffer, errno, strerror(errno));
598+
if (retval < 0 || MAX_PRINT_LINE <= retval) { /* avoid malloc() bomb */
599+
return (EOF);
600+
}
601+
message_string = (char*)malloc(retval+1);
602+
if (!message_string) {
603+
return (EOF);
604+
}
605+
msize = retval + 1;
606+
retval = snprintf(message_string, msize,
607+
"%s %d %s\n", temp_buffer, errno, strerror(errno));
608+
if (msize != (size_t)retval) {
609+
return EOF;
610+
}
611+
rcs_puts(message_string);
612+
free(message_string);
613+
break;
550614

551615
default:
552-
rcs_puts(temp_string);
616+
rcs_puts(temp_buffer);
553617
break;
554618
}
555-
return (strlen(temp_string));
619+
free(temp_buffer);
620+
return (size - 1); /* string length without trailing NUL */
556621
}
557622

558623
#ifdef rcs_print_error

0 commit comments

Comments
 (0)