diff options
author | Thaddeus Crews <repiteo@outlook.com> | 2024-11-21 17:56:44 -0600 |
---|---|---|
committer | Thaddeus Crews <repiteo@outlook.com> | 2024-11-21 17:56:44 -0600 |
commit | d11c1a4c0091b38d9c046f7d5c8b7711e2ba3d4c (patch) | |
tree | 61fa5e0a54a2e474a945f1c93cad44adc90cc77c | |
parent | 1117d9170498e85510d8a19b0efb01c723a294c1 (diff) | |
parent | 0524e29b5cf9b4b099e7f2a7be09f21fd80e1e14 (diff) | |
download | redot-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
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 '%'. |