You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
[GDScript] Correctly report invalid read-only access
This commit is contained in:
@@ -3515,6 +3515,17 @@ bool Variant::is_shared() const {
|
|||||||
return is_type_shared(type);
|
return is_type_shared(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Variant::is_read_only() const {
|
||||||
|
switch (type) {
|
||||||
|
case ARRAY:
|
||||||
|
return reinterpret_cast<const Array *>(_data._mem)->is_read_only();
|
||||||
|
case DICTIONARY:
|
||||||
|
return reinterpret_cast<const Dictionary *>(_data._mem)->is_read_only();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Variant::_variant_call_error(const String &p_method, Callable::CallError &error) {
|
void Variant::_variant_call_error(const String &p_method, Callable::CallError &error) {
|
||||||
switch (error.error) {
|
switch (error.error) {
|
||||||
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
|
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
|
||||||
|
|||||||
@@ -349,6 +349,7 @@ public:
|
|||||||
bool is_zero() const;
|
bool is_zero() const;
|
||||||
bool is_one() const;
|
bool is_one() const;
|
||||||
bool is_null() const;
|
bool is_null() const;
|
||||||
|
bool is_read_only() const;
|
||||||
|
|
||||||
// Make sure Variant is not implicitly cast when accessing it with bracket notation (GH-49469).
|
// Make sure Variant is not implicitly cast when accessing it with bracket notation (GH-49469).
|
||||||
Variant &operator[](const Variant &p_key) = delete;
|
Variant &operator[](const Variant &p_key) = delete;
|
||||||
|
|||||||
@@ -884,6 +884,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
|
if (dst->is_read_only()) {
|
||||||
|
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
|
||||||
|
} else {
|
||||||
Object *obj = dst->get_validated_object();
|
Object *obj = dst->get_validated_object();
|
||||||
String v = index->operator String();
|
String v = index->operator String();
|
||||||
bool read_only_property = false;
|
bool read_only_property = false;
|
||||||
@@ -903,6 +906,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
err_text = "Invalid assignment of index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
|
err_text = "Invalid assignment of index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
OPCODE_BREAK;
|
OPCODE_BREAK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -926,6 +930,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
|
if (dst->is_read_only()) {
|
||||||
|
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
|
||||||
|
} else {
|
||||||
String v = index->operator String();
|
String v = index->operator String();
|
||||||
if (!v.is_empty()) {
|
if (!v.is_empty()) {
|
||||||
v = "'" + v + "'";
|
v = "'" + v + "'";
|
||||||
@@ -933,6 +940,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
v = "of type '" + _get_var_type(index) + "'";
|
v = "of type '" + _get_var_type(index) + "'";
|
||||||
}
|
}
|
||||||
err_text = "Invalid assignment of property or key " + v + " with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
|
err_text = "Invalid assignment of property or key " + v + " with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
|
||||||
|
}
|
||||||
OPCODE_BREAK;
|
OPCODE_BREAK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -958,6 +966,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (oob) {
|
if (oob) {
|
||||||
|
if (dst->is_read_only()) {
|
||||||
|
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
|
||||||
|
} else {
|
||||||
String v = index->operator String();
|
String v = index->operator String();
|
||||||
if (!v.is_empty()) {
|
if (!v.is_empty()) {
|
||||||
v = "'" + v + "'";
|
v = "'" + v + "'";
|
||||||
@@ -965,6 +976,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
v = "of type '" + _get_var_type(index) + "'";
|
v = "of type '" + _get_var_type(index) + "'";
|
||||||
}
|
}
|
||||||
err_text = "Out of bounds set index " + v + " (on base: '" + _get_var_type(dst) + "')";
|
err_text = "Out of bounds set index " + v + " (on base: '" + _get_var_type(dst) + "')";
|
||||||
|
}
|
||||||
OPCODE_BREAK;
|
OPCODE_BREAK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1092,6 +1104,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
|
if (dst->is_read_only()) {
|
||||||
|
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
|
||||||
|
} else {
|
||||||
Object *obj = dst->get_validated_object();
|
Object *obj = dst->get_validated_object();
|
||||||
bool read_only_property = false;
|
bool read_only_property = false;
|
||||||
if (obj) {
|
if (obj) {
|
||||||
@@ -1102,6 +1117,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
} else {
|
} else {
|
||||||
err_text = "Invalid assignment of property or key '" + String(*index) + "' with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
|
err_text = "Invalid assignment of property or key '" + String(*index) + "' with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
OPCODE_BREAK;
|
OPCODE_BREAK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
|
|||||||
>> on function: test()
|
>> on function: test()
|
||||||
>> runtime/errors/constant_array_is_deep.gd
|
>> runtime/errors/constant_array_is_deep.gd
|
||||||
>> 6
|
>> 6
|
||||||
>> Invalid assignment of property or key '0' with value of type 'int' on a base object of type 'Dictionary'.
|
>> Invalid assignment on read-only value (on base: 'Dictionary').
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
|
|||||||
>> on function: test()
|
>> on function: test()
|
||||||
>> runtime/errors/constant_dictionary_is_deep.gd
|
>> runtime/errors/constant_dictionary_is_deep.gd
|
||||||
>> 6
|
>> 6
|
||||||
>> Invalid assignment of index '0' (on base: 'Array') with value of type 'int'.
|
>> Invalid assignment on read-only value (on base: 'Array').
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
|
|||||||
>> on function: test()
|
>> on function: test()
|
||||||
>> runtime/errors/read_only_dictionary.gd
|
>> runtime/errors/read_only_dictionary.gd
|
||||||
>> 4
|
>> 4
|
||||||
>> Invalid assignment of property or key 'a' with value of type 'int' on a base object of type 'Dictionary'.
|
>> Invalid assignment on read-only value (on base: 'Dictionary').
|
||||||
|
|||||||
Reference in New Issue
Block a user