From ac10f504e467053861fcf00b86bbb2904ddadafe Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 13 Mar 2024 15:12:14 +0000 Subject: [PATCH] Add infinite loop check and early out in `map_insert_hash_dynamic` --- base/runtime/dynamic_map_internal.odin | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/base/runtime/dynamic_map_internal.odin b/base/runtime/dynamic_map_internal.odin index 6955f4a1e..5ecf2207f 100644 --- a/base/runtime/dynamic_map_internal.odin +++ b/base/runtime/dynamic_map_internal.odin @@ -391,7 +391,8 @@ map_alloc_dynamic :: proc "odin" (info: ^Map_Info, log2_capacity: uintptr, alloc // arrays to reduce variance. This swapping can only be done with memcpy since // there is no type information. // -// This procedure returns the address of the just inserted value. +// This procedure returns the address of the just inserted value, and will +// return 'nil' if there was no room to insert the entry @(require_results) map_insert_hash_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, ik: uintptr, iv: uintptr) -> (result: uintptr) { h := h @@ -415,6 +416,11 @@ map_insert_hash_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^ tv := map_cell_index_dynamic(sv, info.vs, 1) swap_loop: for { + if distance > mask + // Failed to find an empty slot and prevent infinite loop + return 0 + } + element_hash := hs[pos] if map_hash_is_empty(element_hash) { @@ -898,7 +904,9 @@ __dynamic_map_set :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_In } result := map_insert_hash_dynamic(m, info, hash, uintptr(key), uintptr(value)) - m.len += 1 + if result != 0 { + m.len += 1 + } return rawptr(result) } __dynamic_map_set_extra_without_hash :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, key, value: rawptr, loc := #caller_location) -> (prev_key_ptr, value_ptr: rawptr) { @@ -921,7 +929,9 @@ __dynamic_map_set_extra :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^ } result := map_insert_hash_dynamic(m, info, hash, uintptr(key), uintptr(value)) - m.len += 1 + if result != 0 { + m.len += 1 + } return nil, rawptr(result) }