[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua 5.3.4 and LPeg 1.0.1 dumped core on me
- From: Andrew Gierth <andrew@...>
- Date: Sat, 10 Nov 2018 08:27:44 +0000
>>>>> "Andrew" == Andrew Gierth <andrew@tao11.riddles.org.uk> writes:
>>>>> "Sean" == Sean Conner <sean@conman.org> writes:
Sean> So I'm participating in this years National Novel Generation
Sean> Month [1] and I finished my entry. While generating the output, I
Sean> had to use Lua 5.1 because Lua 5.3 would crash---hard.
Andrew> Looks like lpeg is at fault: substcap is passing a bad length to
Andrew> luaL_addlstring.
Andrew> Here in substcap:
Andrew> 403 while (!isclosecap(cs->cap)) { /* traverse nested captures */
Andrew> 404 const char *next = cs->cap->s;
Andrew> 405 luaL_addlstring(b, curr, next - curr); /* add text up to capture */
Andrew> "next" is 0x0 while "curr" is a valid pointer.
The offending null value of cs->cap->s comes from here:
/*
** Add capture values returned by a dynamic capture to the capture list
** 'base', nested inside a group capture. 'fd' indexes the first capture
** value, 'n' is the number of values (at least 1).
*/
static void adddyncaptures (const char *s, Capture *base, int n, int fd) {
int i;
base[0].kind = Cgroup; /* create group capture */
base[0].siz = 0;
base[0].idx = 0; /* make it an anonymous group */
for (i = 1; i <= n; i++) { /* add runtime captures */
...
This code thinks it can create an anonymous group capture with no valid
.s pointer (to contain the results of a match-time capture). I _think_
the failure is normally hidden by the fact that base[0] is _usually_ a
reuse of the same Capture that was used for the match-time capture
itself - except that the array of Capture structures might get
reallocated between the two uses, without preserving the old value of
the (now unused) Capture.
Here is a small testcase (note that shortening the string eliminates the
error):
local lpeg = require 'lpeg'
local P,Cs,Cmt = lpeg.P, lpeg.Cs, lpeg.Cmt
local pat1 = P"a" / "b" + Cmt(P"c", function(_,p) return p,"d" end) + P(1)
local pat = Cs(pat1^1)
print(pat:match("abcdabcdabcdabcdabcdabcdabcdabc"))'
--
Andrew.