aboutsummaryrefslogtreecommitdiffstats
path: root/capinfos.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2020-04-29 11:24:45 -0700
committerGuy Harris <gharris@sonic.net>2020-04-29 19:11:16 +0000
commit928bbf5984ee8b81e960c3d53c1d8d2e1bc2bdbf (patch)
tree4c948417cd1e6b97e9761a21f460a2987c21d108 /capinfos.c
parent0eb92d7aa0fca23cafb675f6140861206ba48101 (diff)
capinfos: fix absolute and relative time display.
Make the buffers big enough to handle the largest possible time values you can get with a 64-bit time_t. Don't cast the seconds value to unsigned long; it's probably signed, and may not fit in an unsigned long (64-bit on an ILP32 or LLP64 platform), so cast it to gint64 and print using G_GINT64_MODIFIER followed by "d". Bug: 16519 Change-Id: I3ab79dfa086d2c4dfb6b93eba8cef3bdce731731 Reviewed-on: https://code.wireshark.org/review/36971 Petri-Dish: Guy Harris <gharris@sonic.net> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <gharris@sonic.net>
Diffstat (limited to 'capinfos.c')
-rw-r--r--capinfos.c91
1 files changed, 65 insertions, 26 deletions
diff --git a/capinfos.c b/capinfos.c
index 03a5d4007c..d842f786fe 100644
--- a/capinfos.c
+++ b/capinfos.c
@@ -300,7 +300,37 @@ order_string(order_t order)
static gchar *
absolute_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info)
{
- static gchar time_string_buf[4+1+2+1+2+1+2+1+2+1+2+1+9+1+1];
+ /*
+ * https://web.archive.org/web/20120513133703/http://www.idrbt.ac.in/publications/workingpapers/Working%20Paper%20No.%209.pdf
+ *
+ * says:
+ *
+ * A 64-bit Unix time would be safe for the indefinite future, as
+ * this variable would not overflow until 2**63 or
+ * 9,223,372,036,854,775,808 (over nine quintillion) seconds
+ * after the beginning of the Unix epoch - corresponding to
+ * GMT 15:30:08, Sunday, 4th December, 292,277,026,596.
+ *
+ * So, if we're displaying the time as YYYY-MM-DD HH:MM:SS.SSSSSSSSS,
+ * we'll have the buffer be large enouth for a date of the format
+ * 292277026596-MM-DD HH:MM:SS.SSSSSSSSS, which is the biggest value
+ * you'll get with a 64-bit time_t and a nanosecond-resolution
+ * fraction-of-a-second.
+ *
+ * That's 12+1+2+1+2+1+2+1+2+2+2+1+9+1, including the terminating
+ * \0, or 39.
+ *
+ * If we're displaying the time as epoch time, and the time is
+ * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
+ * to be big enough for 18446744073709551615.999999999. That's
+ * 20+1+9+1, including the terminating '\0', or 31. If it's
+ * signed, 2^63 is 9223372036854775808, so the buffer has to
+ * be big enough for -9223372036854775808.999999999, which is
+ * again 20+1+9+1, or 31.
+ *
+ * So we go with 39.
+ */
+ static gchar time_string_buf[39];
struct tm *ti_tm;
if (cf_info->times_known && cf_info->packet_count > 0) {
@@ -309,46 +339,46 @@ absolute_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info)
case WTAP_TSPREC_SEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu",
- (unsigned long)timer->secs);
+ "%"G_GINT64_MODIFIER"d",
+ (gint64)timer->secs);
break;
case WTAP_TSPREC_DSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%01d",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%01d",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 100000000);
break;
case WTAP_TSPREC_CSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%02d",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%02d",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 10000000);
break;
case WTAP_TSPREC_MSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%03d",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%03d",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 1000000);
break;
case WTAP_TSPREC_USEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%06d",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%06d",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 1000);
break;
case WTAP_TSPREC_NSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%09d",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%09d",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs);
break;
@@ -463,23 +493,32 @@ relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gb
{
const gchar *second = want_seconds ? " second" : "";
const gchar *plural = want_seconds ? "s" : "";
- static gchar time_string_buf[4+1+2+1+2+1+2+1+2+1+2+1+1];
+ /*
+ * If we're displaying the time as epoch time, and the time is
+ * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
+ * to be big enough for "18446744073709551615.999999999 seconds".
+ * That's 20+1+9+1+7+1, including the terminating '\0', or 39.
+ * If it'ssigned, 2^63 is 9223372036854775808, so the buffer has to
+ * be big enough for "-9223372036854775808.999999999 seconds",
+ * which is again 20+1+9+1+7+1, or 39.
+ */
+ static gchar time_string_buf[39];
if (cf_info->times_known && cf_info->packet_count > 0) {
switch (tsprecision) {
case WTAP_TSPREC_SEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%s",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%s",
+ (gint64)timer->secs,
second,
timer->secs == 1 ? "" : plural);
break;
case WTAP_TSPREC_DSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%01d%s%s",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%01d%s%s",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 100000000,
second,
@@ -488,8 +527,8 @@ relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gb
case WTAP_TSPREC_CSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%02d%s%s",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%02d%s%s",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 10000000,
second,
@@ -498,8 +537,8 @@ relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gb
case WTAP_TSPREC_MSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%03d%s%s",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%03d%s%s",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 1000000,
second,
@@ -508,8 +547,8 @@ relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gb
case WTAP_TSPREC_USEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%06d%s%s",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%06d%s%s",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs / 1000,
second,
@@ -518,8 +557,8 @@ relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gb
case WTAP_TSPREC_NSEC:
g_snprintf(time_string_buf, sizeof time_string_buf,
- "%lu%s%09d%s%s",
- (unsigned long)timer->secs,
+ "%"G_GINT64_MODIFIER"d%s%09d%s%s",
+ (gint64)timer->secs,
decimal_point,
timer->nsecs,
second,