lua

A copy of the Lua development repository
Log | Files | Refs | README

commit acff3ad88db13bb6d74170a3db475a4e45ddb51f
parent e7b2e01d43d9c3ab6d223daa18eebb94a322e082
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Wed, 23 Mar 2016 14:11:51 -0300

bug: 'gmatch' iterator fails when called from a coroutine different
from the one that created it

Diffstat:
Mbugs | 27+++++++++++++++++++++++++++
Mlstrlib.c | 9++++-----
2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/bugs b/bugs @@ -3575,6 +3575,33 @@ patch = [[ } +Bug{ +what = [['gmatch' iterator fails when called from a coroutine different +from the one that created it]], +report = [[Nagaev Boris, 2016/03/18]], +since = [[5.3.2]], +fix = nil, +example = [[ +local f = string.gmatch("1 2 3 4 5", "%d+") +print(f()) --> 1 +co = coroutine.wrap(f) +print(co()) --> ??? (should be 2) +]], +patch = [[ +--- lstrlib.c 2016/02/25 19:42:55 1.240 ++++ lstrlib.c 2016/03/21 17:27:07 +@@ -688,14 +688,13 @@ + static int gmatch_aux (lua_State *L) { + GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); + const char *src; ++ gm->ms.L = L; + for (src = gm->src; src <= gm->ms.src_end; src++) { + const char *e; + reprepstate(&gm->ms); +]] +} + + --[=[ Bug{ what = [[ ]], diff --git a/lstrlib.c b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.240 2016/02/25 19:42:55 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -688,14 +688,13 @@ typedef struct GMatchState { static int gmatch_aux (lua_State *L) { GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); const char *src; + gm->ms.L = L; for (src = gm->src; src <= gm->ms.src_end; src++) { const char *e; reprepstate(&gm->ms); if ((e = match(&gm->ms, src, gm->p)) != NULL) { - if (e == src) /* empty match? */ - gm->src =src + 1; /* go at least one position */ - else - gm->src = e; + /* in empty matches, advance at least one position */ + gm->src = (e == src) ? src + 1 : e; return push_captures(&gm->ms, src, e); } }