summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThaddeus Crews <repiteo@outlook.com>2024-11-21 17:56:44 -0600
committerThaddeus Crews <repiteo@outlook.com>2024-11-21 17:56:44 -0600
commitd11c1a4c0091b38d9c046f7d5c8b7711e2ba3d4c (patch)
tree61fa5e0a54a2e474a945f1c93cad44adc90cc77c
parent1117d9170498e85510d8a19b0efb01c723a294c1 (diff)
parent0524e29b5cf9b4b099e7f2a7be09f21fd80e1e14 (diff)
downloadredot-engine-d11c1a4c0091b38d9c046f7d5c8b7711e2ba3d4c.tar.gz
Merge pull request #95172 from Chaosus/gdscript_fix_vector_division_by_zero_crash
Fix crash when division by zero/modulo by zero happen on vectors
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp21
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/division_by_zero.gd3
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/division_by_zero.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.gd3
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.out6
5 files changed, 37 insertions, 2 deletions
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp
index b77c641eb5..fb4d27caab 100644
--- a/modules/gdscript/gdscript_byte_codegen.cpp
+++ b/modules/gdscript/gdscript_byte_codegen.cpp
@@ -585,8 +585,25 @@ void GDScriptByteCodeGenerator::write_unary_operator(const Address &p_target, Va
}
void GDScriptByteCodeGenerator::write_binary_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) {
- // Avoid validated evaluator for modulo and division when operands are int, since there's no check for division by zero.
- if (HAS_BUILTIN_TYPE(p_left_operand) && HAS_BUILTIN_TYPE(p_right_operand) && ((p_operator != Variant::OP_DIVIDE && p_operator != Variant::OP_MODULE) || p_left_operand.type.builtin_type != Variant::INT || p_right_operand.type.builtin_type != Variant::INT)) {
+ bool valid = HAS_BUILTIN_TYPE(p_left_operand) && HAS_BUILTIN_TYPE(p_right_operand);
+
+ // Avoid validated evaluator for modulo and division when operands are int or integer vector, since there's no check for division by zero.
+ if (valid && (p_operator == Variant::OP_DIVIDE || p_operator == Variant::OP_MODULE)) {
+ switch (p_left_operand.type.builtin_type) {
+ case Variant::INT:
+ valid = p_right_operand.type.builtin_type != Variant::INT;
+ break;
+ case Variant::VECTOR2I:
+ case Variant::VECTOR3I:
+ case Variant::VECTOR4I:
+ valid = p_right_operand.type.builtin_type != Variant::INT && p_right_operand.type.builtin_type != p_left_operand.type.builtin_type;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (valid) {
if (p_target.mode == Address::TEMPORARY) {
Variant::Type result_type = Variant::get_operator_return_type(p_operator, p_left_operand.type.builtin_type, p_right_operand.type.builtin_type);
Variant::Type temp_type = temporaries[p_target.address].type;
diff --git a/modules/gdscript/tests/scripts/runtime/errors/division_by_zero.gd b/modules/gdscript/tests/scripts/runtime/errors/division_by_zero.gd
new file mode 100644
index 0000000000..ace5397f40
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/division_by_zero.gd
@@ -0,0 +1,3 @@
+func test():
+ var integer: int = 1
+ integer /= 0
diff --git a/modules/gdscript/tests/scripts/runtime/errors/division_by_zero.out b/modules/gdscript/tests/scripts/runtime/errors/division_by_zero.out
new file mode 100644
index 0000000000..6a9d11cd77
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/division_by_zero.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/division_by_zero.gd
+>> 3
+>> Division by zero error in operator '/'.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.gd b/modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.gd
new file mode 100644
index 0000000000..99792e4e32
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.gd
@@ -0,0 +1,3 @@
+func test():
+ var integer: int = 1
+ integer %= 0
diff --git a/modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.out b/modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.out
new file mode 100644
index 0000000000..79c512888f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/modulo_by_zero.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/modulo_by_zero.gd
+>> 3
+>> Modulo by zero error in operator '%'.