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).
This commit is contained in:
Akim Demaille
2019-03-12 19:09:10 +01:00
parent f6e38d7ac9
commit 35add841ee
2 changed files with 9 additions and 17 deletions

View File

@@ -31,25 +31,16 @@ 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;
return column <= INT_MAX - width ? column + width : INT_MAX;
}
/* Set *LOC and adjust scanner cursor to account for token TOKEN of
@@ -66,7 +57,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':

View File

@@ -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;
}