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 {
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 {

View File

@ -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) {