diff --git a/Libraries/LibWeb/CSS/Parser/Token.h b/Libraries/LibWeb/CSS/Parser/Token.h index d38e501b2ce..461174faf13 100644 --- a/Libraries/LibWeb/CSS/Parser/Token.h +++ b/Libraries/LibWeb/CSS/Parser/Token.h @@ -14,6 +14,17 @@ namespace Web::CSS::Parser { +inline static double clamp_to_single_precision(double value) +{ + if (value > static_cast(NumericLimits::max())) + return static_cast(NumericLimits::max()); + + if (value < static_cast(NumericLimits::lowest())) + return static_cast(NumericLimits::lowest()); + + return value; +} + class WEB_API Token { public: enum class Type : u8 { @@ -139,7 +150,7 @@ public: double number_value() const { VERIFY(m_type == Type::Number); - return m_number_value.value(); + return clamp_to_single_precision(m_number_value.value()); } i32 to_integer() const { @@ -155,14 +166,14 @@ public: double dimension_value() const { VERIFY(m_type == Type::Dimension); - return m_number_value.value(); + return clamp_to_single_precision(m_number_value.value()); } i32 dimension_value_int() const { return m_number_value.integer_value(); } double percentage() const { VERIFY(m_type == Type::Percentage); - return m_number_value.value(); + return clamp_to_single_precision(m_number_value.value()); } Type mirror_variant() const; diff --git a/Tests/LibWeb/CSSTokenizer/expected/numeric-clamping.txt b/Tests/LibWeb/CSSTokenizer/expected/numeric-clamping.txt new file mode 100644 index 00000000000..4f91b0038a3 --- /dev/null +++ b/Tests/LibWeb/CSSTokenizer/expected/numeric-clamping.txt @@ -0,0 +1,12 @@ +Percentage(value=3.4028234663852886e+38, number_type=Number, source="1e39%", start=0:0, end=0:5) +Whitespace(source="\n", start=0:5, end=1:0) +Percentage(value=-3.4028234663852886e+38, number_type=Number, source="-1e39%", start=1:0, end=1:6) +Whitespace(source="\n", start=1:6, end=2:0) +Dimension(value=3.4028234663852886e+38, number_type=Number, unit="px", source="1e39px", start=2:0, end=2:6) +Whitespace(source="\n", start=2:6, end=3:0) +Dimension(value=-3.4028234663852886e+38, number_type=Number, unit="px", source="-1e39px", start=3:0, end=3:7) +Whitespace(source="\n", start=3:7, end=4:0) +Number(value=3.4028234663852886e+38, number_type=Number, source="1e39", start=4:0, end=4:4) +Whitespace(source="\n", start=4:4, end=5:0) +Number(value=-3.4028234663852886e+38, number_type=Number, source="-1e39", start=5:0, end=5:5) +__EOF__(source="", start=5:5, end=5:5) diff --git a/Tests/LibWeb/CSSTokenizer/input/numeric-clamping.css b/Tests/LibWeb/CSSTokenizer/input/numeric-clamping.css new file mode 100644 index 00000000000..f9ff0572496 --- /dev/null +++ b/Tests/LibWeb/CSSTokenizer/input/numeric-clamping.css @@ -0,0 +1,6 @@ +1e39% +-1e39% +1e39px +-1e39px +1e39 +-1e39 \ No newline at end of file