emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r115491: Avoid undefined behavior with huge regexp i


From: Paul Eggert
Subject: [Emacs-diffs] trunk r115491: Avoid undefined behavior with huge regexp interval counts.
Date: Thu, 12 Dec 2013 19:23:30 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 115491
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Thu 2013-12-12 11:23:25 -0800
message:
  Avoid undefined behavior with huge regexp interval counts.
  
  * regex.c (GET_INTERVAL_COUNT): Rename from 'GET_UNSIGNED_NUMBER',
  since it's now specialized to interval counts.        All uses changed.
  Do not assume wrapraound on signed integer overflow.
  (regex_compile): Simplify based on the above changes.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/regex.c                    regex.c-20091113204419-o5vbwnq5f7feedwu-518
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-12-12 18:19:10 +0000
+++ b/src/ChangeLog     2013-12-12 19:23:25 +0000
@@ -1,3 +1,11 @@
+2013-12-12  Paul Eggert  <address@hidden>
+
+       Avoid undefined behavior with huge regexp interval counts.
+       * regex.c (GET_INTERVAL_COUNT): Rename from 'GET_UNSIGNED_NUMBER',
+       since it's now specialized to interval counts.  All uses changed.
+       Do not assume wrapraound on signed integer overflow.
+       (regex_compile): Simplify based on the above changes.
+
 2013-12-12  Eli Zaretskii  <address@hidden>
 
        Support file names on MS-Windows that use characters outside of

=== modified file 'src/regex.c'
--- a/src/regex.c       2013-12-01 22:33:13 +0000
+++ b/src/regex.c       2013-12-12 19:23:25 +0000
@@ -1989,7 +1989,7 @@
 #endif /* emacs */
 
 /* Get the next unsigned number in the uncompiled pattern.  */
-#define GET_UNSIGNED_NUMBER(num)                                       \
+#define GET_INTERVAL_COUNT(num)                                        \
   do {                                                                 \
     if (p == pend)                                                     \
       FREE_STACK_RETURN (REG_EBRACE);                                  \
@@ -1998,13 +1998,11 @@
        PATFETCH (c);                                                   \
        while ('0' <= c && c <= '9')                                    \
          {                                                             \
-           int prev;                                                   \
            if (num < 0)                                                \
              num = 0;                                                  \
-           prev = num;                                                 \
+           if (RE_DUP_MAX / 10 - (RE_DUP_MAX % 10 < c - '0') < num)    \
+             FREE_STACK_RETURN (REG_BADBR);                            \
            num = num * 10 + c - '0';                                   \
-           if (num / 10 != prev)                                       \
-             FREE_STACK_RETURN (REG_BADBR);                            \
            if (p == pend)                                              \
              FREE_STACK_RETURN (REG_EBRACE);                           \
            PATFETCH (c);                                               \
@@ -3310,18 +3308,18 @@
 
                beg_interval = p;
 
-               GET_UNSIGNED_NUMBER (lower_bound);
+               GET_INTERVAL_COUNT (lower_bound);
 
                if (c == ',')
-                 GET_UNSIGNED_NUMBER (upper_bound);
+                 {
+                   GET_INTERVAL_COUNT (upper_bound);
+                   if (upper_bound < lower_bound)
+                     FREE_STACK_RETURN (REG_BADBR);
+                 }
                else
                  /* Interval such as `{1}' => match exactly once. */
                  upper_bound = lower_bound;
 
-               if (lower_bound < 0 || upper_bound > RE_DUP_MAX
-                   || (upper_bound >= 0 && lower_bound > upper_bound))
-                 FREE_STACK_RETURN (REG_BADBR);
-
                if (!(syntax & RE_NO_BK_BRACES))
                  {
                    if (c != '\\')


reply via email to

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