comparison 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
comparison
equal deleted inserted replaced
4321:98e54edf3ab2 4322:f70e56bb52a7
1369 1369
1370 if (new_bytelen != orig_bytelen || inv_bytelen != orig_bytelen) 1370 if (new_bytelen != orig_bytelen || inv_bytelen != orig_bytelen)
1371 boyer_moore_ok = 0; 1371 boyer_moore_ok = 0;
1372 if (translated != c || inverse != c) 1372 if (translated != c || inverse != c)
1373 { 1373 {
1374 /* Keep track of which character set row 1374 /* Keep track of which charset and character set row
1375 contains the characters that need translation. */ 1375 contains the characters that need translation.
1376 Zero out the bits corresponding to the last byte.
1377 */
1376 int charset_base_code = c & ~ICHAR_FIELD3_MASK; 1378 int charset_base_code = c & ~ICHAR_FIELD3_MASK;
1377 if (charset_base == -1) 1379 if (charset_base == -1)
1378 charset_base = charset_base_code; 1380 charset_base = charset_base_code;
1379 else if (charset_base != charset_base_code) 1381 else if (charset_base != charset_base_code)
1380 /* If two different rows appear, needing translation, 1382 /* If two different rows appear, needing translation, then
1381 then we cannot use boyer_moore search. */ 1383 we cannot use boyer_moore search. See the comment at the
1384 head of boyer_moore(). */
1382 boyer_moore_ok = 0; 1385 boyer_moore_ok = 0;
1383 } 1386 }
1384 memcpy (pat, tmp_str, new_bytelen); 1387 memcpy (pat, tmp_str, new_bytelen);
1385 pat += new_bytelen; 1388 pat += new_bytelen;
1386 base_pat += orig_bytelen; 1389 base_pat += orig_bytelen;
1466 INC_BYTEBPOS (buf, pos); 1469 INC_BYTEBPOS (buf, pos);
1467 } 1470 }
1468 n--; 1471 n--;
1469 } 1472 }
1470 else 1473 else
1471 while (n < 0) 1474 {
1472 { 1475 /* If lim < len, then there are too few buffer positions to hold the
1473 while (1) 1476 pattern between the beginning of the buffer and lim. Adjust to
1474 { 1477 ensure pattern fits. If we don't do this, we can assert in the
1475 Bytecount this_len = len; 1478 DEC_BYTEBPOS below. */
1476 Bytebpos this_pos = pos; 1479 if (lim < len)
1477 Ibyte *p; 1480 lim = len;
1478 if (pos <= lim) 1481 while (n < 0)
1479 goto stop; 1482 {
1480 p = base_pat + len; 1483 while (1)
1481 1484 {
1482 while (this_len > 0) 1485 Bytecount this_len = len;
1483 { 1486 Bytebpos this_pos = pos;
1484 Ichar pat_ch, buf_ch; 1487 Ibyte *p;
1485 1488 if (pos <= lim)
1486 DEC_IBYTEPTR (p); 1489 goto stop;
1487 DEC_BYTEBPOS (buf, this_pos); 1490 p = base_pat + len;
1488 pat_ch = itext_ichar (p); 1491
1489 buf_ch = BYTE_BUF_FETCH_CHAR (buf, this_pos); 1492 while (this_len > 0)
1490 1493 {
1491 buf_ch = TRANSLATE (trt, buf_ch); 1494 Ichar pat_ch, buf_ch;
1492 1495
1493 if (buf_ch != pat_ch) 1496 DEC_IBYTEPTR (p);
1497 DEC_BYTEBPOS (buf, this_pos);
1498 pat_ch = itext_ichar (p);
1499 buf_ch = BYTE_BUF_FETCH_CHAR (buf, this_pos);
1500
1501 buf_ch = TRANSLATE (trt, buf_ch);
1502
1503 if (buf_ch != pat_ch)
1504 break;
1505
1506 this_len -= itext_ichar_len (p);
1507 }
1508 if (this_len == 0)
1509 {
1510 buf_len = pos - this_pos;
1511 pos = this_pos;
1494 break; 1512 break;
1495 1513 }
1496 this_len -= itext_ichar_len (p); 1514 DEC_BYTEBPOS (buf, pos);
1497 } 1515 }
1498 if (this_len == 0) 1516 n++;
1499 { 1517 }
1500 buf_len = pos - this_pos; 1518 }
1501 pos = this_pos;
1502 break;
1503 }
1504 DEC_BYTEBPOS (buf, pos);
1505 }
1506 n++;
1507 }
1508 stop: 1519 stop:
1509 if (n == 0) 1520 if (n == 0)
1510 { 1521 {
1511 Charbpos beg, end, retval; 1522 Charbpos beg, end, retval;
1512 if (forward) 1523 if (forward)