Skip to content

Commit

Permalink
Make print methods in libnml/rcs/rcs_print.cc handle any size strings
Browse files Browse the repository at this point in the history
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
  • Loading branch information
petterreinholdtsen committed Aug 16, 2022
1 parent 4c34757 commit 2ffe72b
Showing 1 changed file with 93 additions and 28 deletions.
121 changes: 93 additions & 28 deletions src/libnml/rcs/rcs_print.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ extern "C" {
extern "C" double etime(void);
#endif

#define MAX_PRINT_LINE (2^16)

LinkedList *rcs_print_list = NULL;
char **rcs_lines_table = NULL;
void (*rcs_print_notify) () = NULL;
Expand Down Expand Up @@ -287,15 +289,29 @@ int separate_words(char **_dest, int _max, char *_src)

int rcs_vprint(const char *_fmt, va_list _args, int save_string)
{
static char temp_string[256];
char *temp_buffer = NULL;
int retval;
size_t size = 0;
va_list argscopy;

if (NULL == _fmt) {
return (EOF);
}
if (strlen(_fmt) > 200) { /* Might overflow temp_string. */
return (EOF);
/* Figure out string size */
va_copy(argscopy, _args);
size_t n = vsnprintf(temp_buffer, size, _fmt, argscopy);
va_end(argscopy);
if (n < 0 || MAX_PRINT_LINE <= n) { /* avoid malloc() bomb */
return (EOF);
}
temp_buffer = (char*)malloc(n+1);
if (!temp_buffer) {
return (EOF);
}
if (EOF == (int) vsnprintf(temp_string, sizeof(temp_string), _fmt, _args)) {
size = n + 1;

if (size != (size_t)vsnprintf(temp_buffer, size, _fmt, _args)) {
free(temp_buffer);
return (EOF);
}
if (save_string) {
Expand All @@ -308,9 +324,11 @@ int rcs_vprint(const char *_fmt, va_list _args, int save_string)
}
last_error_buf_filled++;
last_error_buf_filled %= 4;
strncpy(last_error_bufs[last_error_buf_filled], temp_string, 99);
rtapi_strlcpy(last_error_bufs[last_error_buf_filled], temp_buffer, 100);
}
return (rcs_fputs(temp_string));
retval = rcs_fputs(temp_buffer);
free(temp_buffer);
return (retval);
}

int rcs_puts(const char *_str)
Expand Down Expand Up @@ -431,16 +449,36 @@ int set_rcs_print_file(char *_file_name)

int rcs_print(const char *_fmt, ...)
{
static char temp_buffer[400];
char *temp_buffer = NULL;
int retval;
va_list args;
va_list args, argscopy;
size_t size = 0;

if (NULL == _fmt) {
return (EOF);
}
va_start(args, _fmt);
retval = vsnprintf(temp_buffer, sizeof(temp_buffer), _fmt, args);

/* Figure out string size */
va_copy(argscopy, args);
size_t n = vsnprintf(temp_buffer, size, _fmt, argscopy);
va_end(argscopy);
if (n < 0 || MAX_PRINT_LINE <= n) { /* avoid malloc() bomb */
return (EOF);
}
temp_buffer = (char*)malloc(n+1);
if (!temp_buffer) {
return (EOF);
}
size = n + 1;
retval = vsnprintf(temp_buffer, size, _fmt, args);
va_end(args);
if (retval == (EOF)) {
return EOF;
if (size != (size_t)retval) {
free(temp_buffer);
return (EOF);
}
retval = rcs_fputs(temp_buffer);
free(temp_buffer);
return (retval);
}

Expand Down Expand Up @@ -510,23 +548,34 @@ void clear_rcs_print_flag(long flag_to_clear)

int rcs_print_sys_error(int error_source, const char *_fmt, ...)
{
static char temp_string[256];
static char message_string[512];
va_list args;
int r;
static char *temp_buffer = NULL;
static char *message_string = NULL;
va_list args, argscopy;
size_t size = 0;
size_t msize = 0;
int retval;

if (NULL == _fmt) {
return (EOF);
}
if (strlen(_fmt) > 200) { /* Might overflow temp_string. */
return (EOF);
}

va_start(args, _fmt);
r = vsnprintf(temp_string, sizeof(temp_string), _fmt, args);

/* Figure out string size */
va_copy(argscopy, args);
retval = vsnprintf(temp_buffer, size, _fmt, argscopy);
va_end(argscopy);
if (retval < 0 || MAX_PRINT_LINE <= retval) { /* avoid malloc() bomb */
return (EOF);
}
temp_buffer = (char*)malloc(retval+1);
if (!temp_buffer) {
return (EOF);
}
size = retval + 1;
retval = vsnprintf(temp_buffer, size, _fmt, args);
va_end(args);

if (r < 0) {
if (size != (size_t)retval) {
return EOF;
}

Expand All @@ -537,22 +586,38 @@ int rcs_print_sys_error(int error_source, const char *_fmt, ...)
rcs_errors_printed++;
if (max_rcs_errors_to_print <= rcs_errors_printed &&
max_rcs_errors_to_print >= 0) {
free(temp_buffer);
return (EOF);
}

switch (error_source) {
case ERRNO_ERROR_SOURCE:
snprintf(message_string, sizeof(message_string),
"%s %d %s\n", temp_string, errno,
strerror(errno));
rcs_puts(message_string);
break;
/* Figure out string size */
retval = snprintf(message_string, msize,
"%s %d %s\n", temp_buffer, errno, strerror(errno));
if (retval < 0 || MAX_PRINT_LINE <= retval) { /* avoid malloc() bomb */
return (EOF);
}
message_string = (char*)malloc(retval+1);
if (!message_string) {
return (EOF);
}
msize = retval + 1;
retval = snprintf(message_string, msize,
"%s %d %s\n", temp_buffer, errno, strerror(errno));
if (msize != (size_t)retval) {
return EOF;
}
rcs_puts(message_string);
free(message_string);
break;

default:
rcs_puts(temp_string);
rcs_puts(temp_buffer);
break;
}
return (strlen(temp_string));
free(temp_buffer);
return (size - 1); /* string length without trailing NUL */
}

#ifdef rcs_print_error
Expand Down

0 comments on commit 2ffe72b

Please sign in to comment.