From 1f2720ce0d43e74100ef093cd0222780e8929bab Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Mon, 31 May 2021 13:05:39 -0600 Subject: [PATCH] LibJS: Avoid undefined static cast of negative values in to_u32 If the value we get after fmod in Value::to_u32 is negative, UBSAN complains that -N is out of bounds for u32. An extra static cast to i64 makes it stop complaining. An alternative implementation could add 2^32 if the fmod'd value is negative. Caught by UBSAN and oss-fuzz. --- Userland/Libraries/LibJS/Runtime/Value.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index e2b0eac70d..0317f35882 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -637,7 +637,9 @@ u32 Value::to_u32(GlobalObject& global_object) const if (signbit(value)) int_val = -int_val; auto int32bit = fmod(int_val, NumericLimits::max() + 1.0); - return static_cast(int32bit); + // Cast to i64 here to ensure that the double --> u32 cast doesn't invoke undefined behavior + // Otherwise, negative numbers cause a UBSAN warning. + return static_cast(static_cast(int32bit)); } // 7.1.8 ToInt16 ( argument ), https://tc39.es/ecma262/#sec-toint16