aboutsummaryrefslogtreecommitdiff
path: root/loslib.c
diff options
context:
space:
mode:
Diffstat (limited to 'loslib.c')
-rw-r--r--loslib.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/loslib.c b/loslib.c
index bf436b81..eb444bb2 100644
--- a/loslib.c
+++ b/loslib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loslib.c,v 1.56 2015/02/09 17:41:54 roberto Exp roberto $ 2** $Id: loslib.c,v 1.57 2015/04/10 17:41:04 roberto Exp roberto $
3** Standard Operating System library 3** Standard Operating System library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -54,7 +54,12 @@
54*/ 54*/
55#define l_timet lua_Integer 55#define l_timet lua_Integer
56#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) 56#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t))
57#define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a)) 57
58static time_t l_checktime (lua_State *L, int arg) {
59 lua_Integer t = luaL_checkinteger(L, arg);
60 luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds");
61 return (time_t)t;
62}
58 63
59#endif /* } */ 64#endif /* } */
60 65
@@ -198,17 +203,29 @@ static int getboolfield (lua_State *L, const char *key) {
198} 203}
199 204
200 205
201static int getfield (lua_State *L, const char *key, int d) { 206/* maximum value for date fields (to avoid arithmetic overflows with 'int') */
202 int res, isnum; 207#if !defined(L_MAXDATEFIELD)
203 lua_getfield(L, -1, key); 208#define L_MAXDATEFIELD (INT_MAX / 2)
204 res = (int)lua_tointegerx(L, -1, &isnum); 209#endif
205 if (!isnum) { 210
206 if (d < 0) 211static int getfield (lua_State *L, const char *key, int d, int delta) {
212 int isnum;
213 int t = lua_getfield(L, -1, key);
214 lua_Integer res = lua_tointegerx(L, -1, &isnum);
215 if (!isnum) { /* field is not a number? */
216 if (t != LUA_TNIL) /* some other value? */
217 return luaL_error(L, "field '%s' not an integer", key);
218 else if (d < 0) /* abssent field; no default? */
207 return luaL_error(L, "field '%s' missing in date table", key); 219 return luaL_error(L, "field '%s' missing in date table", key);
208 res = d; 220 res = d;
209 } 221 }
222 else {
223 if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
224 return luaL_error(L, "field '%s' out-of-bounds", key);
225 res -= delta;
226 }
210 lua_pop(L, 1); 227 lua_pop(L, 1);
211 return res; 228 return (int)res;
212} 229}
213 230
214 231
@@ -247,8 +264,8 @@ static int os_date (lua_State *L) {
247 else 264 else
248 stm = l_localtime(&t, &tmr); 265 stm = l_localtime(&t, &tmr);
249 if (stm == NULL) /* invalid date? */ 266 if (stm == NULL) /* invalid date? */
250 lua_pushnil(L); 267 luaL_error(L, "time result cannot be represented in this installation");
251 else if (strcmp(s, "*t") == 0) { 268 if (strcmp(s, "*t") == 0) {
252 lua_createtable(L, 0, 9); /* 9 = number of fields */ 269 lua_createtable(L, 0, 9); /* 9 = number of fields */
253 setfield(L, "sec", stm->tm_sec); 270 setfield(L, "sec", stm->tm_sec);
254 setfield(L, "min", stm->tm_min); 271 setfield(L, "min", stm->tm_min);
@@ -290,21 +307,18 @@ static int os_time (lua_State *L) {
290 struct tm ts; 307 struct tm ts;
291 luaL_checktype(L, 1, LUA_TTABLE); 308 luaL_checktype(L, 1, LUA_TTABLE);
292 lua_settop(L, 1); /* make sure table is at the top */ 309 lua_settop(L, 1); /* make sure table is at the top */
293 ts.tm_sec = getfield(L, "sec", 0); 310 ts.tm_sec = getfield(L, "sec", 0, 0);
294 ts.tm_min = getfield(L, "min", 0); 311 ts.tm_min = getfield(L, "min", 0, 0);
295 ts.tm_hour = getfield(L, "hour", 12); 312 ts.tm_hour = getfield(L, "hour", 12, 0);
296 ts.tm_mday = getfield(L, "day", -1); 313 ts.tm_mday = getfield(L, "day", -1, 0);
297 ts.tm_mon = getfield(L, "month", -1) - 1; 314 ts.tm_mon = getfield(L, "month", -1, 1);
298 ts.tm_year = getfield(L, "year", -1) - 1900; 315 ts.tm_year = getfield(L, "year", -1, 1900);
299 ts.tm_isdst = getboolfield(L, "isdst"); 316 ts.tm_isdst = getboolfield(L, "isdst");
300 t = mktime(&ts); 317 t = mktime(&ts);
301 } 318 }
302 if (t != (time_t)(l_timet)t) 319 if (t != (time_t)(l_timet)t || t == (time_t)(-1))
303 luaL_error(L, "time result cannot be represented in this Lua installation"); 320 luaL_error(L, "time result cannot be represented in this installation");
304 else if (t == (time_t)(-1)) 321 l_pushtime(L, t);
305 lua_pushnil(L);
306 else
307 l_pushtime(L, t);
308 return 1; 322 return 1;
309} 323}
310 324