From 454bea87cff4ff3cd2fd9ae34a3718dd200ce0fb Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Sun, 17 Mar 2019 11:34:04 +0530
Subject: [PATCH 69/72] Guard against undefined behaviour when casting from
float to unsigned
Only range (-1.0, UINT64_MAX) can be safely converted to unsigned
directly, and (-INT64_MAX,INT_64_MAX) through a cast to int64_t first.
The remaining range is undefined.
TODO: Do the same for JIT as well as for float to other ranges.
---
src/lj_obj.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/lj_obj.h b/src/lj_obj.h
index c7e4742..4ff5944 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -944,12 +944,18 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n)
static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)
{
+ /* Undefined behaviour. This is deliberately not a full check because we
+ don't want to slow down compliant code. */
+ lua_assert(n >= -9223372036854775809.0);
#ifdef _MSC_VER
if (n >= 9223372036854775808.0) /* They think it's a feature. */
return (uint64_t)(int64_t)(n - 18446744073709551616.0);
else
#endif
- return (uint64_t)n;
+ if (n > -1.0)
+ return (uint64_t)n;
+ else
+ return (uint64_t)(int64_t)n;
}
static LJ_AINLINE int32_t numberVint(cTValue *o)
--
2.20.1