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 null pointer dereference after...



details:   https://anonhg.NetBSD.org/src/rev/716a66d0b796
branches:  trunk
changeset: 366573:716a66d0b796
user:      rillig <rillig%NetBSD.org@localhost>
date:      Tue May 31 00:35:18 2022 +0000

description:
lint: fix null pointer dereference after syntax error

Found by afl, starting with the malformed input '/**/f=({;/**/};}' that
no longer crashes.  This input led to 'f=({L:;}', which is at least a
syntactically valid prefix of a translation unit, containing a GCC
statement expression with an unused label.  The error message for this
unused label assumed that it would always be inside a function
definition.

While here, document incomplete recovery after syntax errors, in
msg_249.c.

diffstat:

 tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c   |  15 +++++++-
 tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.exp |  10 +++--
 tests/usr.bin/xlint/lint1/msg_249.c                      |  29 +++++++++++++++-
 tests/usr.bin/xlint/lint1/msg_249.exp                    |   4 ++
 usr.bin/xlint/lint1/decl.c                               |   9 +++-
 5 files changed, 58 insertions(+), 9 deletions(-)

diffs (121 lines):

diff -r 314c75322a74 -r 716a66d0b796 tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c
--- a/tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c    Tue May 31 00:17:10 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c    Tue May 31 00:35:18 2022 +0000
@@ -1,8 +1,21 @@
-/*     $NetBSD: d_gcc_compound_statements1.c,v 1.9 2022/04/24 20:08:23 rillig Exp $    */
+/*     $NetBSD: d_gcc_compound_statements1.c,v 1.10 2022/05/31 00:35:18 rillig Exp $   */
 # 3 "d_gcc_compound_statements1.c"
 
 /* GCC compound statement with expression */
 
+/*
+ * Compound statements are only allowed in functions, not at file scope.
+ *
+ * Before decl.c 1.283 from 2022-05-21, lint crashed with a segmentation
+ * fault due to the unused label.
+ */
+int invalid_gcc_statement_expression = ({
+unused_label:
+       3;
+/* expect+2: error: syntax error 'labels are only valid inside a function' [249] */
+/* expect+1: error: cannot initialize 'int' from 'void' [185] */
+});
+
 void foo(unsigned long z)
 {
        z = ({
diff -r 314c75322a74 -r 716a66d0b796 tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.exp
--- a/tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.exp  Tue May 31 00:17:10 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.exp  Tue May 31 00:35:18 2022 +0000
@@ -1,4 +1,6 @@
-d_gcc_compound_statements1.c(24): error: syntax error 'return outside function' [249]
-d_gcc_compound_statements1.c(25): error: cannot initialize 'int' from 'void' [185]
-d_gcc_compound_statements1.c(37): error: type 'int' does not have member 'e' [101]
-d_gcc_compound_statements1.c(50): error: syntax error ';' [249]
+d_gcc_compound_statements1.c(17): error: syntax error 'labels are only valid inside a function' [249]
+d_gcc_compound_statements1.c(17): error: cannot initialize 'int' from 'void' [185]
+d_gcc_compound_statements1.c(37): error: syntax error 'return outside function' [249]
+d_gcc_compound_statements1.c(38): error: cannot initialize 'int' from 'void' [185]
+d_gcc_compound_statements1.c(50): error: type 'int' does not have member 'e' [101]
+d_gcc_compound_statements1.c(63): error: syntax error ';' [249]
diff -r 314c75322a74 -r 716a66d0b796 tests/usr.bin/xlint/lint1/msg_249.c
--- a/tests/usr.bin/xlint/lint1/msg_249.c       Tue May 31 00:17:10 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_249.c       Tue May 31 00:35:18 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msg_249.c,v 1.9 2022/01/15 23:21:34 rillig Exp $       */
+/*     $NetBSD: msg_249.c,v 1.10 2022/05/31 00:35:18 rillig Exp $      */
 # 3 "msg_249.c"
 
 // Test for message: syntax error '%s' [249]
@@ -58,3 +58,30 @@
        /* expect+1: error: syntax error 'member without type' [249] */
        const;
 };
+
+/*
+ * At this point, lint assumes that the following code is still in the
+ * function 'access_declaration_after_syntax_error'.
+ */
+
+int gcc_statement_expression_1 = ({
+/* expect+1: warning: label 'unused_label' unused in function 'access_declaration_after_syntax_error' [232] */
+unused_label:
+       1;
+       1;
+});
+/* expect-1: error: non-constant initializer [177] */
+
+/* Even another function definition does not help. */
+void
+try_to_recover(void)
+{
+}
+
+int gcc_statement_expression_2 = ({
+/* expect+1: warning: label 'unused_label' unused in function 'try_to_recover' [232] */
+unused_label:
+       1;
+       1;
+});
+/* expect-1: error: non-constant initializer [177] */
diff -r 314c75322a74 -r 716a66d0b796 tests/usr.bin/xlint/lint1/msg_249.exp
--- a/tests/usr.bin/xlint/lint1/msg_249.exp     Tue May 31 00:17:10 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_249.exp     Tue May 31 00:35:18 2022 +0000
@@ -3,3 +3,7 @@
 msg_249.c(33): warning: statement not reached [193]
 msg_249.c(34): error: syntax error ')' [249]
 msg_249.c(59): error: syntax error 'member without type' [249]
+msg_249.c(69): warning: label 'unused_label' unused in function 'access_declaration_after_syntax_error' [232]
+msg_249.c(72): error: non-constant initializer [177]
+msg_249.c(83): warning: label 'unused_label' unused in function 'try_to_recover' [232]
+msg_249.c(86): error: non-constant initializer [177]
diff -r 314c75322a74 -r 716a66d0b796 usr.bin/xlint/lint1/decl.c
--- a/usr.bin/xlint/lint1/decl.c        Tue May 31 00:17:10 2022 +0000
+++ b/usr.bin/xlint/lint1/decl.c        Tue May 31 00:35:18 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.282 2022/05/26 13:40:49 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.283 2022/05/31 00:35:18 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: decl.c,v 1.282 2022/05/26 13:40:49 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.283 2022/05/31 00:35:18 rillig Exp $");
 #endif
 
 #include <sys/param.h>
@@ -3174,7 +3174,10 @@
        lint_assert(block_level == 1);
        lint_assert(lab->s_block_level == 1);
 
-       if (lab->s_set && !lab->s_used) {
+       if (funcsym == NULL) {
+               /* syntax error '%s' */
+               error(249, "labels are only valid inside a function");
+       } else if (lab->s_set && !lab->s_used) {
                /* label '%s' unused in function '%s' */
                warning_at(232, &lab->s_set_pos, lab->s_name, funcsym->s_name);
        } else if (!lab->s_set) {



Home | Main Index | Thread Index | Old Index