Skip to content

Commit

Permalink
cli: fix timestamp validation (#4356)
Browse files Browse the repository at this point in the history
* cli: fix timestamp validation

cli/src/cli-cmd-parser.c's config_parse was calling strftime
with a struct tm that may have tm_year that is out of range
for strftime, yielding unspecified and/or undefined behavior.
Fix this by using mktime instead of strftime, as mktime's
behavior is well-defined for out-of-range values.  This also
fixes a portability issue with strftime %s and time zones.

Fixes: #4355

Signed-off-by: Paul Eggert <[email protected]>

* cli: pass clang-format check

Adjust patch to pass clang-format.

Fixes: #4355

Signed-off-by: Paul Eggert <[email protected]>

* cli: fix off-by-one-hour error if DST

Don't tell mktime that standard time is in effect.
This fixes a bug where the timestamp is off by
an hour when daylight saving time is in effect.
(The issue is also present in the devel branch,
which uses strftime %s and which therefore
has the same bug.)

---------

Signed-off-by: Paul Eggert <[email protected]>
  • Loading branch information
eggert authored Oct 26, 2024
1 parent 595745f commit c164db3
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions cli/src/cli-cmd-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2524,7 +2524,7 @@ config_parse(const char **words, int wordcount, dict_t *dict, unsigned cmdi,
char *subop = NULL;
char *ret_chkpt = NULL;
struct tm checkpoint_time;
char chkpt_buf[20] = "";
time_t checkpoint_sec;

switch ((wordcount - 1) - cmdi) {
case 0:
Expand Down Expand Up @@ -2594,8 +2594,11 @@ config_parse(const char **words, int wordcount, dict_t *dict, unsigned cmdi,
memset(&checkpoint_time, 0, sizeof(struct tm));
ret_chkpt = strptime(append_str, "%Y-%m-%d %H:%M:%S",
&checkpoint_time);
checkpoint_time.tm_isdst = -1;
checkpoint_sec = mktime(&checkpoint_time);

if (ret_chkpt == NULL || *ret_chkpt != '\0') {
if (ret_chkpt == NULL || *ret_chkpt != '\0' ||
checkpoint_time.tm_mday == 0) {
ret = -1;
cli_err(
"Invalid Checkpoint label. Use format "
Expand All @@ -2608,8 +2611,7 @@ config_parse(const char **words, int wordcount, dict_t *dict, unsigned cmdi,
ret = -1;
goto out;
}
strftime(chkpt_buf, sizeof(chkpt_buf), "%s", &checkpoint_time);
snprintf(append_str, 300, "%s", chkpt_buf);
snprintf(append_str, 300, "%lld", (long long)checkpoint_sec);
}

ret = dict_set_dynstr(dict, "op_value", append_str);
Expand Down

0 comments on commit c164db3

Please sign in to comment.