X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/d07e352f5a8a9cbf7e8f3ed49a316ed906353fd8..2d02497b02b040bd885825dba9230f86a8ffce0e:/util-print.c diff --git a/util-print.c b/util-print.c index 0b4f055b..90e11b9f 100644 --- a/util-print.c +++ b/util-print.c @@ -21,7 +21,7 @@ /* * txtproto_print() derived from original code by Hannes Gredler - * (hannes@juniper.net): + * (hannes@gredler.at): * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code @@ -387,15 +387,14 @@ ts_print(netdissect_options *ndo, } /* - * Print a signed relative number of seconds (e.g. hold time, prune timer) + * Print an unsigned relative number of seconds (e.g. hold time, prune timer) * in the form 5m1s. This does no truncation, so 32230861 seconds * is represented as 1y1w1d1h1m1s. */ void -signed_relts_print(netdissect_options *ndo, - int32_t secs) +unsigned_relts_print(netdissect_options *ndo, + uint32_t secs) { - uint32_t secs_abs; static const char *lengths[] = {"y", "w", "d", "h", "m", "s"}; static const u_int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; const char **l = lengths; @@ -405,28 +404,10 @@ signed_relts_print(netdissect_options *ndo, ND_PRINT((ndo, "0s")); return; } - if (secs == -2147483648) { - /* - * -2^31; you can't fit its absolute value into a 32-bit - * signed integer. - * - * We calculate the right string by hand. - */ - ND_PRINT((ndo, "-68y5w3h14m8s")); - return; - } - if (secs < 0) { - /* - * We now know -secs will fit into secs. - */ - ND_PRINT((ndo, "-")); - secs = -secs; - } - secs_abs = secs; - while (secs_abs > 0) { - if (secs_abs >= *s) { - ND_PRINT((ndo, "%d%s", secs_abs / *s, *l)); - secs_abs -= (secs_abs / *s) * *s; + while (secs > 0) { + if (secs >= *s) { + ND_PRINT((ndo, "%d%s", secs / *s, *l)); + secs -= (secs / *s) * *s; } s++; l++; @@ -434,31 +415,39 @@ signed_relts_print(netdissect_options *ndo, } /* - * Print an unsigned relative number of seconds (e.g. hold time, prune timer) + * Print a signed relative number of seconds (e.g. hold time, prune timer) * in the form 5m1s. This does no truncation, so 32230861 seconds * is represented as 1y1w1d1h1m1s. */ void -unsigned_relts_print(netdissect_options *ndo, - uint32_t secs) +signed_relts_print(netdissect_options *ndo, + int32_t secs) { - static const char *lengths[] = {"y", "w", "d", "h", "m", "s"}; - static const u_int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; - const char **l = lengths; - const u_int *s = seconds; - - if (secs == 0) { - ND_PRINT((ndo, "0s")); - return; - } - while (secs > 0) { - if (secs >= *s) { - ND_PRINT((ndo, "%d%s", secs / *s, *l)); - secs -= (secs / *s) * *s; + if (secs < 0) { + ND_PRINT((ndo, "-")); + if (secs == INT32_MIN) { + /* + * -2^31; you can't fit its absolute value into + * a 32-bit signed integer. + * + * Just directly pass said absolute value to + * unsigned_relts_print() directly. + * + * (XXX - does ISO C guarantee that -(-2^n), + * when calculated and cast to an n-bit unsigned + * integer type, will have the value 2^n?) + */ + unsigned_relts_print(ndo, 2147483648U); + } else { + /* + * We now know -secs will fit into an int32_t; + * negate it and pass that to unsigned_relts_print(). + */ + unsigned_relts_print(ndo, -secs); } - s++; - l++; + return; } + unsigned_relts_print(ndo, secs); } /* @@ -532,8 +521,9 @@ static char * bittok2str_internal(register const struct tok *lp, register const char *fmt, register u_int v, const char *sep) { - static char buf[256]; /* our stringbuffer */ - int buflen=0; + static char buf[1024+1]; /* our string buffer */ + char *bufp = buf; + size_t space_left = sizeof(buf), string_size; register u_int rotbit; /* this is the bit we rotate through all bitpositions */ register u_int tokval; const char * sepstr = ""; @@ -548,8 +538,20 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, */ if (tokval == (v&rotbit)) { /* ok we have found something */ - buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", - sepstr, lp->s); + if (space_left <= 1) + return (buf); /* only enough room left for NUL, if that */ + string_size = strlcpy(bufp, sepstr, space_left); + if (string_size >= space_left) + return (buf); /* we ran out of room */ + bufp += string_size; + space_left -= string_size; + if (space_left <= 1) + return (buf); /* only enough room left for NUL, if that */ + string_size = strlcpy(bufp, lp->s, space_left); + if (string_size >= space_left) + return (buf); /* we ran out of room */ + bufp += string_size; + space_left -= string_size; sepstr = sep; break; } @@ -558,7 +560,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, lp++; } - if (buflen == 0) + if (bufp == buf) /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v); return (buf); @@ -913,7 +915,7 @@ safeputs(netdissect_options *ndo, { u_int idx = 0; - while (*s && idx < maxlen) { + while (idx < maxlen && *s) { safeputchar(ndo, *s); idx++; s++;