From 06ed6a2c976c831cece33682efe457dddbcc89b3 Mon Sep 17 00:00:00 2001 From: biondizzle Date: Mon, 16 Feb 2026 03:11:11 -0500 Subject: [PATCH] free clones via delete instead of free --- dynamodb/expression.odin | 11 ++++++++--- dynamodb/filter.odin | 2 +- main.odin | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/dynamodb/expression.odin b/dynamodb/expression.odin index 623a6bc..6568a06 100644 --- a/dynamodb/expression.odin +++ b/dynamodb/expression.odin @@ -32,6 +32,7 @@ Sort_Key_Condition :: struct { } sort_key_condition_destroy :: proc(skc: ^Sort_Key_Condition) { + delete(skc.sk_name) // Free the cloned string attr_value_destroy(&skc.value) if v2, ok := skc.value2.?; ok { v2_copy := v2 @@ -46,6 +47,7 @@ Key_Condition :: struct { } key_condition_destroy :: proc(kc: ^Key_Condition) { + delete(kc.pk_name) // Free the cloned string attr_value_destroy(&kc.pk_value) if skc, ok := kc.sk_condition.?; ok { skc_copy := skc @@ -166,7 +168,8 @@ parse_key_condition_expression :: proc( t := tokenizer_init(expression) pk_name_token := next_token(&t) or_return - pk_name := resolve_attribute_name(pk_name_token, attribute_names) or_return + pk_name_unowned := resolve_attribute_name(pk_name_token, attribute_names) or_return + pk_name := strings.clone(pk_name_unowned) // Clone for safe storage eq_token := next_token(&t) or_return if eq_token != "=" { @@ -219,7 +222,8 @@ parse_sort_key_condition :: proc( return } - sk_name := resolve_attribute_name(first_token, attribute_names) or_return + sk_name_unowned := resolve_attribute_name(first_token, attribute_names) or_return + sk_name := strings.clone(sk_name_unowned) // Clone for safe storage op_token := next_token(t) or_return operator, op_ok := parse_operator(op_token) @@ -278,7 +282,8 @@ parse_begins_with :: proc( } sk_name_token := next_token(t) or_return - sk_name := resolve_attribute_name(sk_name_token, attribute_names) or_return + sk_name_unowned := resolve_attribute_name(sk_name_token, attribute_names) or_return + sk_name := strings.clone(sk_name_unowned) // Clone for safe storage comma := next_token(t) or_return if comma != "," { diff --git a/dynamodb/filter.odin b/dynamodb/filter.odin index 5b1bfaf..9ca3776 100644 --- a/dynamodb/filter.odin +++ b/dynamodb/filter.odin @@ -54,7 +54,7 @@ parse_projection_expression :: proc( delete(result) return nil, false } - append(&result, resolved) + append(&result, strings.clone(resolved)) // Clone for safe storage } return result[:], true diff --git a/main.odin b/main.odin index ef9af77..da21480 100644 --- a/main.odin +++ b/main.odin @@ -1198,6 +1198,15 @@ handle_query :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, r // Apply ProjectionExpression projection, has_proj := dynamodb.parse_projection_expression(request.body, attr_names) + defer { // This block just frees the cloned string and projection slice + if has_proj && len(projection) > 0 { + for path in projection { + delete(path) // Free each cloned string + } + delete(projection) // Free the slice + } + } + final_items: []dynamodb.Item if has_proj && len(projection) > 0 { @@ -1237,6 +1246,15 @@ handle_query :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, r // ---- Apply ProjectionExpression ---- projection, has_proj := dynamodb.parse_projection_expression(request.body, attr_names) + defer { // This block just frees the cloned string and projection slice + if has_proj && len(projection) > 0 { + for path in projection { + delete(path) // Free each cloned string + } + delete(projection) // Free the slice + } + } + final_items: []dynamodb.Item if has_proj && len(projection) > 0 { @@ -1342,6 +1360,15 @@ handle_scan :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, re scanned_count := len(result.items) projection, has_proj := dynamodb.parse_projection_expression(request.body, attr_names) + defer { // This block just frees the cloned string and projection slice + if has_proj && len(projection) > 0 { + for path in projection { + delete(path) // Free each cloned string + } + delete(projection) // Free the slice + } + } + final_items: []dynamodb.Item if has_proj && len(projection) > 0 { @@ -1381,6 +1408,15 @@ handle_scan :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, re // ---- Apply ProjectionExpression ---- projection, has_proj := dynamodb.parse_projection_expression(request.body, attr_names) + defer { // This block just frees the cloned string and projection slice + if has_proj && len(projection) > 0 { + for path in projection { + delete(path) // Free each cloned string + } + delete(projection) // Free the slice + } + } + final_items: []dynamodb.Item if has_proj && len(projection) > 0 {