emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master b7f3a30: Don't access pointers to freed storage in


From: Paul Eggert
Subject: [Emacs-diffs] master b7f3a30: Don't access pointers to freed storage in regex.c
Date: Sat, 26 Nov 2016 08:20:33 +0000 (UTC)

branch: master
commit b7f3a3055c92010afde318c1108b02e4424a3bac
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/regex.c |   51 +++++++++++++++------------------------------------
 1 file changed, 15 insertions(+), 36 deletions(-)

diff --git a/src/regex.c b/src/regex.c
index 1c6c9e5..afd0d18 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -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
    correct places in the new one.  If extending the buffer results in it
    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()                                                        
\
   do {                                                                 \
     unsigned char *old_buffer = bufp->buffer;                          \
@@ -1674,23 +1652,24 @@ static int analyze_first (re_char *p, re_char *pend,
     bufp->allocated <<= 1;                                             \
     if (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);           \
     if (bufp->buffer == NULL)                                          \
       return REG_ESPACE;                                               \
-    /* If the buffer moved, move all the pointers into it.  */         \
-    if (old_buffer != bufp->buffer)                                    \
-      {                                                                        
\
-       unsigned char *new_buffer = bufp->buffer;                       \
-       MOVE_BUFFER_POINTER (b);                                        \
-       MOVE_BUFFER_POINTER (begalt);                                   \
-       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                                      \
+    unsigned char *new_buffer = bufp->buffer;                          \
+    b = new_buffer + b_off;                                            \
+    begalt = new_buffer + begalt_off;                                  \
+    if (fixup_alt_jump_set) fixup_alt_jump = new_buffer + fixup_alt_jump_off; \
+    if (laststart_set) laststart = new_buffer + laststart_off;         \
+    if (pending_exact_set) pending_exact = new_buffer + pending_exact_off; \
   } while (0)
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]