diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-04-22 13:36:30 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-04-22 13:36:30 -0300 |
commit | 57cdb60429c77078d896ab789c032d87fb58449d (patch) | |
tree | 57f2faf4bc57a62312c9ac6a9549d7f32be96692 /lstrlib.c | |
parent | 89c09c8e400806a2059fe8460c7c9db517d16ed7 (diff) | |
download | lua-57cdb60429c77078d896ab789c032d87fb58449d.tar.gz lua-57cdb60429c77078d896ab789c032d87fb58449d.tar.bz2 lua-57cdb60429c77078d896ab789c032d87fb58449d.zip |
no more time limits to pattern matching (at least for now)
Diffstat (limited to 'lstrlib.c')
-rw-r--r-- | lstrlib.c | 39 |
1 files changed, 1 insertions, 38 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstrlib.c,v 1.245 2016/04/08 21:15:02 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.246 2016/04/19 12:34:08 roberto Exp roberto $ |
3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -215,10 +215,8 @@ typedef struct MatchState { | |||
215 | const char *src_end; /* end ('\0') of source string */ | 215 | const char *src_end; /* end ('\0') of source string */ |
216 | const char *p_end; /* end ('\0') of pattern */ | 216 | const char *p_end; /* end ('\0') of pattern */ |
217 | lua_State *L; | 217 | lua_State *L; |
218 | lua_Unsigned nrep; /* limit to avoid non-linear complexity */ | ||
219 | int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ | 218 | int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ |
220 | unsigned char level; /* total number of captures (finished or unfinished) */ | 219 | unsigned char level; /* total number of captures (finished or unfinished) */ |
221 | unsigned char usedlimit; /* true if real limit for 'nrep' was used */ | ||
222 | struct { | 220 | struct { |
223 | const char *init; | 221 | const char *init; |
224 | ptrdiff_t len; | 222 | ptrdiff_t len; |
@@ -236,16 +234,6 @@ static const char *match (MatchState *ms, const char *s, const char *p); | |||
236 | #endif | 234 | #endif |
237 | 235 | ||
238 | 236 | ||
239 | /* | ||
240 | ** Maximum number of operators handled in a match before consulting | ||
241 | ** 'string.pattlimit'. (This lower limit is only to avoid wasting time | ||
242 | ** consulting 'string.pattlimit' in simple matches.) | ||
243 | */ | ||
244 | #if !defined(PREPATTLIMIT) | ||
245 | #define PREPATTLIMIT 200 | ||
246 | #endif | ||
247 | |||
248 | |||
249 | #define L_ESC '%' | 237 | #define L_ESC '%' |
250 | #define SPECIALS "^$*+?.([%-" | 238 | #define SPECIALS "^$*+?.([%-" |
251 | 239 | ||
@@ -422,27 +410,6 @@ static const char *end_capture (MatchState *ms, const char *s, | |||
422 | } | 410 | } |
423 | 411 | ||
424 | 412 | ||
425 | static void checklimit (MatchState *ms) { | ||
426 | lua_State *L = ms->L; | ||
427 | lua_assert(ms->nrep == 0); | ||
428 | if (!ms->usedlimit) { /* have not used 'string.pattlimit' yet? */ | ||
429 | int top = lua_gettop(L); | ||
430 | if (lua_getglobal(L, "string") == LUA_TTABLE && | ||
431 | lua_getfield(L, -1, "pattlimit") != LUA_TNIL) { /* is it defined? */ | ||
432 | lua_Unsigned limit = (lua_Unsigned)lua_tointeger(L, -1); /* get it */ | ||
433 | if (limit > PREPATTLIMIT) /* discount cycles already used */ | ||
434 | ms->nrep = limit - PREPATTLIMIT; | ||
435 | ms->usedlimit = 1; /* do not use 'pattlimit' again */ | ||
436 | } | ||
437 | else /* no limit defined; set no limit */ | ||
438 | ms->nrep = ~(lua_Unsigned)0; | ||
439 | lua_settop(L, top); /* pop 'string' table and (maybe) 'pattlimit' */ | ||
440 | } | ||
441 | if (ms->nrep == 0) | ||
442 | luaL_error(L, "pattern too complex"); | ||
443 | } | ||
444 | |||
445 | |||
446 | static const char *match_capture (MatchState *ms, const char *s, int l) { | 413 | static const char *match_capture (MatchState *ms, const char *s, int l) { |
447 | size_t len; | 414 | size_t len; |
448 | l = check_capture(ms, l); | 415 | l = check_capture(ms, l); |
@@ -524,8 +491,6 @@ static const char *match (MatchState *ms, const char *s, const char *p) { | |||
524 | s = NULL; /* fail */ | 491 | s = NULL; /* fail */ |
525 | } | 492 | } |
526 | else { /* matched once */ | 493 | else { /* matched once */ |
527 | if (--ms->nrep == 0) | ||
528 | checklimit(ms); | ||
529 | switch (*ep) { /* handle optional suffix */ | 494 | switch (*ep) { /* handle optional suffix */ |
530 | case '?': { /* optional */ | 495 | case '?': { /* optional */ |
531 | const char *res; | 496 | const char *res; |
@@ -629,8 +594,6 @@ static void prepstate (MatchState *ms, lua_State *L, | |||
629 | ms->src_init = s; | 594 | ms->src_init = s; |
630 | ms->src_end = s + ls; | 595 | ms->src_end = s + ls; |
631 | ms->p_end = p + lp; | 596 | ms->p_end = p + lp; |
632 | ms->nrep = PREPATTLIMIT; | ||
633 | ms->usedlimit = 0; | ||
634 | } | 597 | } |
635 | 598 | ||
636 | 599 | ||