Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/indent indent: fix stack overflow, add more tests
details: https://anonhg.NetBSD.org/src/rev/f4a3b8ac953b
branches: trunk
changeset: 376333:f4a3b8ac953b
user: rillig <rillig%NetBSD.org@localhost>
date: Sat Jun 10 17:35:40 2023 +0000
description:
indent: fix stack overflow, add more tests
For several parser symbols, 2 symbols are pushed in a row, which led to
an out-of-bounds write.
diffstat:
tests/usr.bin/indent/opt_cli.c | 53 +++++++++++++++++++++++++++++++++++++++-
tests/usr.bin/indent/psym_else.c | 17 ++++++++++++-
tests/usr.bin/indent/t_errors.sh | 29 +++++++++++++++++++++-
usr.bin/indent/parse.c | 37 +++++++++++----------------
4 files changed, 111 insertions(+), 25 deletions(-)
diffs (251 lines):
diff -r e3f6e677d950 -r f4a3b8ac953b tests/usr.bin/indent/opt_cli.c
--- a/tests/usr.bin/indent/opt_cli.c Sat Jun 10 17:14:57 2023 +0000
+++ b/tests/usr.bin/indent/opt_cli.c Sat Jun 10 17:35:40 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: opt_cli.c,v 1.6 2023/06/06 04:37:27 rillig Exp $ */
+/* $NetBSD: opt_cli.c,v 1.7 2023/06/10 17:35:41 rillig Exp $ */
/*
* Tests for the option '-cli' ("case label indentation"), which sets the
@@ -97,3 +97,54 @@ classify(int n)
}
}
//indent end
+
+
+/*
+ * Test the combination of left-aligned braces and a deep case indentation.
+ *
+ * When the 'case' labels are that deeply indented, the distance between the
+ * braces and the 'case' is between 1 and 2 indentation levels.
+ */
+//indent input
+{
+switch (expr)
+{
+case 1:
+}
+}
+//indent end
+
+//indent run -br -cli3.25
+{
+ switch (expr) {
+ case 1:
+ }
+}
+//indent end
+
+//indent run -bl -cli3.25
+{
+ switch (expr)
+ {
+ case 1:
+ }
+}
+//indent end
+
+//indent run -bl -cli2.75
+{
+ switch (expr)
+ {
+ case 1:
+ }
+}
+//indent end
+
+//indent run -bl -cli1.25
+{
+ switch (expr)
+ {
+ case 1:
+ }
+}
+//indent end
diff -r e3f6e677d950 -r f4a3b8ac953b tests/usr.bin/indent/psym_else.c
--- a/tests/usr.bin/indent/psym_else.c Sat Jun 10 17:14:57 2023 +0000
+++ b/tests/usr.bin/indent/psym_else.c Sat Jun 10 17:35:40 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: psym_else.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
+/* $NetBSD: psym_else.c,v 1.5 2023/06/10 17:35:41 rillig Exp $ */
/*
* Tests for the parser symbol psym_else, which represents the keyword 'else'
@@ -71,3 +71,18 @@ function(void)
(var = 3);
}
//indent end
+
+
+//indent input
+{
+ else
+}
+//indent end
+
+//indent run
+error: Standard Input:2: Unmatched 'else'
+{
+ else
+}
+exit 1
+//indent end
diff -r e3f6e677d950 -r f4a3b8ac953b tests/usr.bin/indent/t_errors.sh
--- a/tests/usr.bin/indent/t_errors.sh Sat Jun 10 17:14:57 2023 +0000
+++ b/tests/usr.bin/indent/t_errors.sh Sat Jun 10 17:35:40 2023 +0000
@@ -1,5 +1,5 @@
#! /bin/sh
-# $NetBSD: t_errors.sh,v 1.34 2023/06/09 11:22:31 rillig Exp $
+# $NetBSD: t_errors.sh,v 1.35 2023/06/10 17:35:41 rillig Exp $
#
# Copyright (c) 2021 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -485,6 +485,32 @@ EOF
"$indent" -l34 code.c -st
}
+atf_test_case 'stack_overflow'
+stack_overflow_body()
+{
+ cat <<-EOF > code.c
+ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{
+ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{
+ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{
+ EOF
+
+ atf_check \
+ -s 'exit:1' \
+ -e 'inline:error: code.c:3: Stuff missing from end of file\n' \
+ "$indent" code.c
+
+ cat <<-EOF > code.c
+ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{
+ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{{{{
+ {{{{{{{{{{ {{{{{{{{{{ {{{{{{{ {
+ EOF
+
+ atf_check \
+ -s 'exit:1' \
+ -e 'inline:indent: Parser stack overflow\n' \
+ "$indent" code.c
+}
+
atf_init_test_cases()
{
@@ -524,4 +550,5 @@ atf_init_test_cases()
atf_add_test_case 'gcc_statement_expression'
atf_add_test_case 'crash_comment_after_controlling_expression'
atf_add_test_case 'comment_fits_in_one_line'
+ atf_add_test_case 'stack_overflow'
}
diff -r e3f6e677d950 -r f4a3b8ac953b usr.bin/indent/parse.c
--- a/usr.bin/indent/parse.c Sat Jun 10 17:14:57 2023 +0000
+++ b/usr.bin/indent/parse.c Sat Jun 10 17:35:40 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.71 2023/06/10 16:43:56 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.72 2023/06/10 17:35:40 rillig Exp $ */
/*-
* SPDX-License-Identifier: BSD-4-Clause
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: parse.c,v 1.71 2023/06/10 16:43:56 rillig Exp $");
+__RCSID("$NetBSD: parse.c,v 1.72 2023/06/10 17:35:40 rillig Exp $");
#include <err.h>
@@ -101,17 +101,13 @@ decl_level(void)
}
static void
-ps_push(parser_symbol psym)
+ps_push(parser_symbol psym, bool follow)
{
+ if (ps.psyms.top + 1 >= STACKSIZE)
+ errx(1, "Parser stack overflow");
ps.psyms.sym[++ps.psyms.top] = psym;
- ps.psyms.ind_level[ps.psyms.top] = ps.ind_level;
-}
-
-static void
-ps_push_follow(parser_symbol psym)
-{
- ps.psyms.sym[++ps.psyms.top] = psym;
- ps.psyms.ind_level[ps.psyms.top] = ps.ind_level_follow;
+ ps.psyms.ind_level[ps.psyms.top] =
+ follow ? ps.ind_level_follow : ps.ind_level;
}
/*
@@ -180,8 +176,8 @@ parse(parser_symbol psym)
--ps.ind_level;
}
- ps_push(psym);
- ps_push_follow(psym_stmt);
+ ps_push(psym, false);
+ ps_push(psym_stmt, true);
break;
case psym_rbrace:
@@ -201,7 +197,7 @@ parse(parser_symbol psym)
break; /* only put one declaration onto stack */
ps.break_after_comma = true;
- ps_push_follow(psym_decl);
+ ps_push(psym_decl, true);
if (opt.left_justify_decl)
ps.ind_level_follow = ps.ind_level = decl_level();
@@ -209,7 +205,7 @@ parse(parser_symbol psym)
case psym_stmt:
ps.break_after_comma = false;
- ps_push(psym_stmt);
+ ps_push(psym_stmt, false);
break;
case psym_if_expr:
@@ -220,7 +216,7 @@ parse(parser_symbol psym)
case psym_do:
case psym_for_exprs:
ps.ind_level = ps.ind_level_follow++;
- ps_push(psym);
+ ps_push(psym, false);
break;
case psym_else:
@@ -234,7 +230,7 @@ parse(parser_symbol psym)
break;
case psym_switch_expr:
- ps_push_follow(psym_switch_expr);
+ ps_push(psym_switch_expr, true);
ps.ind_level_follow += (int)opt.case_indent + 1;
break;
@@ -242,9 +238,9 @@ parse(parser_symbol psym)
if (psyms->sym[psyms->top] == psym_do_stmt) {
ps.ind_level = ps.ind_level_follow =
psyms->ind_level[psyms->top];
- ps_push(psym_while_expr);
+ ps_push(psym_while_expr, false);
} else {
- ps_push_follow(psym_while_expr);
+ ps_push(psym_while_expr, true);
++ps.ind_level_follow;
}
break;
@@ -254,9 +250,6 @@ parse(parser_symbol psym)
return;
}
- if (psyms->top >= STACKSIZE - 1)
- errx(1, "Parser stack overflow");
-
debug_psyms_stack("before reduction");
psyms_reduce(&ps.psyms);
debug_psyms_stack("after reduction");
Home |
Main Index |
Thread Index |
Old Index