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: fix invalid memory access in array...



details:   https://anonhg.NetBSD.org/src/rev/932d591ed4be
branches:  trunk
changeset: 1024722:932d591ed4be
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Oct 31 23:15:44 2021 +0000

description:
lint: fix invalid memory access in array[enum] check

Lint checks whether in an expression 'array[enum]', the array size
matches the value of the maximum enum constant.

The previous tests for this check were missing the case where an enum
name was explicitly cast to an integer type and then used as an array
index. In this situation, the resulting type of the array index is a
plain 'int' without any information about its previous 'enum' history.

An entirely different case is when the 'enum' is implicitly converted to
an integer type, as in the test color_name_too_many. There, for the
final type of the array index, rn->tn_type->t_is_enum is true, which
means that rn->tn_type->t_enum is properly filled.

The bug was a simple typo, I had forgotten a tn_left indirection, which
is necessary to get the type before the implicit conversion.

Found and reported by Christos, triggered by src/lib/libperfuse/ops.c
1.89 line 1226 expression 'VTTOIF(vap->va_type)'.

diffstat:

 tests/usr.bin/xlint/lint1/msg_348.c   |  13 ++++++++++++-
 tests/usr.bin/xlint/lint1/msg_348.exp |   5 +++--
 usr.bin/xlint/lint1/tree.c            |  12 +++++-------
 3 files changed, 20 insertions(+), 10 deletions(-)

diffs (80 lines):

diff -r 7c2af0aad841 -r 932d591ed4be tests/usr.bin/xlint/lint1/msg_348.c
--- a/tests/usr.bin/xlint/lint1/msg_348.c       Sun Oct 31 22:38:12 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_348.c       Sun Oct 31 23:15:44 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msg_348.c,v 1.1 2021/10/30 22:04:42 rillig Exp $       */
+/*     $NetBSD: msg_348.c,v 1.2 2021/10/31 23:15:44 rillig Exp $       */
 # 3 "msg_348.c"
 
 // Test for message 348: maximum value %d of '%s' does not match maximum array index %d [348]
@@ -72,6 +72,17 @@
 }
 
 const char *
+color_name_explicit_cast_to_int(enum color color)
+{
+       static const char *name[] = {
+           "red",
+           "green",
+       };
+       /* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348] */
+       return name[(int)color];
+}
+
+const char *
 color_name_computed_pointer(enum color color, const char *name)
 {
        /* No warning since 'name' is not an array. */
diff -r 7c2af0aad841 -r 932d591ed4be tests/usr.bin/xlint/lint1/msg_348.exp
--- a/tests/usr.bin/xlint/lint1/msg_348.exp     Sun Oct 31 22:38:12 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_348.exp     Sun Oct 31 23:15:44 2021 +0000
@@ -1,4 +1,5 @@
 msg_348.c(32): warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348]
 msg_348.c(45): warning: maximum value 2 of 'enum color' does not match maximum array index 3 [348]
-msg_348.c(92): warning: integral constant too large [56]
-msg_348.c(94): warning: integral constant too large [56]
+msg_348.c(82): warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348]
+msg_348.c(103): warning: integral constant too large [56]
+msg_348.c(105): warning: integral constant too large [56]
diff -r 7c2af0aad841 -r 932d591ed4be usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c        Sun Oct 31 22:38:12 2021 +0000
+++ b/usr.bin/xlint/lint1/tree.c        Sun Oct 31 23:15:44 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tree.c,v 1.387 2021/10/31 16:42:16 christos Exp $      */
+/*     $NetBSD: tree.c,v 1.388 2021/10/31 23:15:44 rillig Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.387 2021/10/31 16:42:16 christos Exp $");
+__RCSID("$NetBSD: tree.c,v 1.388 2021/10/31 23:15:44 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -1793,12 +1793,9 @@
                return;
        if (rn->tn_left->tn_type->t_tspec != ENUM)
                return;
-       // XXX: why?
-       if (rn->tn_type->t_enum == NULL)
-               return;
 
        max_enum_value = INT_MIN;
-       ec = rn->tn_type->t_enum->en_first_enumerator;
+       ec = rn->tn_left->tn_type->t_enum->en_first_enumerator;
        for (; ec != NULL; ec = ec->s_next) {
                int64_t ev = ec->s_value.v_quad;
                lint_assert(INT_MIN <= ev && ev <= INT_MAX);
@@ -1811,7 +1808,8 @@
                return;
 
        /* maximum value %d of '%s' does not match maximum array index %d */
-       warning(348, max_enum_value, type_name(rn->tn_type), max_array_index);
+       warning(348, max_enum_value, type_name(rn->tn_left->tn_type),
+           max_array_index);
 }
 
 /*



Home | Main Index | Thread Index | Old Index