diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-06-19 11:14:02 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-06-19 11:14:02 -0300 |
commit | 9a9ee3d9ab8ce435d743d293ec43075151370200 (patch) | |
tree | 445290bfa04c2cd30f514b65b90b1d8b973f21f1 /lpcap.c | |
parent | a561630f17e61548193666abf9a8b20f20462558 (diff) | |
download | lpeg-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.c | 24 |
1 files changed, 16 insertions, 8 deletions
@@ -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 | */ |
133 | static int capvisible (CapState *cs, Capture *grp, Capture *ref) { | 138 | static 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? */ |