1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: protect against infinite loops in -silent mode over invalid .v files

This commit is contained in:
Delyan Angelov 2020-11-01 13:59:53 +02:00
parent 9fdf04b7ff
commit e72d9c0f88
2 changed files with 16 additions and 0 deletions

View File

@ -258,6 +258,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
for param in params { for param in params {
if p.scope.known_var(param.name) { if p.scope.known_var(param.name) {
p.error_with_pos('redefinition of parameter `$param.name`', param.pos) p.error_with_pos('redefinition of parameter `$param.name`', param.pos)
break
} }
p.scope.register(param.name, ast.Var{ p.scope.register(param.name, ast.Var{
name: param.name name: param.name
@ -456,6 +457,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
} }
} else if is_shared || is_atomic { } else if is_shared || is_atomic {
p.error_with_pos('generic object cannot be `atomic`or `shared`', pos) p.error_with_pos('generic object cannot be `atomic`or `shared`', pos)
break
} }
// if arg_type.is_ptr() { // if arg_type.is_ptr() {
// p.error('cannot mut') // p.error('cannot mut')
@ -476,6 +478,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
if is_variadic { if is_variadic {
p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no', p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no',
pos) pos)
break
} }
p.next() p.next()
} }
@ -488,6 +491,10 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
type_source_name: sym.source_name type_source_name: sym.source_name
} }
arg_no++ arg_no++
if arg_no > 1024 {
p.error_with_pos('too many args', pos)
break
}
} }
} else { } else {
for p.tok.kind != .rpar { 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 { } else if is_shared || is_atomic {
p.error_with_pos('generic object cannot be `atomic` or `shared`', p.error_with_pos('generic object cannot be `atomic` or `shared`',
pos) pos)
break
} }
typ = typ.set_nr_muls(1) typ = typ.set_nr_muls(1)
if is_shared { if is_shared {
@ -557,6 +565,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
if is_variadic && p.tok.kind == .comma { if is_variadic && p.tok.kind == .comma {
p.error_with_pos('cannot use ...(variadic) with non-final parameter $arg_name', p.error_with_pos('cannot use ...(variadic) with non-final parameter $arg_name',
arg_pos[i]) arg_pos[i])
break
} }
} }
if p.tok.kind != .rpar { if p.tok.kind != .rpar {

View File

@ -813,6 +813,13 @@ pub fn (mut p Parser) error_with_pos(s string, pos token.Position) {
message: s 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) { pub fn (mut p Parser) warn_with_pos(s string, pos token.Position) {