From c2680687d148820847607e13ed7100e60d94c79e Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 19 Jul 2019 16:55:37 -0300 Subject: Bug: IBackCommit must remove dynamic captures, too Like a fail, a IBackCommit instruction must remove any dynamic capture made inside an 'and' pattern. (The added test for this problem needs assertions on to detect the bug.) --- lpvm.c | 2 ++ lpvm.h | 2 +- test.lua | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lpvm.c b/lpvm.c index dbe1a8e..af9e617 100644 --- a/lpvm.c +++ b/lpvm.c @@ -320,6 +320,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, case IBackCommit: { assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); s = (--stack)->s; + if (ndyncap > 0) /* are there matchtime captures? */ + ndyncap -= removedyncap(L, capture, stack->caplevel, captop); captop = stack->caplevel; p += getoffset(p); continue; diff --git a/lpvm.h b/lpvm.h index 9fde967..ca625f9 100644 --- a/lpvm.h +++ b/lpvm.h @@ -27,7 +27,7 @@ typedef enum Opcode { IOpenCall, /* call rule number 'key' (must be closed to a ICall) */ ICommit, /* pop choice and jump to 'offset' */ IPartialCommit, /* update top choice to current position and jump */ - IBackCommit, /* "fails" but jump to its own 'offset' */ + IBackCommit, /* backtrack like "fail" but jump to its own 'offset' */ IFailTwice, /* pop one choice and then fail */ IFail, /* go back to saved state on choice and jump to saved offset */ IGiveup, /* internal use */ diff --git a/test.lua b/test.lua index 403aa09..4263ff4 100755 --- a/test.lua +++ b/test.lua @@ -1032,6 +1032,17 @@ local function id (s, i, ...) return true, ... end +do -- run-time capture in an end predicate (should discard its value) + local x = 0 + function foo (s, i) + x = x + 1 + return true, x + end + + local p = #(m.Cmt("", foo) * "xx") * m.Cmt("", foo) + assert(p:match("xx") == 2) +end + assert(m.Cmt(m.Cs((m.Cmt(m.S'abc' / { a = 'x', c = 'y' }, id) + m.R'09'^1 / string.char + m.P(1))^0), id):match"acb98+68c" == "xyb\98+\68y") -- cgit v1.2.3-55-g6feb