Browse Source

cbor: fix capacity and ptr calculation for dynarray unmarshal

Tom Solberg 10 months ago
parent
commit
90a0c834bb
1 changed files with 5 additions and 4 deletions
  1. 5 4
      core/encoding/cbor/unmarshal.odin

+ 5 - 4
core/encoding/cbor/unmarshal.odin

@@ -442,9 +442,6 @@ _unmarshal_array :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header
 		loc := #caller_location,
 		loc := #caller_location,
 	) -> (out_of_space: bool, err: Unmarshal_Error) {
 	) -> (out_of_space: bool, err: Unmarshal_Error) {
 		for idx: uintptr = 0; length == -1 || idx < uintptr(length); idx += 1 {
 		for idx: uintptr = 0; length == -1 || idx < uintptr(length); idx += 1 {
-			elem_ptr := rawptr(uintptr(da.data) + idx*uintptr(elemt.size))
-			elem     := any{elem_ptr, elemt.id}
-
 			hdr := _decode_header(d.reader) or_return
 			hdr := _decode_header(d.reader) or_return
 			
 			
 			// Double size if out of capacity.
 			// Double size if out of capacity.
@@ -459,6 +456,10 @@ _unmarshal_array :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header
 				if !ok { return false, .Out_Of_Memory }
 				if !ok { return false, .Out_Of_Memory }
 			}
 			}
 			
 			
+			// Set ptr after potential resizes to avoid invalidation.
+			elem_ptr := rawptr(uintptr(da.data) + idx*uintptr(elemt.size))
+			elem     := any{elem_ptr, elemt.id}
+
 			err = _unmarshal_value(d, elem, hdr, allocator=allocator, loc=loc)
 			err = _unmarshal_value(d, elem, hdr, allocator=allocator, loc=loc)
 			if length == -1 && err == .Break { break }
 			if length == -1 && err == .Break { break }
 			if err != nil { return }
 			if err != nil { return }
@@ -509,7 +510,7 @@ _unmarshal_array :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header
 		raw           := (^mem.Raw_Dynamic_Array)(v.data)
 		raw           := (^mem.Raw_Dynamic_Array)(v.data)
 		raw.data       = raw_data(data) 
 		raw.data       = raw_data(data) 
 		raw.len        = 0
 		raw.len        = 0
-		raw.cap        = length
+		raw.cap        = scap
 		raw.allocator  = context.allocator
 		raw.allocator  = context.allocator
 
 
 		_ = assign_array(d, raw, t.elem, length) or_return
 		_ = assign_array(d, raw, t.elem, length) or_return