diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2026-04-01 15:01:58 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2026-04-01 15:01:58 -0300 |
| commit | efddc2309c5ff8a1842bea8a9c0d7d4a5d6e1e60 (patch) | |
| tree | 10c85aab8380de274878ecde03f1e03438420918 | |
| parent | f1bb2773bba8b16f0f01c00e59a7be541ef88cb7 (diff) | |
| download | lua-efddc2309c5ff8a1842bea8a9c0d7d4a5d6e1e60.tar.gz lua-efddc2309c5ff8a1842bea8a9c0d7d4a5d6e1e60.tar.bz2 lua-efddc2309c5ff8a1842bea8a9c0d7d4a5d6e1e60.zip | |
Bug: wrong initialization in result from 'gmatch'
Function returned by 'string.gmatch' can be left in an inconsistent
state after an error.
| -rw-r--r-- | lstrlib.c | 10 | ||||
| -rw-r--r-- | testes/pm.lua | 10 |
2 files changed, 18 insertions, 2 deletions
| @@ -757,19 +757,25 @@ static int nospecials (const char *p, size_t l) { | |||
| 757 | } | 757 | } |
| 758 | 758 | ||
| 759 | 759 | ||
| 760 | /* | ||
| 761 | ** Prepare state for matches. These fields are not affected by each match. | ||
| 762 | */ | ||
| 760 | static void prepstate (MatchState *ms, lua_State *L, | 763 | static void prepstate (MatchState *ms, lua_State *L, |
| 761 | const char *s, size_t ls, const char *p, size_t lp) { | 764 | const char *s, size_t ls, const char *p, size_t lp) { |
| 762 | ms->L = L; | 765 | ms->L = L; |
| 763 | ms->matchdepth = MAXCCALLS; | ||
| 764 | ms->src_init = s; | 766 | ms->src_init = s; |
| 765 | ms->src_end = s + ls; | 767 | ms->src_end = s + ls; |
| 766 | ms->p_end = p + lp; | 768 | ms->p_end = p + lp; |
| 767 | } | 769 | } |
| 768 | 770 | ||
| 769 | 771 | ||
| 772 | /* | ||
| 773 | ** (Re)prepare state for a match, setting fields that change during | ||
| 774 | ** each match. | ||
| 775 | */ | ||
| 770 | static void reprepstate (MatchState *ms) { | 776 | static void reprepstate (MatchState *ms) { |
| 777 | ms->matchdepth = MAXCCALLS; | ||
| 771 | ms->level = 0; | 778 | ms->level = 0; |
| 772 | lua_assert(ms->matchdepth == MAXCCALLS); | ||
| 773 | } | 779 | } |
| 774 | 780 | ||
| 775 | 781 | ||
diff --git a/testes/pm.lua b/testes/pm.lua index 720d2a35..feab33db 100644 --- a/testes/pm.lua +++ b/testes/pm.lua | |||
| @@ -347,6 +347,16 @@ do -- init parameter in gmatch | |||
| 347 | end | 347 | end |
| 348 | 348 | ||
| 349 | 349 | ||
| 350 | do -- bug since 5.3 | ||
| 351 | local N = 20000 | ||
| 352 | local iter = string.gmatch(string.rep("a", N), string.rep("a?", N)) | ||
| 353 | pcall(iter) -- error for pattern too complex | ||
| 354 | -- calling function again found recursion count ('matchdepth') equal | ||
| 355 | -- to -1, so it did not detect next C-stack overflow | ||
| 356 | pcall(iter) | ||
| 357 | end | ||
| 358 | |||
| 359 | |||
| 350 | -- tests for `%f' (`frontiers') | 360 | -- tests for `%f' (`frontiers') |
| 351 | 361 | ||
| 352 | assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") | 362 | assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") |
