From ec29c3e784abdf891abd38f42444216e3d2a0fb7 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:10:37 +0100 Subject: [PATCH] [Core] Fix property access on read-only `Dictionary` --- core/variant/variant_setget.cpp | 20 ++++++++++++------- .../runtime/errors/read_only_dictionary.gd | 4 ++++ .../runtime/errors/read_only_dictionary.out | 6 ++++++ 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.gd create mode 100644 modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.out diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 9d5ed22b1aa..f49e9e54b34 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -251,15 +251,21 @@ void Variant::set_named(const StringName &p_member, const Variant &p_value, bool return; } } else if (type == Variant::DICTIONARY) { - Variant *v = VariantGetInternalPtr::get_ptr(this)->getptr(p_member); - if (v) { - *v = p_value; - r_valid = true; - } else { - VariantGetInternalPtr::get_ptr(this)->operator[](p_member) = p_value; - r_valid = true; + Dictionary &dict = *VariantGetInternalPtr::get_ptr(this); + + if (dict.is_read_only()) { + r_valid = false; + return; } + Variant *v = dict.getptr(p_member); + if (v) { + *v = p_value; + } else { + dict[p_member] = p_value; + } + + r_valid = true; } else { r_valid = false; } diff --git a/modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.gd b/modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.gd new file mode 100644 index 00000000000..2f31ecc52f0 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.gd @@ -0,0 +1,4 @@ +func test(): + var dictionary := { "a": 0 } + dictionary.make_read_only() + dictionary.a = 1 diff --git a/modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.out b/modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.out new file mode 100644 index 00000000000..da7ce58d733 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/read_only_dictionary.out @@ -0,0 +1,6 @@ +GDTEST_RUNTIME_ERROR +>> SCRIPT ERROR +>> on function: test() +>> runtime/errors/read_only_dictionary.gd +>> 4 +>> Invalid assignment of property or key 'a' with value of type 'int' on a base object of type 'Dictionary'.