From e72d9c0f888a24163722bc9f95ae4728e39e4ad6 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 1 Nov 2020 13:59:53 +0200 Subject: [PATCH] parser: protect against infinite loops in -silent mode over invalid .v files --- vlib/v/parser/fn.v | 9 +++++++++ vlib/v/parser/parser.v | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index bd8a73af9b..a24fb6e91f 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -258,6 +258,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { for param in params { if p.scope.known_var(param.name) { p.error_with_pos('redefinition of parameter `$param.name`', param.pos) + break } p.scope.register(param.name, ast.Var{ name: param.name @@ -456,6 +457,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } } else if is_shared || is_atomic { p.error_with_pos('generic object cannot be `atomic`or `shared`', pos) + break } // if arg_type.is_ptr() { // p.error('cannot mut') @@ -476,6 +478,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { if is_variadic { p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no', pos) + break } p.next() } @@ -488,6 +491,10 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { type_source_name: sym.source_name } arg_no++ + if arg_no > 1024 { + p.error_with_pos('too many args', pos) + break + } } } else { for p.tok.kind != .rpar { @@ -532,6 +539,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } else if is_shared || is_atomic { p.error_with_pos('generic object cannot be `atomic` or `shared`', pos) + break } typ = typ.set_nr_muls(1) if is_shared { @@ -557,6 +565,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { if is_variadic && p.tok.kind == .comma { p.error_with_pos('cannot use ...(variadic) with non-final parameter $arg_name', arg_pos[i]) + break } } if p.tok.kind != .rpar { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index a3796ca9de..089684f747 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -813,6 +813,13 @@ pub fn (mut p Parser) error_with_pos(s string, pos token.Position) { message: s } } + if p.pref.output_mode == .silent { + // Normally, parser errors mean that the parser exits immediately, so there can be only 1 parser error. + // In the silent mode however, the parser continues to run, even though it would have stopped. Some + // of the parser logic does not expect that, and may loop forever. + // The p.next() here is needed, so the parser is more robust, and *always* advances, even in the -silent mode. + p.next() + } } pub fn (mut p Parser) warn_with_pos(s string, pos token.Position) {