mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
LibJS: Fix wraparound UB in Value::to_u{8,16}
If we call these two functions on a negative value, undefined behavior occurs due to casting a negative double to an unsigned integer. These functions are defined to perform modular arithmetic, so negative values can be fixed up by adding 2^8/2^16. The reason why this step is not mentioned in ECMA-262 is that it defines modular arithmetic so that `x mod m` had the same sign as `m`, while LibM's `fmod(x, m)` copies `x`'s sign. This issue was found by UBSAN with the Clang toolchain.
This commit is contained in:
parent
0a05f04d1b
commit
12dc2c2079
Notes:
sideshowbarker
2024-07-18 07:15:27 +09:00
Author: https://github.com/BertalanD Commit: https://github.com/SerenityOS/serenity/commit/12dc2c2079b Pull-request: https://github.com/SerenityOS/serenity/pull/8718 Issue: https://github.com/SerenityOS/serenity/issues/363 Reviewed-by: https://github.com/gunnarbeutner ✅ Reviewed-by: https://github.com/nico
@ -684,6 +684,8 @@ u16 Value::to_u16(GlobalObject& global_object) const
|
||||
if (signbit(value))
|
||||
int_val = -int_val;
|
||||
auto int16bit = fmod(int_val, NumericLimits<u16>::max() + 1.0);
|
||||
if (int16bit < 0)
|
||||
int16bit += NumericLimits<u16>::max() + 1.0;
|
||||
return static_cast<u16>(int16bit);
|
||||
}
|
||||
|
||||
@ -720,6 +722,8 @@ u8 Value::to_u8(GlobalObject& global_object) const
|
||||
if (signbit(value))
|
||||
int_val = -int_val;
|
||||
auto int8bit = fmod(int_val, NumericLimits<u8>::max() + 1.0);
|
||||
if (int8bit < 0)
|
||||
int8bit += NumericLimits<u8>::max() + 1.0;
|
||||
return static_cast<u8>(int8bit);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user