commit 365a71d9e5c52a661479a667481405575dd04e71
parent d7b559b96ee55c16fc9d97394d596e3288cd82cf
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 12 Aug 2025 16:52:48 +0200
Improve robustness of date conversion
Force the strptime function to parse all digits in the seconds field to
verify the total number of seconds provided, rather than just a portion.
Until now, strptime could stop parsing the input string as soon as it
determined that there were no more significant digits, as was the case,
for example, with "70". Once the character "7" was parsed, it would stop,
because no valid number of seconds starts with "7", except for the
integer 7.
The entire string is now parsed and an error is thrown if the number of
seconds is invalid compared to a minute. Note that 60 (and even 61)
remains a valid number of seconds for strptime, to handle leap seconds.
Diffstat:
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/smeteo_load.c b/src/smeteo_load.c
@@ -60,18 +60,27 @@ parse_time
/* Check memory space to build a string concatenating date and time */
ldate = strlen(date);
lhour = strlen(hour);
- if(ldate + lhour > sizeof(buf)+1/*NUL byte*/+1/*date/hour separator*/) {
+ if(ldate + lhour > sizeof(buf)+1/*NUL byte*/+1/*separator*/+1/*end char*/) {
res = RES_MEM_ERR;
goto error;
}
- /* Concatenate the data and time strings */
+ /* Concatenate the strings representing the date and time. End the string with
+ * a semicolon (;) to force sptrtime to parse all the digits of the seconds
+ * and not just the part that suits it, so that it returns an error if the
+ * number of seconds is actually invalid */
strcpy(buf, date);
buf[ldate] = 'T'; /* Separator between date and time */
strcpy(buf+ldate+1, hour);
-
- /* Convert time */
- if(!strptime(buf, "%d-%b-%YT%H:%M:%S", time)) {
+ buf[ldate+1/*separator*/+lhour] = ';'; /* end char */
+ buf[ldate+1/*separator*/+lhour+1] = '\0'; /* NUL char */
+
+ /* Note that strptime will not return an error with a number of seconds equal
+ * to 60 (and even 61 in some implementations of the C library). This allows
+ * for leap seconds, which occur occasionally to adjust the Earth's position.
+ * Don't try to outsmart strptime; trust it to check the validity of the time
+ * without adding any additional tests */
+ if(!strptime(buf, "%d-%b-%YT%H:%M:%S;", time)) {
res = RES_BAD_ARG;
goto error;
}