From 9bcc1785c15a91e0f92039e03cd011079447b297 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 28 Jan 2021 06:15:31 +0000 Subject: [PATCH] epan: don't use gmtime_s(). It has the "feature" that, if handed a negative value, it might just exit. gmtime() doesn't have that "feature", and is sufficiently thread-safe for our purposes; use it instead, and check to make sure it doesn't return a null pointer. The previous fix for #17179 still used gmtime_s(); this doesn't, so it's a better fix for #17179. (cherry picked from commit bf265d7e7aa8c69841291a20ab9c9f5ac189135b) --- epan/print.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/epan/print.c b/epan/print.c index 51834f5859..a53a9693ff 100644 --- a/epan/print.c +++ b/epan/print.c @@ -1273,8 +1273,10 @@ ek_write_field_value(field_info *fi, write_json_data* pdata) gchar label_str[ITEM_LABEL_LENGTH]; char *dfilter_string; const nstime_t *t; + struct tm *tm; +#ifndef _WIN32 struct tm tm_time; - gboolean success; +#endif char time_string[sizeof("YYYY-MM-DDTHH:MM:SS")]; /* Text label */ @@ -1304,12 +1306,32 @@ ek_write_field_value(field_info *fi, write_json_data* pdata) case FT_ABSOLUTE_TIME: t = (const nstime_t *)fvalue_get(&fi->value); #ifdef _WIN32 - success = (gmtime_s(&tm_time, &t->secs) == 0); + /* + * Do not use gmtime_s(), as it will call and + * exception handler if the time we're providing + * is < 0, and that will, by default, exit. + * ("Programmers not bothering to check return + * values? Try new Microsoft Visual Studio, + * with Parameter Validation(R)! Kill insufficiently + * careful programs - *and* the processes running them - + * fast!") + * + * We just want to report this as an unrepresentable + * time. It fills in a per-thread structure, which + * is sufficiently thread-safe for our purposes. + */ + tm = gmtime(&t->secs); #else - success = (gmtime_r(&t->secs, &tm_time) != NULL); + /* + * Use gmtime_r(), because the Single UNIX Specification + * does *not* guarantee that gmtime() is thread-safe. + * Perhaps it is on all platforms on which we run, but + * this way we don't have to check. + */ + tm = gmtime_r(&t->secs, &tm_time); #endif - if (success) { - strftime(time_string, sizeof(time_string), "%FT%T", &tm_time); + if (tm != NULL) { + strftime(time_string, sizeof(time_string), "%FT%T", tm); } else { g_snprintf(time_string, sizeof(time_string), "Not representable"); }