mirror of
https://github.com/janet-lang/janet
synced 2025-02-24 04:00:02 +00:00
int/to-number: restrict input to JANET_INTMAX/MIN
Previously int/to-number would fail if the input was outside the range of an int32. Because Janet numbers are doubles, they can safely store larger ints than an int32. This commit updates int/to-number to restrict the value to the range of integers a double can hold, instead of an int32.
This commit is contained in:
parent
88db9751d7
commit
75845c0283
@ -216,23 +216,22 @@ JANET_CORE_FN(cfun_to_number,
|
||||
|
||||
if (janet_abstract_type(abst) == &janet_s64_type) {
|
||||
int64_t value = *((int64_t*)abst);
|
||||
if (value > INT32_MAX) {
|
||||
janet_panicf("cannot convert %q to a number, exceededs int32 max", argv[0]);
|
||||
if (value > JANET_INTMAX_INT64) {
|
||||
janet_panicf("cannot convert %q to a number, must be in the range [%q, %q]", argv[0], janet_wrap_number(JANET_INTMIN_DOUBLE), janet_wrap_number(JANET_INTMAX_DOUBLE));
|
||||
}
|
||||
if (value < INT32_MIN) {
|
||||
janet_panicf("cannot convert %q to a number, exceededs int32 min", argv[0]);
|
||||
if (value < -JANET_INTMAX_INT64) {
|
||||
janet_panicf("cannot convert %q to a number, must be in the range [%q, %q]", argv[0], janet_wrap_number(JANET_INTMIN_DOUBLE), janet_wrap_number(JANET_INTMAX_DOUBLE));
|
||||
}
|
||||
|
||||
return janet_wrap_integer(value);
|
||||
return janet_wrap_number((double)value);
|
||||
}
|
||||
|
||||
if (janet_abstract_type(abst) == &janet_u64_type) {
|
||||
uint64_t value = *((uint64_t*)abst);
|
||||
if (value > INT32_MAX) {
|
||||
janet_panicf("cannot convert %q to a number, exceededs int32 max", argv[0]);
|
||||
if (value > JANET_INTMAX_INT64) {
|
||||
janet_panicf("cannot convert %q to a number, must be in the range [%q, %q]", argv[0], janet_wrap_number(JANET_INTMIN_DOUBLE), janet_wrap_number(JANET_INTMAX_DOUBLE));
|
||||
}
|
||||
|
||||
return janet_wrap_integer(value);
|
||||
return janet_wrap_number((double)value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,12 +42,17 @@
|
||||
# Conversion back to an int32
|
||||
(assert (= (int/to-number (u64 0xFaFa)) 0xFaFa))
|
||||
(assert (= (int/to-number (i64 0xFaFa)) 0xFaFa))
|
||||
(assert (= (int/to-number (u64 9007199254740991)) 9007199254740991))
|
||||
(assert (= (int/to-number (i64 9007199254740991)) 9007199254740991))
|
||||
(assert (= (int/to-number (i64 -9007199254740991)) -9007199254740991))
|
||||
|
||||
(assert-error
|
||||
"int64 out of bounds for int32"
|
||||
(do
|
||||
(int/to-number (u64 "0x7fff_ffff_ffff_ffff"))
|
||||
(int/to-number (i64 "-0x7fff_ffff_ffff_ffff"))))
|
||||
"u64 out of bounds for safe integer"
|
||||
(int/to-number (u64 "9007199254740993"))
|
||||
|
||||
(assert-error
|
||||
"s64 out of bounds for safe integer"
|
||||
(int/to-number (i64 "-9007199254740993"))))
|
||||
|
||||
(assert-error
|
||||
"int/to-number fails on non-abstract types"
|
||||
|
Loading…
x
Reference in New Issue
Block a user