From 2884ec52de7dba99c083ebea138be3d9b7fd6e3c Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Fri, 24 Nov 2023 13:02:05 +0530 Subject: [PATCH] checker: disallow casting strings to pointers outside `unsafe` (#19977) --- vlib/v/checker/checker.v | 4 ++++ .../invalid_string_cast_to_pointers_err.out | 17 +++++++++++++++++ .../invalid_string_cast_to_pointers_err.vv | 4 ++++ 3 files changed, 25 insertions(+) create mode 100644 vlib/v/checker/tests/invalid_string_cast_to_pointers_err.out create mode 100644 vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8af22768e8..73fce34058 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3174,6 +3174,10 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { snexpr := node.expr.str() tt := c.table.type_to_str(to_type) c.error('cannot cast string to `${tt}`, use `${snexpr}[index]` instead.', node.pos) + } else if final_from_sym.kind == .string && to_type.is_pointer() && !c.inside_unsafe { + tt := c.table.type_to_str(to_type) + c.error('cannot cast string to `${tt}` outside `unsafe`, use ${tt}(s.str) instead', + node.pos) } else if final_from_sym.kind == .array && !from_type.is_ptr() && to_type != ast.string_type && !(to_type.has_flag(.option) && from_type.idx() == to_type.idx()) { ft := c.table.type_to_str(from_type) diff --git a/vlib/v/checker/tests/invalid_string_cast_to_pointers_err.out b/vlib/v/checker/tests/invalid_string_cast_to_pointers_err.out new file mode 100644 index 0000000000..4a0bc4b748 --- /dev/null +++ b/vlib/v/checker/tests/invalid_string_cast_to_pointers_err.out @@ -0,0 +1,17 @@ +vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv:2:9: error: cannot cast string to `voidptr` outside `unsafe`, use voidptr(s.str) instead + 1 | test := 'test' + 2 | println(voidptr(test)) + | ~~~~~~~~~~~~~ + 3 | println(byteptr(test)) + 4 | println(charptr(test)) +vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv:3:9: error: cannot cast string to `byteptr` outside `unsafe`, use byteptr(s.str) instead + 1 | test := 'test' + 2 | println(voidptr(test)) + 3 | println(byteptr(test)) + | ~~~~~~~~~~~~~ + 4 | println(charptr(test)) +vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv:4:9: error: cannot cast string to `charptr` outside `unsafe`, use charptr(s.str) instead + 2 | println(voidptr(test)) + 3 | println(byteptr(test)) + 4 | println(charptr(test)) + | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv b/vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv new file mode 100644 index 0000000000..00820f2a93 --- /dev/null +++ b/vlib/v/checker/tests/invalid_string_cast_to_pointers_err.vv @@ -0,0 +1,4 @@ +test := 'test' +println(voidptr(test)) +println(byteptr(test)) +println(charptr(test))