diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index 19761188832..3c40f42f37c 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -139,7 +139,7 @@ struct GDScriptUtilityFunctionsDefinitions { case 1: { DEBUG_VALIDATE_ARG_TYPE(0, Variant::INT); - int count = *p_args[0]; + int64_t count = *p_args[0]; Array arr; if (count <= 0) { @@ -147,10 +147,11 @@ struct GDScriptUtilityFunctionsDefinitions { return; } + GDFUNC_FAIL_COND_MSG(count > INT32_MAX, RTR("Range too big.")); Error err = arr.resize(count); GDFUNC_FAIL_COND_MSG(err != OK, RTR("Cannot resize array.")); - for (int i = 0; i < count; i++) { + for (int64_t i = 0; i < count; i++) { arr[i] = i; } @@ -160,8 +161,8 @@ struct GDScriptUtilityFunctionsDefinitions { DEBUG_VALIDATE_ARG_TYPE(0, Variant::INT); DEBUG_VALIDATE_ARG_TYPE(1, Variant::INT); - int from = *p_args[0]; - int to = *p_args[1]; + int64_t from = *p_args[0]; + int64_t to = *p_args[1]; Array arr; if (from >= to) { @@ -169,10 +170,11 @@ struct GDScriptUtilityFunctionsDefinitions { return; } + GDFUNC_FAIL_COND_MSG(to - from > INT32_MAX, RTR("Range too big.")); Error err = arr.resize(to - from); GDFUNC_FAIL_COND_MSG(err != OK, RTR("Cannot resize array.")); - for (int i = from; i < to; i++) { + for (int64_t i = from; i < to; i++) { arr[i - from] = i; } @@ -183,9 +185,9 @@ struct GDScriptUtilityFunctionsDefinitions { DEBUG_VALIDATE_ARG_TYPE(1, Variant::INT); DEBUG_VALIDATE_ARG_TYPE(2, Variant::INT); - int from = *p_args[0]; - int to = *p_args[1]; - int incr = *p_args[2]; + int64_t from = *p_args[0]; + int64_t to = *p_args[1]; + int64_t incr = *p_args[2]; VALIDATE_ARG_CUSTOM(2, Variant::INT, incr == 0, RTR("Step argument is zero!")); @@ -200,24 +202,25 @@ struct GDScriptUtilityFunctionsDefinitions { } // Calculate how many. - int count = 0; + int64_t count = 0; if (incr > 0) { count = Math::division_round_up(to - from, incr); } else { count = Math::division_round_up(from - to, -incr); } + GDFUNC_FAIL_COND_MSG(count > INT32_MAX, RTR("Range too big.")); Error err = arr.resize(count); GDFUNC_FAIL_COND_MSG(err != OK, RTR("Cannot resize array.")); if (incr > 0) { - int idx = 0; - for (int i = from; i < to; i += incr) { + int64_t idx = 0; + for (int64_t i = from; i < to; i += incr) { arr[idx++] = i; } } else { - int idx = 0; - for (int i = from; i > to; i += incr) { + int64_t idx = 0; + for (int64_t i = from; i > to; i += incr) { arr[idx++] = i; } } diff --git a/modules/gdscript/tests/scripts/runtime/features/range_large_ints.gd b/modules/gdscript/tests/scripts/runtime/features/range_large_ints.gd new file mode 100644 index 00000000000..4a13c95b2c2 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/range_large_ints.gd @@ -0,0 +1,13 @@ +func test(): + # GH-109376 + # Note: unlike "for range", which is iterated in place, this helper function generates an array of all values in range. + var result + + result = range(2147483640, 2147483647) # Range below 32-bit size limit. + print(result) + + result = range(2147483640, 2147483647 + 1) # Range 1 over 32-bit size limit. + print(result) + + result = range(9922147483640, 9922147483647) # Range significantly over 32-bit size limit. + print(result) diff --git a/modules/gdscript/tests/scripts/runtime/features/range_large_ints.out b/modules/gdscript/tests/scripts/runtime/features/range_large_ints.out new file mode 100644 index 00000000000..1ba2a72717c --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/range_large_ints.out @@ -0,0 +1,4 @@ +GDTEST_OK +[2147483640, 2147483641, 2147483642, 2147483643, 2147483644, 2147483645, 2147483646] +[2147483640, 2147483641, 2147483642, 2147483643, 2147483644, 2147483645, 2147483646, 2147483647] +[9922147483640, 9922147483641, 9922147483642, 9922147483643, 9922147483644, 9922147483645, 9922147483646]