Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/xlint/lint1 lint: prevent undefined behavior for sig...



details:   https://anonhg.NetBSD.org/src/rev/0be20beac468
branches:  trunk
changeset: 373161:0be20beac468
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Jan 22 16:05:08 2023 +0000

description:
lint: prevent undefined behavior for signed '<<'

Found by manual code inspection, verified by MKSANITIZER=yes
USE_SANITIZER=undefined.

diffstat:

 tests/usr.bin/xlint/lint1/msg_071.c |   9 ++++++++-
 tests/usr.bin/xlint/lint1/msg_075.c |  14 +++++++++++++-
 usr.bin/xlint/lint1/lex.c           |  18 ++++++++++--------
 usr.bin/xlint/lint1/tree.c          |   5 +++--
 4 files changed, 34 insertions(+), 12 deletions(-)

diffs (135 lines):

diff -r fc0a87a684d9 -r 0be20beac468 tests/usr.bin/xlint/lint1/msg_071.c
--- a/tests/usr.bin/xlint/lint1/msg_071.c       Sun Jan 22 15:20:01 2023 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_071.c       Sun Jan 22 16:05:08 2023 +0000
@@ -1,9 +1,16 @@
-/*     $NetBSD: msg_071.c,v 1.5 2022/06/15 20:18:31 rillig Exp $       */
+/*     $NetBSD: msg_071.c,v 1.6 2023/01/22 16:05:08 rillig Exp $       */
 # 3 "msg_071.c"
 
 // Test for message: too many characters in character constant [71]
 
 /*
+ * See also:
+ *     lex_char.c
+ *     lex_char_uchar.c
+ *     lex_wide_char.c
+ */
+
+/*
  * C11 6.4.4.4p7 says: Each hexadecimal escape sequence is the longest
  * sequence of characters that can constitute the escape sequence.
  */
diff -r fc0a87a684d9 -r 0be20beac468 tests/usr.bin/xlint/lint1/msg_075.c
--- a/tests/usr.bin/xlint/lint1/msg_075.c       Sun Jan 22 15:20:01 2023 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_075.c       Sun Jan 22 16:05:08 2023 +0000
@@ -1,7 +1,19 @@
-/*     $NetBSD: msg_075.c,v 1.4 2022/06/15 20:18:31 rillig Exp $       */
+/*     $NetBSD: msg_075.c,v 1.5 2023/01/22 16:05:08 rillig Exp $       */
 # 3 "msg_075.c"
 
 // Test for message: overflow in hex escape [75]
 
+/*
+ * See also:
+ *     lex_char.c
+ *     lex_char_uchar.c
+ *     lex_string.c
+ *     lex_wide_char.c
+ *     lex_wide_string.c
+ */
+
 /* expect+1: warning: overflow in hex escape [75] */
 char str[] = "\x12345678123456781234567812345678";
+
+/* C11 6.4.4.4p7 */
+char leading_zeroes = '\x0000000000000000000000000000020';
diff -r fc0a87a684d9 -r 0be20beac468 usr.bin/xlint/lint1/lex.c
--- a/usr.bin/xlint/lint1/lex.c Sun Jan 22 15:20:01 2023 +0000
+++ b/usr.bin/xlint/lint1/lex.c Sun Jan 22 16:05:08 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.144 2023/01/21 21:26:40 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.145 2023/01/22 16:05:08 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: lex.c,v 1.144 2023/01/21 21:26:40 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.145 2023/01/22 16:05:08 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -751,13 +751,13 @@
        return value;
 }
 
-static int
+static unsigned int
 read_escaped_hex(int c)
 {
        if (!allow_c90)
                /* \x undefined in traditional C */
                warning(82);
-       int value = 0;
+       unsigned int value = 0;
        int state = 0;          /* 0 = no digits, 1 = OK, 2 = overflow */
        while (c = read_byte(), isxdigit(c)) {
                c = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
@@ -830,7 +830,7 @@
        case '4': case '5': case '6': case '7':
                return read_escaped_oct(c);
        case 'x':
-               return read_escaped_hex(c);
+               return (int)read_escaped_hex(c);
        case '\n':
                return -3;
        case EOF:
@@ -902,15 +902,17 @@
        n = 0;
        val = 0;
        while ((c = get_escaped_char('\'')) >= 0) {
-               val = (val << CHAR_SIZE) + c;
+               val = (int)((unsigned int)val << CHAR_SIZE) + c;
                n++;
        }
        if (c == -2) {
                /* unterminated character constant */
                error(253);
        } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) {
-               /* XXX: should rather be sizeof(TARG_INT) */
-
+               /*
+                * XXX: ^^ should rather be sizeof(TARG_INT). Luckily,
+                * sizeof(int) is the same on all supported platforms.
+                */
                /* too many characters in character constant */
                error(71);
        } else if (n > 1) {
diff -r fc0a87a684d9 -r 0be20beac468 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c        Sun Jan 22 15:20:01 2023 +0000
+++ b/usr.bin/xlint/lint1/tree.c        Sun Jan 22 16:05:08 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tree.c,v 1.493 2023/01/21 20:07:01 rillig Exp $        */
+/*     $NetBSD: tree.c,v 1.494 2023/01/22 16:05:08 rillig Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.493 2023/01/21 20:07:01 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.494 2023/01/22 16:05:08 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3609,6 +3609,7 @@
                break;
        case SHL:
                /* TODO: warn about out-of-bounds 'sr'. */
+               /* TODO: warn about overflow in signed '<<'. */
                q = utyp ? (int64_t)(ul << (sr & 63)) : sl << (sr & 63);
                break;
        case SHR:



Home | Main Index | Thread Index | Old Index