mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
[BZ #3155]
2006-09-07 Jakub Jelinek <jakub@redhat.com> [BZ #3155] * sysdeps/powerpc/powerpc32/fpu/s_lrint.S (__lrint): Don't access stack below r1. * posix/regex_internal.c (re_string_reconstruct): Handle offset < pstr->valid_raw_len && pstr->offsets_needed case. Ensure no bytes read before raw_mbs array. Pass a saved copy of pstr->valid_len - 1 rather than pstr->valid_raw_len - 1 to re_string_context_at. * posix/Makefile: Add rules to build and run bug-regex26 test. * posix/bug-regex26.c: New test. * dlfcn/Makefile (LDLIBS-bug-atexit3-lib.so): Add ld.so.
This commit is contained in:
@ -585,34 +585,98 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
||||
|
||||
if (BE (offset != 0, 1))
|
||||
{
|
||||
/* Are the characters which are already checked remain? */
|
||||
if (BE (offset < pstr->valid_raw_len, 1)
|
||||
#ifdef RE_ENABLE_I18N
|
||||
/* Handling this would enlarge the code too much.
|
||||
Accept a slowdown in that case. */
|
||||
&& pstr->offsets_needed == 0
|
||||
#endif
|
||||
)
|
||||
/* Should the already checked characters be kept? */
|
||||
if (BE (offset < pstr->valid_raw_len, 1))
|
||||
{
|
||||
/* Yes, move them to the front of the buffer. */
|
||||
pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags);
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (pstr->mb_cur_max > 1)
|
||||
memmove (pstr->wcs, pstr->wcs + offset,
|
||||
(pstr->valid_len - offset) * sizeof (wint_t));
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
if (BE (pstr->mbs_allocated, 0))
|
||||
memmove (pstr->mbs, pstr->mbs + offset,
|
||||
pstr->valid_len - offset);
|
||||
pstr->valid_len -= offset;
|
||||
pstr->valid_raw_len -= offset;
|
||||
#if DEBUG
|
||||
assert (pstr->valid_len > 0);
|
||||
if (BE (pstr->offsets_needed, 0))
|
||||
{
|
||||
int low = 0, high = pstr->valid_len, mid;
|
||||
do
|
||||
{
|
||||
mid = (high + low) / 2;
|
||||
if (pstr->offsets[mid] > offset)
|
||||
high = mid;
|
||||
else if (pstr->offsets[mid] < offset)
|
||||
low = mid + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (low < high);
|
||||
if (pstr->offsets[mid] < offset)
|
||||
++mid;
|
||||
pstr->tip_context = re_string_context_at (pstr, mid - 1,
|
||||
eflags);
|
||||
/* This can be quite complicated, so handle specially
|
||||
only the common and easy case where the character with
|
||||
different length representation of lower and upper
|
||||
case is present at or after offset. */
|
||||
if (pstr->valid_len > offset
|
||||
&& mid == offset && pstr->offsets[mid] == offset)
|
||||
{
|
||||
memmove (pstr->wcs, pstr->wcs + offset,
|
||||
(pstr->valid_len - offset) * sizeof (wint_t));
|
||||
memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
|
||||
pstr->valid_len -= offset;
|
||||
pstr->valid_raw_len -= offset;
|
||||
for (low = 0; low < pstr->valid_len; low++)
|
||||
pstr->offsets[low] = pstr->offsets[low + offset] - offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, just find out how long the partial multibyte
|
||||
character at offset is and fill it with WEOF/255. */
|
||||
pstr->len = pstr->raw_len - idx + offset;
|
||||
pstr->stop = pstr->raw_stop - idx + offset;
|
||||
pstr->offsets_needed = 0;
|
||||
while (mid > 0 && pstr->offsets[mid - 1] == offset)
|
||||
--mid;
|
||||
while (mid < pstr->valid_len)
|
||||
if (pstr->wcs[mid] != WEOF)
|
||||
break;
|
||||
else
|
||||
++mid;
|
||||
if (mid == pstr->valid_len)
|
||||
pstr->valid_len = 0;
|
||||
else
|
||||
{
|
||||
pstr->valid_len = pstr->offsets[mid] - offset;
|
||||
if (pstr->valid_len)
|
||||
{
|
||||
for (low = 0; low < pstr->valid_len; ++low)
|
||||
pstr->wcs[low] = WEOF;
|
||||
memset (pstr->mbs, 255, pstr->valid_len);
|
||||
}
|
||||
}
|
||||
pstr->valid_raw_len = pstr->valid_len;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pstr->tip_context = re_string_context_at (pstr, offset - 1,
|
||||
eflags);
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (pstr->mb_cur_max > 1)
|
||||
memmove (pstr->wcs, pstr->wcs + offset,
|
||||
(pstr->valid_len - offset) * sizeof (wint_t));
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
if (BE (pstr->mbs_allocated, 0))
|
||||
memmove (pstr->mbs, pstr->mbs + offset,
|
||||
pstr->valid_len - offset);
|
||||
pstr->valid_len -= offset;
|
||||
pstr->valid_raw_len -= offset;
|
||||
#if DEBUG
|
||||
assert (pstr->valid_len > 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No, skip all characters until IDX. */
|
||||
int prev_valid_len = pstr->valid_len;
|
||||
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (BE (pstr->offsets_needed, 0))
|
||||
{
|
||||
@ -636,6 +700,8 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
||||
byte other than 0x80 - 0xbf. */
|
||||
raw = pstr->raw_mbs + pstr->raw_mbs_idx;
|
||||
end = raw + (offset - pstr->mb_cur_max);
|
||||
if (end < pstr->raw_mbs)
|
||||
end = pstr->raw_mbs;
|
||||
p = raw + offset - 1;
|
||||
#ifdef _LIBC
|
||||
/* We know the wchar_t encoding is UCS4, so for the simple
|
||||
@ -643,7 +709,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
||||
if (isascii (*p) && BE (pstr->trans == NULL, 1))
|
||||
{
|
||||
memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
|
||||
pstr->valid_len = 0;
|
||||
/* pstr->valid_len = 0; */
|
||||
wc = (wchar_t) *p;
|
||||
}
|
||||
else
|
||||
@ -686,7 +752,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
||||
pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
|
||||
if (wc == WEOF)
|
||||
pstr->tip_context
|
||||
= re_string_context_at (pstr, pstr->valid_raw_len - 1, eflags);
|
||||
= re_string_context_at (pstr, prev_valid_len - 1, eflags);
|
||||
else
|
||||
pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
|
||||
&& IS_WIDE_WORD_CHAR (wc))
|
||||
|
Reference in New Issue
Block a user