From d77669da80e4093cfaa74beaf053c51555bec5f1 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Mon, 5 Oct 2020 21:10:51 +0530 Subject: [PATCH] test: add tests for disallowing map/array get element/key address (#6568) --- vlib/builtin/map_test.v | 11 ---------- vlib/v/ast/ast.v | 2 +- vlib/v/checker/checker.v | 16 +++++++-------- .../tests/array_get_element_address_err.out | 7 +++++++ .../tests/array_get_element_address_err.vv | 5 +++++ .../tests/map_get_value_address_err.out | 14 +++++++++++++ .../tests/map_get_value_address_err.vv | 7 +++++++ vlib/v/tests/unsafe_test.v | 20 ++++++++++++------- 8 files changed, 54 insertions(+), 28 deletions(-) create mode 100644 vlib/v/checker/tests/array_get_element_address_err.out create mode 100644 vlib/v/checker/tests/array_get_element_address_err.vv create mode 100644 vlib/v/checker/tests/map_get_value_address_err.out create mode 100644 vlib/v/checker/tests/map_get_value_address_err.vv diff --git a/vlib/builtin/map_test.v b/vlib/builtin/map_test.v index 1bbd0deda2..14d36b25d3 100644 --- a/vlib/builtin/map_test.v +++ b/vlib/builtin/map_test.v @@ -182,17 +182,6 @@ fn test_delete() { println('two' in m) // => true, on Linux and Windows <-- wrong ! } -/* -fn test_ref() { - m := { 'one': 1 } - // TODO "cannot take the address of m['one']" - mut one := &m['one'] - one++ - println(*one) - -} -*/ - fn test_delete_size() { arr := ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] mut m := map[string]int diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 39107d66ed..6e28b33efe 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -471,7 +471,7 @@ pub struct IndexExpr { pub: pos token.Position left Expr - index Expr // [0] or RangeExpr [start..end] + index Expr // [0], RangeExpr [start..end] or map[key] pub mut: left_type table.Type // array, map, fixed array is_setter bool diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index e71fe8a03b..c3c5e96cbd 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -123,15 +123,13 @@ pub fn (mut c Checker) check_files(ast_files []ast.File) { mut has_main_fn := false mut files_from_main_module := []&ast.File{} for i in 0 .. ast_files.len { - unsafe { - file := &ast_files[i] - c.check(file) - if file.mod.name == 'main' { - files_from_main_module << file - has_main_mod_file = true - if c.check_file_in_main(file) { - has_main_fn = true - } + file := unsafe {&ast_files[i]} + c.check(file) + if file.mod.name == 'main' { + files_from_main_module << file + has_main_mod_file = true + if c.check_file_in_main(file) { + has_main_fn = true } } } diff --git a/vlib/v/checker/tests/array_get_element_address_err.out b/vlib/v/checker/tests/array_get_element_address_err.out new file mode 100644 index 0000000000..dfb520089b --- /dev/null +++ b/vlib/v/checker/tests/array_get_element_address_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_get_element_address_err.vv:3:20: error: cannot get address of array elements outside unsafe blocks + 1 | fn main() { + 2 | arr_int := [int(23), 45, 7, 8] + 3 | ele := &arr_int[1] + | ~~~ + 4 | println(ele) + 5 | } diff --git a/vlib/v/checker/tests/array_get_element_address_err.vv b/vlib/v/checker/tests/array_get_element_address_err.vv new file mode 100644 index 0000000000..78a3ce5b7e --- /dev/null +++ b/vlib/v/checker/tests/array_get_element_address_err.vv @@ -0,0 +1,5 @@ +fn main() { + arr_int := [int(23), 45, 7, 8] + ele := &arr_int[1] + println(ele) +} diff --git a/vlib/v/checker/tests/map_get_value_address_err.out b/vlib/v/checker/tests/map_get_value_address_err.out new file mode 100644 index 0000000000..08e11dfc1f --- /dev/null +++ b/vlib/v/checker/tests/map_get_value_address_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/map_get_value_address_err.vv:3:12: error: cannot get address of map values outside unsafe blocks + 1 | fn main() { + 2 | m := {'key' : 3} + 3 | a := &m['key'] + | ~~~~~~~ + 4 | b := &{'foo': 4}['foo'] + 5 | println(a) +vlib/v/checker/tests/map_get_value_address_err.vv:4:21: error: cannot get address of map values outside unsafe blocks + 2 | m := {'key' : 3} + 3 | a := &m['key'] + 4 | b := &{'foo': 4}['foo'] + | ~~~~~~~ + 5 | println(a) + 6 | println(b) diff --git a/vlib/v/checker/tests/map_get_value_address_err.vv b/vlib/v/checker/tests/map_get_value_address_err.vv new file mode 100644 index 0000000000..7f984e1541 --- /dev/null +++ b/vlib/v/checker/tests/map_get_value_address_err.vv @@ -0,0 +1,7 @@ +fn main() { + m := {'key' : 3} + a := &m['key'] + b := &{'foo': 4}['foo'] + println(a) + println(b) +} diff --git a/vlib/v/tests/unsafe_test.v b/vlib/v/tests/unsafe_test.v index 1391c3ce9f..4e72ccbb26 100644 --- a/vlib/v/tests/unsafe_test.v +++ b/vlib/v/tests/unsafe_test.v @@ -30,18 +30,13 @@ fn (s S1) f() { fn test_funcs() { s := S1{} - unsafe { - s.f() - } + unsafe {s.f()} _ = C.strerror(0) // [trusted] function prototype in builtin/cfns.c.v } fn test_if_expr_unsafe() { i := 4 - p := if true { - unsafe {&i} - } - else {unsafe {&i}} + p := if true { unsafe {&i} } else { unsafe {&i} } assert *p == 4 } @@ -54,3 +49,14 @@ fn test_unsafe_if_stmt() int { } return i } + +fn test_map_address_index() { + m := { + 'one': 1 + } + unsafe { + mut one := &m['one'] + one++ + println(*one) + } +}