diff --git a/asc2log.c b/asc2log.c index fbbb01b..5ffc1be 100644 --- a/asc2log.c +++ b/asc2log.c @@ -82,7 +82,7 @@ void prframe(FILE *file, struct timeval *tv, int dev, struct canfd_frame *cf, ch else fprintf(file, "canX "); - sprint_canframe(abuf, (cu_t *)cf, 0); + snprintf_canframe(abuf, sizeof(abuf), (cu_t *)cf, 0); fprintf(file, "%s%s", abuf, extra_info); } diff --git a/candump.c b/candump.c index 87958cd..2c57b8d 100644 --- a/candump.c +++ b/candump.c @@ -837,7 +837,7 @@ int main(int argc, char **argv) alen += sprintf(afrbuf + alen, "%*s ", max_devname_len, devname[idx]); - alen += sprint_canframe(afrbuf + alen, &cu, 0); + alen += snprintf_canframe(afrbuf + alen, sizeof(afrbuf) - alen, &cu, 0); } /* write CAN frame in log file style to logfile */ @@ -876,7 +876,7 @@ int main(int argc, char **argv) } alen += sprintf(afrbuf + alen, "%s ", (color == 1) ? col_off : ""); - alen += sprint_long_canframe(afrbuf + alen, &cu, view); + alen += snprintf_long_canframe(afrbuf + alen, sizeof(afrbuf) - alen, &cu, view); if ((view & CANLIB_VIEW_ERROR) && (cu.fd.can_id & CAN_ERR_FLAG)) { alen += sprintf(afrbuf + alen, "\n\t"); diff --git a/cangen.c b/cangen.c index 0e5ec8d..4e27261 100644 --- a/cangen.c +++ b/cangen.c @@ -1009,9 +1009,9 @@ int main(int argc, char **argv) printf(" %s ", argv[optind]); if (verbose > 1) - sprint_long_canframe(afrbuf, &cu, view); + snprintf_long_canframe(afrbuf, sizeof(afrbuf), &cu, view); else - sprint_canframe(afrbuf, &cu, 1); + snprintf_canframe(afrbuf, sizeof(afrbuf), &cu, 1); printf("%s\n", afrbuf); } diff --git a/canlogserver.c b/canlogserver.c index ca900ef..1921e23 100644 --- a/canlogserver.c +++ b/canlogserver.c @@ -439,7 +439,7 @@ int main(int argc, char **argv) sprintf(afrbuf, "(%llu.%06llu) %*s ", (unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec, max_devname_len, devname[idx]); - sprint_canframe(afrbuf+strlen(afrbuf), &cu, 0); + snprintf_canframe(afrbuf + strlen(afrbuf), sizeof(afrbuf) - strlen(afrbuf), &cu, 0); strcat(afrbuf, "\n"); if (write(accsocket, afrbuf, strlen(afrbuf)) < 0) { diff --git a/canplayer.c b/canplayer.c index a38a82a..dfd1919 100644 --- a/canplayer.c +++ b/canplayer.c @@ -513,7 +513,7 @@ int main(int argc, char **argv) if (verbose) { printf("%s (%s) ", get_txname(device), device); - sprint_long_canframe(afrbuf, &cu, CANLIB_VIEW_INDENT_SFF); + snprintf_long_canframe(afrbuf, sizeof(afrbuf), &cu, CANLIB_VIEW_INDENT_SFF); printf("%s\n", afrbuf); } diff --git a/lib.c b/lib.c index bd8d3cf..1c2ec0c 100644 --- a/lib.c +++ b/lib.c @@ -308,7 +308,7 @@ int parse_canframe(char *cs, cu_t *cu) return mtu; } -int sprint_canframe(char *buf, cu_t *cu, int sep) +int snprintf_canframe(char *buf, size_t size, cu_t *cu, int sep) { /* documentation see lib.h */ @@ -316,10 +316,22 @@ int sprint_canframe(char *buf, cu_t *cu, int sep) int i, offset; int len; + /* ensure space for string termination */ + if (size < 1) + return size; + /* handle CAN XL frames */ if (cu->xl.flags & CANXL_XLF) { len = cu->xl.len; + /* check if the CAN frame fits into the provided buffer */ + if (sizeof("00123#11:22:12345678#") + 2 * len + (sep ? len : 0) > size - 1) { + /* mark buffer overflow in output */ + memset(buf, '-', size - 1); + buf[size - 1] = 0; + return size; + } + /* print prio and CAN XL header content */ offset = sprintf(buf, "%02X%03X#%02X:%02X:%08X#", (canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET, @@ -345,6 +357,15 @@ int sprint_canframe(char *buf, cu_t *cu, int sep) else len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len; + /* check if the CAN frame fits into the provided buffer */ + if (sizeof("12345678#_F") + 2 * len + (sep ? len : 0) + \ + (cu->fd.can_id & CAN_RTR_FLAG ? 2 : 0) > size - 1) { + /* mark buffer overflow in output */ + memset(buf, '-', size - 1); + buf[size - 1] = 0; + return size; + } + if (cu->fd.can_id & CAN_ERR_FLAG) { put_eff_id(buf, cu->fd.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG)); buf[8] = '#'; @@ -411,48 +432,60 @@ int sprint_canframe(char *buf, cu_t *cu, int sep) return offset; } -int sprint_long_canframe(char *buf, cu_t *cu, int view) +int snprintf_long_canframe(char *buf, size_t size, cu_t *cu, int view) { /* documentation see lib.h */ unsigned char is_canfd = cu->fd.flags; - int i, j, dlen, offset; + int i, j, dlen, offset, maxsize; int len; - /* initialize space for CAN-ID and length information */ - memset(buf, ' ', 15); + /* ensure space for string termination */ + if (size < 1) + return size; /* handle CAN XL frames */ if (cu->xl.flags & CANXL_XLF) { len = cu->xl.len; + /* crop to CANFD_MAX_DLEN */ + if (len > CANFD_MAX_DLEN) + dlen = CANFD_MAX_DLEN; + else + dlen = len; + + /* check if the CAN frame fits into the provided buffer */ + if (sizeof(".....123 [2048] (00|11:22:12345678) ...") + 3 * dlen > size - 1) { + /* mark buffer overflow in output */ + memset(buf, '-', size - 1); + buf[size - 1] = 0; + return size; + } + if (view & CANLIB_VIEW_INDENT_SFF) { + memset(buf, ' ', 5); put_sff_id(buf + 5, cu->xl.prio & CANXL_PRIO_MASK); - offset = 9; + offset = 8; } else { put_sff_id(buf, cu->xl.prio & CANXL_PRIO_MASK); - offset = 4; + offset = 3; } /* print prio and CAN XL header content */ - offset += sprintf(buf + offset, "[%04d] (%02X|%02X:%02X:%08X) ", + offset += sprintf(buf + offset, " [%04d] (%02X|%02X:%02X:%08X) ", len, (canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET, cu->xl.flags, cu->xl.sdt, cu->xl.af); - /* data - crop to CANFD_MAX_DLEN */ - if (len > CANFD_MAX_DLEN) - len = CANFD_MAX_DLEN; - - for (i = 0; i < len; i++) { + for (i = 0; i < dlen; i++) { put_hex_byte(buf + offset, cu->xl.data[i]); offset += 2; - if (i + 1 < len) + if (i + 1 < dlen) buf[offset++] = ' '; } /* indicate cropped output */ - if (cu->xl.len > len) + if (cu->xl.len > dlen) offset += sprintf(buf + offset, " ..."); buf[offset] = 0; @@ -466,6 +499,39 @@ int sprint_long_canframe(char *buf, cu_t *cu, int view) else len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len; + /* check if the CAN frame fits into the provided buffer */ + maxsize = sizeof("12345678 [12] "); + if (view & CANLIB_VIEW_BINARY) + dlen = 9; /* _10101010 */ + else + dlen = 3; /* _AA */ + + if (cu->fd.can_id & CAN_RTR_FLAG) { + maxsize += sizeof(" remote request"); + } else { + maxsize += len * dlen; + + if (len <= CAN_MAX_DLEN) { + if (cu->fd.can_id & CAN_ERR_FLAG) { + maxsize += sizeof(" ERRORFRAME"); + maxsize += (8 - len) * dlen; + } else if (view & CANLIB_VIEW_ASCII) { + maxsize += sizeof(" 'a.b.CDEF'"); + maxsize += (8 - len) * dlen; + } + } + } + + if (maxsize > size - 1) { + /* mark buffer overflow in output */ + memset(buf, '-', size - 1); + buf[size - 1] = 0; + return size; + } + + /* initialize space for CAN-ID and length information */ + memset(buf, ' ', 15); + if (cu->cc.can_id & CAN_ERR_FLAG) { put_eff_id(buf, cu->cc.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG)); offset = 10; @@ -515,7 +581,7 @@ int sprint_long_canframe(char *buf, cu_t *cu, int view) offset += 5; if (view & CANLIB_VIEW_BINARY) { - dlen = 9; /* _10101010 */ + /* _10101010 - dlen = 9, see above */ if (view & CANLIB_VIEW_SWAP) { for (i = len - 1; i >= 0; i--) { buf[offset++] = (i == len - 1) ? ' ' : SWAP_DELIMITER; @@ -530,7 +596,7 @@ int sprint_long_canframe(char *buf, cu_t *cu, int view) } } } else { - dlen = 3; /* _AA */ + /* _AA - dlen = 3, see above */ if (view & CANLIB_VIEW_SWAP) { for (i = len - 1; i >= 0; i--) { if (i == len - 1) diff --git a/lib.h b/lib.h index 23514c7..1ab0324 100644 --- a/lib.h +++ b/lib.h @@ -178,7 +178,7 @@ int parse_canframe(char *cs, cu_t *cu); * - CAN FD frames do not have a RTR bit */ -int sprint_canframe(char *buf , cu_t *cu, int sep); +int snprintf_canframe(char *buf, size_t size, cu_t *cu, int sep); /* * Creates a CAN frame hexadecimal output in compact format. * The CAN data[] is separated by '.' when sep != 0. @@ -211,7 +211,7 @@ int sprint_canframe(char *buf , cu_t *cu, int sep); #define SWAP_DELIMITER '`' -int sprint_long_canframe(char *buf , cu_t *cu, int view); +int snprintf_long_canframe(char *buf, size_t size, cu_t *cu, int view); /* * Creates a CAN frame hexadecimal output in user readable format. * diff --git a/log2long.c b/log2long.c index 731d29a..301f201 100644 --- a/log2long.c +++ b/log2long.c @@ -94,8 +94,8 @@ int main(void) } /* with ASCII output */ - sprint_long_canframe(afrbuf, &cu, - (CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII)); + snprintf_long_canframe(afrbuf, sizeof(afrbuf), &cu, + (CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII)); printf("%s %s %s\n", timestamp, device, afrbuf); }