bison-patches
[Top][All Lists]
Advanced

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

Re: address warnings from GCC's UB sanitizer


From: Akim Demaille
Subject: Re: address warnings from GCC's UB sanitizer
Date: Fri, 15 Mar 2019 18:28:27 +0100

Hi Paul,

> Le 14 mars 2019 à 22:26, Paul Eggert <address@hidden> a écrit :
> 
> On 3/14/19 1:43 PM, Akim Demaille wrote:
> 
>> +  return column <= INT_MAX - width ? column + width : INT_MAX;
> 
> Nowadays a better (i.e., more-efficient, and I think easier-to-follow)
> way of writing this is:
> 
>   int result;
>   return INT_ADD_WRAPV (column, width, &result) : INT_MAX : result;
> 
> where INT_ADD_WRAPV is defined in intprops.h.

Excellent!  Thanks a lot.  I'll install the following when the CI confirms it.

commit 57a9210568b79b552a939c89345a0a4c332cc00c
Author: Akim Demaille <address@hidden>
Date:   Tue Mar 12 19:09:10 2019 +0100

    address warnings from GCC's UB sanitizer
    
    Running with CC='gcc-mp-8 -fsanitize=undefined' revealed Undefined
    Behaviors.
    https://lists.gnu.org/archive/html/bison-patches/2019-03/msg00008.html
    
    * src/state.c (errs_new): Don't call memcpy with NULL as source.
    * src/location.c (add_column_width): Don't assume that the column
    argument is nonnegative: the scanner sometimes "backtracks" (e.g., see
    ROLLBACK_CURRENT_TOKEN and DEPRECATED) in which case we can have
    negative column numbers (temporarily).
    Found in test 3 (Invalid inputs).
    Use INT_ADD_WRAPV.
    Suggested by Paul Eggert.

diff --git a/src/location.c b/src/location.c
index ab478107..1d1bfcb7 100644
--- a/src/location.c
+++ b/src/location.c
@@ -21,6 +21,7 @@
 #include <config.h>
 #include "system.h"
 
+#include <intprops.h>
 #include <mbswidth.h>
 #include <quotearg.h>
 
@@ -31,25 +32,17 @@ location const empty_location = EMPTY_LOCATION_INIT;
 
 /* If BUF is null, add BUFSIZE (which in this case must be less than
    INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
-   COLUMN.  If an overflow occurs, or might occur but is undetectable,
-   return INT_MAX.  Assume COLUMN is nonnegative.  */
+   COLUMN.  If an overflow occurs, return INT_MAX.  */
 
 static inline int
 add_column_width (int column, char const *buf, size_t bufsize)
 {
-  size_t width;
-  unsigned remaining_columns = INT_MAX - column;
-
-  if (buf)
-    {
-      if (INT_MAX / 2 <= bufsize)
-        return INT_MAX;
-      width = mbsnwidth (buf, bufsize, 0);
-    }
-  else
-    width = bufsize;
-
-  return width <= remaining_columns ? column + width : INT_MAX;
+  int width
+    = buf ? mbsnwidth (buf, bufsize, 0)
+    : INT_MAX <= bufsize ? INT_MAX
+    : bufsize;
+  int res;
+  return INT_ADD_WRAPV (column, width, &res) ? INT_MAX : res;
 }
 
 /* Set *LOC and adjust scanner cursor to account for token TOKEN of
@@ -66,7 +59,7 @@ location_compute (location *loc, boundary *cur, char const 
*token, size_t size)
 
   loc->start = *cur;
 
-  for (p = token; p < lim; p++)
+  for (p = token; p < lim; ++p)
     switch (*p)
       {
       case '\n':
diff --git a/src/state.c b/src/state.c
index b8b8e2ff..58980954 100644
--- a/src/state.c
+++ b/src/state.c
@@ -77,7 +77,8 @@ errs_new (int num, symbol **tokens)
   size_t symbols_size = num * sizeof *tokens;
   errs *res = xmalloc (offsetof (errs, symbols) + symbols_size);
   res->num = num;
-  memcpy (res->symbols, tokens, symbols_size);
+  if (tokens)
+    memcpy (res->symbols, tokens, symbols_size);
   return res;
 }
 




reply via email to

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