Fix UB signed integer overflow

This commit is contained in:
Ben Noordhuis 2023-11-01 09:26:15 +01:00
parent 4a8372a709
commit d6fbd6b744
2 changed files with 8 additions and 2 deletions

View file

@ -41883,8 +41883,10 @@ static JSValue js_math_imul(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION; return JS_EXCEPTION;
if (JS_ToInt32(ctx, &b, argv[1])) if (JS_ToInt32(ctx, &b, argv[1]))
return JS_EXCEPTION; return JS_EXCEPTION;
/* purposely ignoring overflow */ /* TODO(bnoordhuis) Signed integral narrowing has implementation-defined
return JS_NewInt32(ctx, a * b); * behavior but that's a step up from the undefined behavior it replaced.
*/
return JS_NewInt32(ctx, (int64_t)a * (int64_t)b);
} }
static JSValue js_math_clz32(JSContext *ctx, JSValueConst this_val, static JSValue js_math_clz32(JSContext *ctx, JSValueConst this_val,

View file

@ -311,6 +311,10 @@ function test_math()
assert(Math.floor(a), 1); assert(Math.floor(a), 1);
assert(Math.ceil(a), 2); assert(Math.ceil(a), 2);
assert(Math.imul(0x12345678, 123), -1088058456); assert(Math.imul(0x12345678, 123), -1088058456);
assert(Math.imul(0xB505, 0xB504), 2147441940);
assert(Math.imul(0xB505, 0xB505), -2147479015);
assert(Math.imul((-2)**31, (-2)**31), 0);
assert(Math.imul(2**31-1, 2**31-1), 1);
assert(Math.fround(0.1), 0.10000000149011612); assert(Math.fround(0.1), 0.10000000149011612);
assert(Math.hypot() == 0); assert(Math.hypot() == 0);
assert(Math.hypot(-2) == 2); assert(Math.hypot(-2) == 2);