Commit graph

8 commits

Author SHA1 Message Date
sideshowbarker
028eb0a966 AK: Don’t let float precision sneak past is_within_range bounds
Problem: is_within_range<I>(F value) — where I is an integer and F is a
floating-point type — is unexpectedly too permissive in some cases:

a. Values that are 1 past the integer range unexpectedly pass; e.g.,
   is_within_range<int>(2147483648.0f) returns true — even though
   2147483648 is INT_MAX + 1.

b. Fractional values whose magnitude exceeds the destination max
   unexpectedly pass; e.g., is_within_range<unsigned>(4294967295.5)
   returns true — even though 4294967295.5 > UINT_MAX.

c. Fractional values within the destination’s numeric range unexpectedly
   pass (e.g., is_within_range<int>(2.5) returns true) — even though
   they aren’t exactly representable as the destination type.

Cause: TypeBoundsChecker integer-bounds specializations compare against
NumericLimits<Destination>::max() and ::min() directly. When a caller’s
value is a float, the integer max/min get implicitly converted to a
float for the comparison. For Destination/Source pairs with the integer
extreme not exactly representable in the float, that conversion rounds
up to the next power-of-two boundary — so “value <= F(max)” accepts
values that are actually out of range by one (case a). And the
comparison itself doesn’t reject fractional values (cases b and c).

Fix: When Source is a floating-point type:

1. First gate (case a) — Compare against 2^digits; exactly representable
   in any IEEE float, and equals max + 1 for unsigned / -min for two’s-
   complement signed integers.

2. Second gate (cases b and c) – Round-trip check: cast value to
   Destination, then cast back — and require equality. Only integer-
   valued floats whose truncation matches the original pass.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/6212
2026-05-27 19:05:56 +02:00
Jelle Raaijmakers
2c78fd5b89 AK: Remove unused Checked<T> code
We could never hit the #else branches for some of these methods, because
we already relied on having __builtin_*_overflow() readily available in
earlier methods.

multiplication_would_overflow() with three arguments was only used in a
test, so let's get rid of that as well.
2025-10-22 00:26:23 +02:00
me-it-is
b76f1fb011 AK: Fix is_within_range when converting from float
Within range now uses the max capacity of a type rather than its size.
This fixes some subtests in
https://wpt.fyi/results/wasm/core/conversions.wast.js.html?product=ladybird
2025-09-24 10:40:24 +01:00
Jess
88c4f71114 AK/Checked: Dont verify overflow bit in lvalue operations
Before, adding an overflow'n `Checked<T>` to another `Checked<T>` would
cause a verification faliure when instead it should propogate m_overflow
and allow the user to handle the overflow.
2025-02-25 11:20:13 +00:00
Timothy Flynn
ec492a1a08 Everywhere: Run clang-format
The following command was used to clang-format these files:

    clang-format-18 -i $(find . \
        -not \( -path "./\.*" -prune \) \
        -not \( -path "./Base/*" -prune \) \
        -not \( -path "./Build/*" -prune \) \
        -not \( -path "./Toolchain/*" -prune \) \
        -not \( -path "./Ports/*" -prune \) \
        -type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")

There are a couple of weird cases where clang-format now thinks that a
pointer access in an initializer list, e.g. `m_member(ptr->foo)`, is a
lambda return statement, and it puts spaces around the `->`.
2024-04-24 16:50:01 -04:00
Poseydon42
d2334957ba Tests: Add tests for Checked<> decrement operator 2022-12-08 07:20:14 -05:00
Ali Mohammad Pur
aacbee8ed8 Tests: Add tests for Checked<T>::div() overflow 2021-05-07 09:26:11 +02:00
Brian Gianforcaro
67322b0702 Tests: Move AK tests to Tests/AK 2021-05-06 17:54:28 +02:00
Renamed from AK/Tests/TestChecked.cpp (Browse further)