lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



mktime() is a function to calculate the number of seconds *since* the epoch. Note the *since*.

Since mktime() returns -1 to signal an error and the last second of 1969 (which is -1 seconds from the epoch) returns the same value that is otherwise used to signal an error, the program misinterprets the result.

In consequence, when mktime() returns -1, you probably should take a look at errno (in C code), as mktime() sets errno accordingly.

This is a bug in Lua, or, rather in its use of mktime().

To properly catch this cornercase, clear errno prior to the call of mktime() and check it afterwards:

--- loslib.c.orig 2022-02-12 13:57:14.000000000 +0100
+++ loslib.c 2022-02-12 14:02:57.000000000 +0100
@@ -358,10 +358,11 @@
     ts.tm_min = getfield(L, "min", 0, 0);
     ts.tm_sec = getfield(L, "sec", 0, 0);
     ts.tm_isdst = getboolfield(L, "isdst");
+    errno = 0;
     t = mktime(&ts);
     setallfields(L, &ts);  /* update fields with normalized values */
   }
-  if (t != (time_t)(l_timet)t || t == (time_t)(-1))
+  if ((t != (time_t)(l_timet)t || t == (time_t)(-1)) && errno != 0)
     return luaL_error(L,
                   "time result cannot be represented in this installation");
   l_pushtime(L, t);

(Clearing errno before mktime() is important, since it may still contain a non-zero value from a previous error).