From 242c5760f1c9caa53c9b5faef5ccbd3de59b7d4b Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 21 Jan 2021 17:17:00 +0800 Subject: [PATCH] array: fix array_clone (fix #8220) (#8238) --- vlib/builtin/array.v | 14 +++++++++++--- vlib/builtin/array_test.v | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 85f6213c58..4c95018a57 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -346,17 +346,25 @@ pub fn (a &array) clone() array { // Recursively clone-generated elements if array element is array type size_of_array := int(sizeof(array)) if a.element_size == size_of_array { + mut is_elem_array := true for i in 0 .. a.len { ar := array{} unsafe { C.memcpy(&ar, a.get_unsafe(i), size_of_array) } + if ar.len > ar.cap || ar.cap <= 0 || ar.element_size <= 0 { + is_elem_array = false + break + } ar_clone := ar.clone() unsafe { arr.set_unsafe(i, &ar_clone) } } - } else { - if !isnil(a.data) { - unsafe { C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size) } + if is_elem_array { + return arr } } + + if !isnil(a.data) { + unsafe { C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size) } + } return arr } diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 6a2a8c0c6c..abdab85c05 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -1343,3 +1343,19 @@ fn test_multi_fixed_array_with_default_init() { println(a) assert a == [[10, 10, 10]!, [10, 10, 10]!, [10, 10, 10]!]! } + +struct Abc { +mut: + x i64 + y i64 + z i64 +} + +fn test_clone_of_same_elem_size_array() { + mut arr := []Abc{} + arr << Abc{1, 2, 3} + arr << Abc{2, 3, 4} + arr2 := arr.clone() + println(arr2) + assert arr2 == [Abc{1, 2, 3}, Abc{2, 3, 4}] +}