Browse Source

Merge pull request #74730 from MarioLiebisch/fix-74726

Fix read-only dictionaries adding missing keys
Rémi Verschelde 2 years ago
parent
commit
867ea7fe59
2 changed files with 15 additions and 2 deletions
  1. 9 2
      core/variant/dictionary.cpp
  2. 6 0
      tests/core/variant/test_dictionary.h

+ 9 - 2
core/variant/dictionary.cpp

@@ -83,9 +83,16 @@ Variant &Dictionary::operator[](const Variant &p_key) {
 	if (unlikely(_p->read_only)) {
 		if (p_key.get_type() == Variant::STRING_NAME) {
 			const StringName *sn = VariantInternal::get_string_name(&p_key);
-			*_p->read_only = _p->variant_map[sn->operator String()];
-		} else {
+			const String &key = sn->operator String();
+			if (likely(_p->variant_map.has(key))) {
+				*_p->read_only = _p->variant_map[key];
+			} else {
+				*_p->read_only = Variant();
+			}
+		} else if (likely(_p->variant_map.has(p_key))) {
 			*_p->read_only = _p->variant_map[p_key];
+		} else {
+			*_p->read_only = Variant();
 		}
 
 		return *_p->read_only;

+ 6 - 0
tests/core/variant/test_dictionary.h

@@ -88,6 +88,12 @@ TEST_CASE("[Dictionary] Assignment using bracket notation ([])") {
 	CHECK(int(map[0]) == 400);
 	// Check that assigning 0 doesn't overwrite the value for `false`.
 	CHECK(int(map[false]) == 128);
+
+	// Ensure read-only maps aren't modified by non-existing keys.
+	const auto length = map.size();
+	map.make_read_only();
+	CHECK(int(map["This key does not exist"].get_type()) == Variant::NIL);
+	CHECK(map.size() == length);
 }
 
 TEST_CASE("[Dictionary] get_key_lists()") {