summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--loslib.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/loslib.c b/loslib.c
index 4563d2e0..dd2bb378 100644
--- a/loslib.c
+++ b/loslib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loslib.c,v 1.63 2016/02/09 12:16:11 roberto Exp roberto $ 2** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $
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*/
@@ -30,16 +30,16 @@
30*/ 30*/
31#if !defined(LUA_STRFTIMEOPTIONS) /* { */ 31#if !defined(LUA_STRFTIMEOPTIONS) /* { */
32 32
33/* options for ANSI C 89 */ 33/* options for ANSI C 89 (only 1-char options) */
34#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" 34#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
35 35
36/* options for ISO C 99 and POSIX */ 36/* options for ISO C 99 and POSIX */
37#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ 37#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
38 "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" 38 "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
39 39
40/* options for Windows */ 40/* options for Windows */
41#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ 41#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
42 "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" 42 "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
43 43
44#if defined(LUA_USE_WINDOWS) 44#if defined(LUA_USE_WINDOWS)
45#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN 45#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
@@ -257,12 +257,13 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
257} 257}
258 258
259 259
260static const char *checkoption (lua_State *L, const char *conv, char *buff) { 260static const char *checkoption (lua_State *L, const char *conv,
261 const char *option; 261 ptrdiff_t convlen, char *buff) {
262 int oplen = 1; 262 const char *option = LUA_STRFTIMEOPTIONS;
263 for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) { 263 int oplen = 1; /* length of options being checked */
264 for (; *option != '\0' && oplen <= convlen; option += oplen) {
264 if (*option == '|') /* next block? */ 265 if (*option == '|') /* next block? */
265 oplen++; /* next length */ 266 oplen++; /* will check options with next length (+1) */
266 else if (memcmp(conv, option, oplen) == 0) { /* match? */ 267 else if (memcmp(conv, option, oplen) == 0) { /* match? */
267 memcpy(buff, conv, oplen); /* copy valid option to buffer */ 268 memcpy(buff, conv, oplen); /* copy valid option to buffer */
268 buff[oplen] = '\0'; 269 buff[oplen] = '\0';
@@ -280,8 +281,10 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) {
280 281
281 282
282static int os_date (lua_State *L) { 283static int os_date (lua_State *L) {
283 const char *s = luaL_optstring(L, 1, "%c"); 284 size_t slen;
285 const char *s = luaL_optlstring(L, 1, "%c", &slen);
284 time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); 286 time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
287 const char *se = s + slen; /* 's' end */
285 struct tm tmr, *stm; 288 struct tm tmr, *stm;
286 if (*s == '!') { /* UTC? */ 289 if (*s == '!') { /* UTC? */
287 stm = l_gmtime(&t, &tmr); 290 stm = l_gmtime(&t, &tmr);
@@ -300,13 +303,14 @@ static int os_date (lua_State *L) {
300 luaL_Buffer b; 303 luaL_Buffer b;
301 cc[0] = '%'; 304 cc[0] = '%';
302 luaL_buffinit(L, &b); 305 luaL_buffinit(L, &b);
303 while (*s) { 306 while (s < se) {
304 if (*s != '%') /* not a conversion specifier? */ 307 if (*s != '%') /* not a conversion specifier? */
305 luaL_addchar(&b, *s++); 308 luaL_addchar(&b, *s++);
306 else { 309 else {
307 size_t reslen; 310 size_t reslen;
308 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); 311 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
309 s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */ 312 s++; /* skip '%' */
313 s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
310 reslen = strftime(buff, SIZETIMEFMT, cc, stm); 314 reslen = strftime(buff, SIZETIMEFMT, cc, stm);
311 luaL_addsize(&b, reslen); 315 luaL_addsize(&b, reslen);
312 } 316 }