From f854f644a7eaa16ec1b4f8f88580ec876a848af5 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Mon, 28 Apr 2025 10:02:57 +0100 Subject: [PATCH] LibWeb: Don't crash when interpolating non `` scale values --- Libraries/LibWeb/CSS/Interpolation.cpp | 37 +++++++------------ .../animations/scale-interpolation-crash.html | 6 +++ 2 files changed, 20 insertions(+), 23 deletions(-) create mode 100644 Tests/LibWeb/Crash/wpt-import/css/css-values/animations/scale-interpolation-crash.html diff --git a/Libraries/LibWeb/CSS/Interpolation.cpp b/Libraries/LibWeb/CSS/Interpolation.cpp index c55358ce943..d2751d12640 100644 --- a/Libraries/LibWeb/CSS/Interpolation.cpp +++ b/Libraries/LibWeb/CSS/Interpolation.cpp @@ -58,7 +58,7 @@ static NonnullRefPtr with_keyword_values_resolved(DOM::Elem return value; } -static RefPtr interpolate_scale(DOM::Element&, CSSStyleValue const& a_from, CSSStyleValue const& a_to, float delta) +static RefPtr interpolate_scale(DOM::Element& element, CalculationContext calculation_context, CSSStyleValue const& a_from, CSSStyleValue const& a_to, float delta) { if (a_from.to_keyword() == Keyword::None && a_to.to_keyword() == Keyword::None) return a_from; @@ -71,30 +71,21 @@ static RefPtr interpolate_scale(DOM::Element&, CSSStyleValu auto const& from_transform = from.as_transformation(); auto const& to_transform = to.as_transformation(); - auto from_x = from_transform.values()[0]->as_number().value(); - auto to_x = to_transform.values()[0]->as_number().value(); - auto from_y = from_transform.values()[1]->as_number().value(); - auto to_y = to_transform.values()[1]->as_number().value(); + auto interpolated_x = interpolate_value(element, calculation_context, from_transform.values()[0], to_transform.values()[0], delta); + auto interpolated_y = interpolate_value(element, calculation_context, from_transform.values()[1], to_transform.values()[1], delta); - Optional from_z; - Optional to_z; - if (from_transform.values().size() == 3) { - from_z = from_transform.values()[2]->as_number().value(); - } - if (to_transform.values().size() == 3) { - to_z = to_transform.values()[2]->as_number().value(); - } - Optional new_z; - if (from_z.has_value() || to_z.has_value()) { - new_z = interpolate_raw(from_z.value_or(1), to_z.value_or(1), delta); + RefPtr interpolated_z; + + if (from_transform.values().size() == 3 || to_transform.values().size() == 3) { + static auto one_value = NumberStyleValue::create(1); + auto from = from_transform.values().size() == 3 ? from_transform.values()[2] : one_value; + auto to = to_transform.values().size() == 3 ? to_transform.values()[2] : one_value; + interpolated_z = interpolate_value(element, calculation_context, from, to, delta); } - auto new_x = NumberStyleValue::create(interpolate_raw(from_x, to_x, delta)); - auto new_y = NumberStyleValue::create(interpolate_raw(from_y, to_y, delta)); - - StyleValueVector new_values = { new_x, new_y }; - if (new_z.has_value() && new_z.value() != 1) { - new_values.append(NumberStyleValue::create(new_z.value())); + StyleValueVector new_values = { interpolated_x, interpolated_y }; + if (interpolated_z && interpolated_z->is_number() && interpolated_z->as_number().number() != 1) { + new_values.append(*interpolated_z); } return TransformationStyleValue::create( @@ -135,7 +126,7 @@ ValueComparingRefPtr interpolate_property(DOM::Element& ele return interpolate_box_shadow(element, calculation_context, from, to, delta); if (property_id == PropertyID::Scale) - return interpolate_scale(element, from, to, delta); + return interpolate_scale(element, calculation_context, from, to, delta); // FIXME: Handle all custom animatable properties [[fallthrough]]; diff --git a/Tests/LibWeb/Crash/wpt-import/css/css-values/animations/scale-interpolation-crash.html b/Tests/LibWeb/Crash/wpt-import/css/css-values/animations/scale-interpolation-crash.html new file mode 100644 index 00000000000..408d6eaec22 --- /dev/null +++ b/Tests/LibWeb/Crash/wpt-import/css/css-values/animations/scale-interpolation-crash.html @@ -0,0 +1,6 @@ + + +