Skip to content

Commit 54b2c86

Browse files
authored
builtin,cgen: ensure array of string is not cloned with depth 0 (fix #25783) (#25793)
1 parent 34d9790 commit 54b2c86

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

vlib/builtin/array.v

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,13 @@ pub fn (a &array) clone_to_depth(depth int) array {
724724
unsafe { arr.set_unsafe(i, &ar_clone) }
725725
}
726726
return arr
727+
} else if depth > 0 && a.element_size == sizeof(string) && a.len >= 0 && a.cap >= a.len {
728+
for i in 0 .. a.len {
729+
str_ptr := unsafe { &string(a.get_unsafe(i)) }
730+
str_clone := (*str_ptr).clone()
731+
unsafe { arr.set_unsafe(i, &str_clone) }
732+
}
733+
return arr
727734
} else {
728735
if a.data != 0 && source_capacity_in_bytes > 0 {
729736
unsafe { vmemcpy(&u8(arr.data), a.data, source_capacity_in_bytes) }

vlib/os/os_args_autofree_test.v

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// vtest build: !sanitize-memory-gcc && !sanitize-address-gcc && !sanitize-address-clang
2+
// vtest vflags: -autofree
3+
import os
4+
5+
fn test_os_args_no_double_free() {
6+
args := os.args
7+
assert args.len > 0
8+
}
9+
10+
fn test_os_args_clone() {
11+
a1 := os.args
12+
a2 := os.args
13+
assert a1 == a2
14+
}

vlib/v/gen/c/cgen.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8531,6 +8531,8 @@ pub fn (mut g Gen) get_array_depth(el_typ ast.Type) int {
85318531
if sym.kind == .array {
85328532
info := sym.info as ast.Array
85338533
return 1 + g.get_array_depth(info.elem_type)
8534+
} else if sym.kind in [.string, .map] {
8535+
return 1
85348536
} else {
85358537
return 0
85368538
}

0 commit comments

Comments
 (0)