diff options
| author | Mattias EngdegÄrd | 2019-03-19 13:06:20 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2019-03-30 11:48:25 +0100 |
| commit | 75ec1b1952633019f5afaf24dd87e7e4f7d31f9c (patch) | |
| tree | 2e59acb674e825b2176709551123b46ee15fdef9 /src | |
| parent | 9c0fa1172fd987a8f23b115145270383a11c12fc (diff) | |
| download | emacs-75ec1b1952633019f5afaf24dd87e7e4f7d31f9c.tar.gz emacs-75ec1b1952633019f5afaf24dd87e7e4f7d31f9c.zip | |
Fix spurious regexp reentrancy error
* src/search.c (compile_pattern): Don't give up if the last regexp
cache entry is busy. Instead, use the last (least recently used)
non-busy entry, and only signal a reentrancy error if there is no free
entry at all (Bug#34910).
Diffstat (limited to 'src')
| -rw-r--r-- | src/search.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/search.c b/src/search.c index e15e2b94e5f..07ff0e47643 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -198,11 +198,13 @@ static struct regexp_cache * | |||
| 198 | compile_pattern (Lisp_Object pattern, struct re_registers *regp, | 198 | compile_pattern (Lisp_Object pattern, struct re_registers *regp, |
| 199 | Lisp_Object translate, bool posix, bool multibyte) | 199 | Lisp_Object translate, bool posix, bool multibyte) |
| 200 | { | 200 | { |
| 201 | struct regexp_cache *cp, **cpp; | 201 | struct regexp_cache *cp, **cpp, **lru_nonbusy; |
| 202 | 202 | ||
| 203 | for (cpp = &searchbuf_head; ; cpp = &cp->next) | 203 | for (cpp = &searchbuf_head, lru_nonbusy = NULL; ; cpp = &cp->next) |
| 204 | { | 204 | { |
| 205 | cp = *cpp; | 205 | cp = *cpp; |
| 206 | if (!cp->busy) | ||
| 207 | lru_nonbusy = cpp; | ||
| 206 | /* Entries are initialized to nil, and may be set to nil by | 208 | /* Entries are initialized to nil, and may be set to nil by |
| 207 | compile_pattern_1 if the pattern isn't valid. Don't apply | 209 | compile_pattern_1 if the pattern isn't valid. Don't apply |
| 208 | string accessors in those cases. However, compile_pattern_1 | 210 | string accessors in those cases. However, compile_pattern_1 |
| @@ -222,13 +224,14 @@ compile_pattern (Lisp_Object pattern, struct re_registers *regp, | |||
| 222 | && cp->buf.charset_unibyte == charset_unibyte) | 224 | && cp->buf.charset_unibyte == charset_unibyte) |
| 223 | break; | 225 | break; |
| 224 | 226 | ||
| 225 | /* If we're at the end of the cache, compile into the nil cell | 227 | /* If we're at the end of the cache, compile into the last |
| 226 | we found, or the last (least recently used) cell with a | 228 | (least recently used) non-busy cell in the cache. */ |
| 227 | string value. */ | ||
| 228 | if (cp->next == 0) | 229 | if (cp->next == 0) |
| 229 | { | 230 | { |
| 230 | if (cp->busy) | 231 | if (!lru_nonbusy) |
| 231 | error ("Too much matching reentrancy"); | 232 | error ("Too much matching reentrancy"); |
| 233 | cpp = lru_nonbusy; | ||
| 234 | cp = *cpp; | ||
| 232 | compile_it: | 235 | compile_it: |
| 233 | eassert (!cp->busy); | 236 | eassert (!cp->busy); |
| 234 | compile_pattern_1 (cp, pattern, translate, posix); | 237 | compile_pattern_1 (cp, pattern, translate, posix); |