parser: fix more edge case panics on fuzzed V source code in vlib/v/parser/testdata/silent/

This commit is contained in:
Delyan Angelov 2024-08-20 16:11:53 +03:00
parent c92577e6ed
commit 6dbf9c9155
No known key found for this signature in database
GPG key ID: 66886C0F12D595ED
5 changed files with 42 additions and 9 deletions

View file

@ -189,14 +189,20 @@ fn (foptions &FormatOptions) formated_content_from_file(prefs &pref.Preferences,
} }
fn (foptions &FormatOptions) format_file(file string) { fn (foptions &FormatOptions) format_file(file string) {
file_name := os.file_name(file)
ulid := rand.ulid()
vfmt_output_path := os.join_path(vtmp_folder, 'vfmt_${ulid}_${file_name}')
if file.contains('_vfmt_off') {
os.cp(file, vfmt_output_path) or { panic(err) }
foptions.vlog('format_file copied the file ${file} as it was, 1:1, since its name contains `_vfmt_off`.')
eprintln('${formatted_file_token}${vfmt_output_path}')
return
}
foptions.vlog('vfmt2 running fmt.fmt over file: ${file}') foptions.vlog('vfmt2 running fmt.fmt over file: ${file}')
prefs, mut table := setup_preferences_and_table() prefs, mut table := setup_preferences_and_table()
file_ast := parser.parse_file(file, mut table, .parse_comments, prefs) file_ast := parser.parse_file(file, mut table, .parse_comments, prefs)
// checker.new_checker(table, prefs).check(file_ast) // checker.new_checker(table, prefs).check(file_ast)
formatted_content := fmt.fmt(file_ast, mut table, prefs, foptions.is_debug) formatted_content := fmt.fmt(file_ast, mut table, prefs, foptions.is_debug)
file_name := os.file_name(file)
ulid := rand.ulid()
vfmt_output_path := os.join_path(vtmp_folder, 'vfmt_${ulid}_${file_name}')
os.write_file(vfmt_output_path, formatted_content) or { panic(err) } os.write_file(vfmt_output_path, formatted_content) or { panic(err) }
foptions.vlog('fmt.fmt worked and ${formatted_content.len} bytes were written to ${vfmt_output_path} .') foptions.vlog('fmt.fmt worked and ${formatted_content.len} bytes were written to ${vfmt_output_path} .')
eprintln('${formatted_file_token}${vfmt_output_path}') eprintln('${formatted_file_token}${vfmt_output_path}')

View file

@ -2536,8 +2536,14 @@ fn (mut p Parser) is_generic_cast() bool {
fn (mut p Parser) alias_array_type() ast.Type { fn (mut p Parser) alias_array_type() ast.Type {
full_name := p.prepend_mod(p.tok.lit) full_name := p.prepend_mod(p.tok.lit)
if idx := p.table.type_idxs[full_name] { if idx := p.table.type_idxs[full_name] {
if idx == 0 {
return ast.void_type
}
sym := p.table.sym(idx) sym := p.table.sym(idx)
if sym.info is ast.Alias { if sym.info is ast.Alias {
if sym.info.parent_type == 0 {
return ast.void_type
}
if p.table.sym(sym.info.parent_type).kind == .array { if p.table.sym(sym.info.parent_type).kind == .array {
return idx return idx
} }
@ -2791,7 +2797,7 @@ fn (mut p Parser) name_expr() ast.Expr {
} }
node = ast.CastExpr{ node = ast.CastExpr{
typ: to_typ typ: to_typ
typname: p.table.sym(to_typ).name typname: if to_typ != 0 { p.table.sym(to_typ).name } else { 'unknown typename' }
expr: expr expr: expr
arg: arg arg: arg
has_arg: has_arg has_arg: has_arg
@ -2949,7 +2955,7 @@ fn (mut p Parser) name_expr() ast.Expr {
p.check(.rpar) p.check(.rpar)
node = ast.CastExpr{ node = ast.CastExpr{
typ: to_typ typ: to_typ
typname: p.table.sym(to_typ).name typname: if to_typ != 0 { p.table.sym(to_typ).name } else { 'unknown type name' }
expr: expr expr: expr
arg: ast.empty_expr arg: ast.empty_expr
has_arg: false has_arg: false

View file

@ -0,0 +1 @@
println('Hello, Worlo, Wrin(('Hclcl'Hcl'Hc|)|l\0$&$+$`aa|n`xcalc`$+aaaa%d%n\u2147483648$'%saaaa%d%n\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0d

View file

@ -1,4 +1,5 @@
import os import os
import term
const vexe = @VEXE const vexe = @VEXE
const vroot = os.dir(vexe) const vroot = os.dir(vexe)
@ -7,8 +8,6 @@ fn test_print_v_files_in_stdout_mode() {
check_parsing_files_in_folder('vlib/v/parser/testdata/stdout', '-print-v-files') check_parsing_files_in_folder('vlib/v/parser/testdata/stdout', '-print-v-files')
} }
//
fn test_print_v_files_in_silent_mode() { fn test_print_v_files_in_silent_mode() {
check_parsing_files_in_folder('vlib/v/parser/testdata/silent', '-silent -print-v-files') check_parsing_files_in_folder('vlib/v/parser/testdata/silent', '-silent -print-v-files')
} }
@ -18,11 +17,11 @@ fn test_print_watched_files_in_silent_mode__used_by_vwatch() {
} }
fn check_parsing_files_in_folder(folder string, options string) { fn check_parsing_files_in_folder(folder string, options string) {
println('> checking .vv files in folder: `${folder}`, with `${options}` ...') println(term.colorize(term.magenta, '> checking .vv files in folder: `${folder}`, with `${options}` ...'))
files := os.walk_ext(os.join_path(vroot, folder), '.vv') files := os.walk_ext(os.join_path(vroot, folder), '.vv')
for f in files { for f in files {
cmd := '${os.quoted_path(vexe)} ${options} ${os.quoted_path(f)}' cmd := '${os.quoted_path(vexe)} ${options} ${os.quoted_path(f)}'
// eprintln('> cmd: $cmd') eprintln('> cmd: ${cmd}')
res := os.execute(cmd) res := os.execute(cmd)
assert res.exit_code == 0, 'failed cmd: ${cmd}, output:\n${res.output}' assert res.exit_code == 0, 'failed cmd: ${cmd}, output:\n${res.output}'
assert res.output.split_into_lines().len > 10, 'there should be several files printed by cmd: ${cmd}' assert res.output.split_into_lines().len > 10, 'there should be several files printed by cmd: ${cmd}'

View file

@ -0,0 +1,21 @@
import os
import term
const vexe = @VEXE
const vroot = os.dir(vexe)
fn test_check_syntax_in_silent_mode() {
check_parsing_files_in_folder('vlib/v/parser/testdata/silent', '-silent -check-syntax')
}
fn check_parsing_files_in_folder(folder string, options string) {
println(term.colorize(term.magenta, '> checking .vv files in folder: `${folder}`, with `${options}` ...'))
files := os.walk_ext(os.join_path(vroot, folder), '.vv')
for f in files {
cmd := '${os.quoted_path(vexe)} ${options} ${os.quoted_path(f)}'
eprintln('> cmd: ${cmd}')
res := os.execute(cmd)
assert res.exit_code == 1, 'Command should fail silently, but did not: `${cmd}`, output:\n${res.output}'
assert res.output.trim_space() == '', 'there should be no output printed by comd: `${cmd}`'
}
}