diff --git a/dynamodb/expression.odin b/dynamodb/expression.odin index 6568a06..d4b4d09 100644 --- a/dynamodb/expression.odin +++ b/dynamodb/expression.odin @@ -173,12 +173,14 @@ parse_key_condition_expression :: proc( eq_token := next_token(&t) or_return if eq_token != "=" { + delete(pk_name) // free on error return } pk_value_token := next_token(&t) or_return pk_value, pk_ok := resolve_attribute_value(pk_value_token, attribute_values) if !pk_ok { + delete(pk_name) // free on error return } @@ -187,12 +189,14 @@ parse_key_condition_expression :: proc( // Optional "AND ..." if and_token, has_and := tokenizer_next(&t).?; has_and { if !strings.equal_fold(and_token, "AND") { + delete(pk_name) // free on error attr_value_destroy(&pk_value) return } skc, skc_ok := parse_sort_key_condition(&t, attribute_names, attribute_values) if !skc_ok { + delete(pk_name) // free on error attr_value_destroy(&pk_value) return } @@ -228,12 +232,14 @@ parse_sort_key_condition :: proc( op_token := next_token(t) or_return operator, op_ok := parse_operator(op_token) if !op_ok { + delete(sk_name) // free on error return } value_token := next_token(t) or_return value, val_ok := resolve_attribute_value(value_token, attribute_values) if !val_ok { + delete(sk_name) // free on error return } @@ -242,18 +248,21 @@ parse_sort_key_condition :: proc( // IMPORTANT: after allocating `value`, do NOT use `or_return` without cleanup. and_token, tok_ok := next_token(t) if !tok_ok || !strings.equal_fold(and_token, "AND") { + delete(sk_name) // free on error attr_value_destroy(&value) return } value2_token, tok2_ok := next_token(t) if !tok2_ok { + delete(sk_name) // free on error attr_value_destroy(&value) return } v2, v2_ok := resolve_attribute_value(value2_token, attribute_values) if !v2_ok { + delete(sk_name) // free on error attr_value_destroy(&value) return } @@ -287,18 +296,21 @@ parse_begins_with :: proc( comma := next_token(t) or_return if comma != "," { + delete(sk_name) // free on error return } value_token := next_token(t) or_return value, val_ok := resolve_attribute_value(value_token, attribute_values) if !val_ok { + delete(sk_name) // free on error return } // after allocating `value`, avoid `or_return` so we can clean up rparen, tok_ok := next_token(t) if !tok_ok || rparen != ")" { + delete(sk_name) // free on error attr_value_destroy(&value) return } diff --git a/dynamodb/filter.odin b/dynamodb/filter.odin index 9ca3776..350fda5 100644 --- a/dynamodb/filter.odin +++ b/dynamodb/filter.odin @@ -51,6 +51,10 @@ parse_projection_expression :: proc( resolved, res_ok := resolve_attribute_name(trimmed, attribute_names) if !res_ok { + // Cleanup previously cloned strings + for path in result { + delete(path) + } delete(result) return nil, false }