aboutsummaryrefslogtreecommitdiff
path: root/lpcap.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-19 11:14:02 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-19 11:14:02 -0300
commit9a9ee3d9ab8ce435d743d293ec43075151370200 (patch)
tree445290bfa04c2cd30f514b65b90b1d8b973f21f1 /lpcap.c
parenta561630f17e61548193666abf9a8b20f20462558 (diff)
downloadlpeg-9a9ee3d9ab8ce435d743d293ec43075151370200.tar.gz
lpeg-9a9ee3d9ab8ce435d743d293ec43075151370200.tar.bz2
lpeg-9a9ee3d9ab8ce435d743d293ec43075151370200.zip
Some fixes in vibibility check for back captures
Diffstat (limited to 'lpcap.c')
-rw-r--r--lpcap.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/lpcap.c b/lpcap.c
index 74a34db..fca8cbb 100644
--- a/lpcap.c
+++ b/lpcap.c
@@ -126,15 +126,23 @@ static void pushonenestedvalue (CapState *cs) {
126 126
127 127
128/* 128/*
129** Checks whether group 'grp' is visible to 'ref', that is, 129** Checks whether group 'grp' is visible to 'ref', that is, 'grp' is
130** 'grp' is not nested inside a capture that does not contain 'ref'. 130** not nested inside a full capture that does not contain 'ref'. (We
131** To do that, must find minimum capture that contains 'grp'. 131** only need to care for full captures because the search at 'findback'
132** skips open-end blocks; so, if 'grp' is nested in a non-full capture,
133** 'ref' is also inside it.) To check this, we search backward for the
134** inner full capture enclosing 'grp'. A full capture cannot contain
135** non-full captures, so a close capture means we cannot be inside a
136** full capture anymore.
132*/ 137*/
133static int capvisible (CapState *cs, Capture *grp, Capture *ref) { 138static int capvisible (CapState *cs, Capture *grp, Capture *ref) {
134 Capture *cap = grp; 139 Capture *cap = grp;
135 while (cap-- > cs->ocap) { /* repeat until end of list */ 140 int i = MAXLOP; /* maximum distance for an 'open' */
141 while (i-- > 0 && cap-- > cs->ocap) {
136 if (isclosecap(cap)) 142 if (isclosecap(cap))
137 cap = findopen(cap); /* skip nested captures */ 143 return 1; /* can stop the search */
144 else if (grp->index - cap->index >= UCHAR_MAX)
145 return 1; /* can stop the search */
138 else if (capinside(cap, grp)) /* is 'grp' inside cap? */ 146 else if (capinside(cap, grp)) /* is 'grp' inside cap? */
139 return capinside(cap, ref); /* ok iff cap also contains 'ref' */ 147 return capinside(cap, ref); /* ok iff cap also contains 'ref' */
140 } 148 }
@@ -150,10 +158,10 @@ static Capture *findback (CapState *cs, Capture *ref) {
150 lua_State *L = cs->L; 158 lua_State *L = cs->L;
151 Capture *cap = ref; 159 Capture *cap = ref;
152 while (cap-- > cs->ocap) { /* repeat until end of list */ 160 while (cap-- > cs->ocap) { /* repeat until end of list */
153 if (isopencap(cap)) 161 if (isclosecap(cap))
154 continue; /* enclosing captures are not visible to 'ref' */
155 else if (isclosecap(cap))
156 cap = findopen(cap); /* skip nested captures */ 162 cap = findopen(cap); /* skip nested captures */
163 else if (capinside(cap, ref))
164 continue; /* enclosing captures are not visible to 'ref' */
157 if (captype(cap) == Cgroup && capvisible(cs, cap, ref)) { 165 if (captype(cap) == Cgroup && capvisible(cs, cap, ref)) {
158 getfromktable(cs, cap->idx); /* get group name */ 166 getfromktable(cs, cap->idx); /* get group name */
159 if (lp_equal(L, -2, -1)) { /* right group? */ 167 if (lp_equal(L, -2, -1)) { /* right group? */