Mercurial > hg > xemacs-beta
diff src/search.c @ 4322:f70e56bb52a7
src/search.c (simple_search): Fix underrun in reverse search.
Add braces to avoid future whitespace bogosity.
(search_buffer): Clarify decision to use boyer_moore or not.
tests/reproduce-bugs.el: Bug 10 to test for the underrun.
author | Stephen J. Turnbull <stephen@xemacs.org> |
---|---|
date | Mon, 10 Dec 2007 01:13:36 -0800 |
parents | 3660d327399f |
children | 4ee73bbe4f8e |
line wrap: on
line diff
--- a/src/search.c Mon Dec 10 00:57:19 2007 -0800 +++ b/src/search.c Mon Dec 10 01:13:36 2007 -0800 @@ -1371,14 +1371,17 @@ boyer_moore_ok = 0; if (translated != c || inverse != c) { - /* Keep track of which character set row - contains the characters that need translation. */ + /* Keep track of which charset and character set row + contains the characters that need translation. + Zero out the bits corresponding to the last byte. + */ int charset_base_code = c & ~ICHAR_FIELD3_MASK; if (charset_base == -1) charset_base = charset_base_code; else if (charset_base != charset_base_code) - /* If two different rows appear, needing translation, - then we cannot use boyer_moore search. */ + /* If two different rows appear, needing translation, then + we cannot use boyer_moore search. See the comment at the + head of boyer_moore(). */ boyer_moore_ok = 0; } memcpy (pat, tmp_str, new_bytelen); @@ -1468,43 +1471,51 @@ n--; } else - while (n < 0) - { - while (1) - { - Bytecount this_len = len; - Bytebpos this_pos = pos; - Ibyte *p; - if (pos <= lim) - goto stop; - p = base_pat + len; - - while (this_len > 0) - { - Ichar pat_ch, buf_ch; - - DEC_IBYTEPTR (p); - DEC_BYTEBPOS (buf, this_pos); - pat_ch = itext_ichar (p); - buf_ch = BYTE_BUF_FETCH_CHAR (buf, this_pos); - - buf_ch = TRANSLATE (trt, buf_ch); - - if (buf_ch != pat_ch) + { + /* If lim < len, then there are too few buffer positions to hold the + pattern between the beginning of the buffer and lim. Adjust to + ensure pattern fits. If we don't do this, we can assert in the + DEC_BYTEBPOS below. */ + if (lim < len) + lim = len; + while (n < 0) + { + while (1) + { + Bytecount this_len = len; + Bytebpos this_pos = pos; + Ibyte *p; + if (pos <= lim) + goto stop; + p = base_pat + len; + + while (this_len > 0) + { + Ichar pat_ch, buf_ch; + + DEC_IBYTEPTR (p); + DEC_BYTEBPOS (buf, this_pos); + pat_ch = itext_ichar (p); + buf_ch = BYTE_BUF_FETCH_CHAR (buf, this_pos); + + buf_ch = TRANSLATE (trt, buf_ch); + + if (buf_ch != pat_ch) + break; + + this_len -= itext_ichar_len (p); + } + if (this_len == 0) + { + buf_len = pos - this_pos; + pos = this_pos; break; - - this_len -= itext_ichar_len (p); - } - if (this_len == 0) - { - buf_len = pos - this_pos; - pos = this_pos; - break; - } - DEC_BYTEBPOS (buf, pos); - } - n++; - } + } + DEC_BYTEBPOS (buf, pos); + } + n++; + } + } stop: if (n == 0) {