From e42634788e6d02dade7f6a862f6d82111f1a3aec Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Mon, 18 Mar 2024 17:48:54 +0100 Subject: [PATCH] [Core] Add `set_safe` method to `Array` and `Dictionary` This returns an error, making it possible to check the behavior Also adds range checking for `Array.set` to match `Vector` and allow it to be use safely --- core/variant/array.cpp | 11 +++++++++++ core/variant/array.h | 1 + core/variant/dictionary.cpp | 8 ++++++++ core/variant/dictionary.h | 1 + tests/core/variant/test_dictionary.h | 3 +++ 5 files changed, 24 insertions(+) diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 54cd1eda2fc4..1ab6fda78616 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -428,9 +428,20 @@ void Array::set(int p_idx, const Variant &p_value) { Variant value = p_value; ERR_FAIL_COND(!_p->typed.validate(value, "set")); + ERR_FAIL_INDEX(p_idx, size()); operator[](p_idx) = value; } +Error Array::set_safe(int p_idx, const Variant &p_value) { + ERR_FAIL_COND_V_MSG(_p->read_only, ERR_LOCKED, "Array is in read-only state."); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "set"), ERR_INVALID_PARAMETER); + + ERR_FAIL_INDEX_V(p_idx, size(), ERR_PARAMETER_RANGE_ERROR); + operator[](p_idx) = value; + return OK; +} + const Variant &Array::get(int p_idx) const { return operator[](p_idx); } diff --git a/core/variant/array.h b/core/variant/array.h index 3aa957b31268..6f25ad3a2a7d 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -116,6 +116,7 @@ class Array { const Variant &operator[](int p_idx) const; void set(int p_idx, const Variant &p_value); + Error set_safe(int p_idx, const Variant &p_value); const Variant &get(int p_idx) const; int size() const; diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index d4198fbed944..164ebda0b298 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -130,6 +130,14 @@ void Dictionary::set(const Variant &p_key, const Variant &p_value) { operator[](key) = p_value; } +Error Dictionary::set_safe(const Variant &p_key, const Variant &p_value) { + ERR_FAIL_COND_V_MSG(_p->read_only, ERR_LOCKED, "Dictionary is in read-only state."); + Variant key = p_key; + ERR_FAIL_COND_V(!_p->typed_key.validate(key, "set_safe"), ERR_INVALID_PARAMETER); + operator[](key) = p_value; + return OK; +} + Variant Dictionary::get_valid(const Variant &p_key) const { Variant key = p_key; ERR_FAIL_COND_V(!_p->typed_key.validate(key, "get_valid"), Variant()); diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h index 24cbdff79397..9a1d38221320 100644 --- a/core/variant/dictionary.h +++ b/core/variant/dictionary.h @@ -57,6 +57,7 @@ class Dictionary { Variant *getptr(const Variant &p_key); void set(const Variant &p_key, const Variant &p_value); + Error set_safe(const Variant &p_key, const Variant &p_value); Variant get_valid(const Variant &p_key) const; Variant get(const Variant &p_key, const Variant &p_default) const; Variant get_or_add(const Variant &p_key, const Variant &p_default); diff --git a/tests/core/variant/test_dictionary.h b/tests/core/variant/test_dictionary.h index 350fe04079f8..14b6f0d154f1 100644 --- a/tests/core/variant/test_dictionary.h +++ b/tests/core/variant/test_dictionary.h @@ -101,6 +101,9 @@ TEST_CASE("[Dictionary] Assignment using bracket notation ([])") { map.set("This key does not exist", String()); CHECK_FALSE(map.has("This key does not exist")); CHECK(map.size() == length); + + CHECK(map.set_safe("This key does not exist", String()) == ERR_LOCKED); + CHECK(map.size() == length); ERR_PRINT_ON; }