Fix UB signed integer overflow in js_math_imul

- Use uint32_t arithmetics and Standard conformant conversion to
  avoid UB in js_math_imul.
- add builtin tests
- use specific object directories for SAN targets
This commit is contained in:
Charlie Gordon 2024-02-17 21:15:29 +01:00
parent 8df4327559
commit 85fb2caeae
3 changed files with 21 additions and 5 deletions

View File

@ -56,6 +56,16 @@ CONFIG_BIGNUM=y
OBJDIR=.obj OBJDIR=.obj
ifdef CONFIG_ASAN
OBJDIR:=$(OBJDIR)/asan
endif
ifdef CONFIG_MSAN
OBJDIR:=$(OBJDIR)/msan
endif
ifdef CONFIG_UBSAN
OBJDIR:=$(OBJDIR)/ubsan
endif
ifdef CONFIG_DARWIN ifdef CONFIG_DARWIN
# use clang instead of gcc # use clang instead of gcc
CONFIG_CLANG=y CONFIG_CLANG=y

View File

@ -43092,14 +43092,16 @@ static double js_math_fround(double a)
static JSValue js_math_imul(JSContext *ctx, JSValueConst this_val, static JSValue js_math_imul(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
{ {
int a, b; uint32_t a, b, c;
int32_t d;
if (JS_ToInt32(ctx, &a, argv[0])) if (JS_ToUint32(ctx, &a, argv[0]))
return JS_EXCEPTION; return JS_EXCEPTION;
if (JS_ToInt32(ctx, &b, argv[1])) if (JS_ToUint32(ctx, &b, argv[1]))
return JS_EXCEPTION; return JS_EXCEPTION;
/* purposely ignoring overflow */ c = a * b;
return JS_NewInt32(ctx, a * b); memcpy(&d, &c, sizeof(d));
return JS_NewInt32(ctx, d);
} }
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);