Commit b7f3a305 authored by Paul Eggert's avatar Paul Eggert

Don't access pointers to freed storage in regex.c

Remove __BOUNDED_POINTERS__ code, which does not work with
-fcheck-pointer-bound and which has undefined behavior anyway.
Problem found when trying to port to gcc -fcheck-pointer-bounds.
(This code was removed from glibc and gnulib regex.c many years ago.)
* src/regex.c (ELSE_EXTEND_BUFFER_HIGH_BOUND): Remove.
(EXTEND_BUFFER): Use a more-portable approach that avoids
undefined behavior due to inspecting pointers to freed storage.
parent caec5c06
...@@ -1644,28 +1644,6 @@ static int analyze_first (re_char *p, re_char *pend, ...@@ -1644,28 +1644,6 @@ static int analyze_first (re_char *p, re_char *pend,
reset the pointers that pointed into the old block to point to the reset the pointers that pointed into the old block to point to the
correct places in the new one. If extending the buffer results in it correct places in the new one. If extending the buffer results in it
being larger than MAX_BUF_SIZE, then flag memory exhausted. */ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
#if __BOUNDED_POINTERS__
# define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
# define MOVE_BUFFER_POINTER(P) \
(__ptrlow (P) = new_buffer + (__ptrlow (P) - old_buffer), \
SET_HIGH_BOUND (P), \
__ptrvalue (P) = new_buffer + (__ptrvalue (P) - old_buffer))
# define ELSE_EXTEND_BUFFER_HIGH_BOUND \
else \
{ \
SET_HIGH_BOUND (b); \
SET_HIGH_BOUND (begalt); \
if (fixup_alt_jump) \
SET_HIGH_BOUND (fixup_alt_jump); \
if (laststart) \
SET_HIGH_BOUND (laststart); \
if (pending_exact) \
SET_HIGH_BOUND (pending_exact); \
}
#else
# define MOVE_BUFFER_POINTER(P) ((P) = new_buffer + ((P) - old_buffer))
# define ELSE_EXTEND_BUFFER_HIGH_BOUND
#endif
#define EXTEND_BUFFER() \ #define EXTEND_BUFFER() \
do { \ do { \
unsigned char *old_buffer = bufp->buffer; \ unsigned char *old_buffer = bufp->buffer; \
...@@ -1674,23 +1652,24 @@ static int analyze_first (re_char *p, re_char *pend, ...@@ -1674,23 +1652,24 @@ static int analyze_first (re_char *p, re_char *pend,
bufp->allocated <<= 1; \ bufp->allocated <<= 1; \
if (bufp->allocated > MAX_BUF_SIZE) \ if (bufp->allocated > MAX_BUF_SIZE) \
bufp->allocated = MAX_BUF_SIZE; \ bufp->allocated = MAX_BUF_SIZE; \
ptrdiff_t b_off = b - old_buffer; \
ptrdiff_t begalt_off = begalt - old_buffer; \
bool fixup_alt_jump_set = !!fixup_alt_jump; \
bool laststart_set = !!laststart; \
bool pending_exact_set = !!pending_exact; \
ptrdiff_t fixup_alt_jump_off, laststart_off, pending_exact_off; \
if (fixup_alt_jump_set) fixup_alt_jump_off = fixup_alt_jump - old_buffer; \
if (laststart_set) laststart_off = laststart - old_buffer; \
if (pending_exact_set) pending_exact_off = pending_exact - old_buffer; \
RETALLOC (bufp->buffer, bufp->allocated, unsigned char); \ RETALLOC (bufp->buffer, bufp->allocated, unsigned char); \
if (bufp->buffer == NULL) \ if (bufp->buffer == NULL) \
return REG_ESPACE; \ return REG_ESPACE; \
/* If the buffer moved, move all the pointers into it. */ \ unsigned char *new_buffer = bufp->buffer; \
if (old_buffer != bufp->buffer) \ b = new_buffer + b_off; \
{ \ begalt = new_buffer + begalt_off; \
unsigned char *new_buffer = bufp->buffer; \ if (fixup_alt_jump_set) fixup_alt_jump = new_buffer + fixup_alt_jump_off; \
MOVE_BUFFER_POINTER (b); \ if (laststart_set) laststart = new_buffer + laststart_off; \
MOVE_BUFFER_POINTER (begalt); \ if (pending_exact_set) pending_exact = new_buffer + pending_exact_off; \
if (fixup_alt_jump) \
MOVE_BUFFER_POINTER (fixup_alt_jump); \
if (laststart) \
MOVE_BUFFER_POINTER (laststart); \
if (pending_exact) \
MOVE_BUFFER_POINTER (pending_exact); \
} \
ELSE_EXTEND_BUFFER_HIGH_BOUND \
} while (0) } while (0)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment