Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibWeb: Handle calculations without a context better #1827

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Tests/LibWeb/Text/expected/css/calc-missing-context.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NO CRASH
15 changes: 15 additions & 0 deletions Tests/LibWeb/Text/input/css/calc-missing-context.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script src="../include.js"></script>
<script>
test(() => {
const testElement = document.getElementById('target');
testElement.style = "";

testElement.style.transform = 'rotate(atan2(1rem, -1rem))';

getComputedStyle(testElement).transform;

println("NO CRASH");

});
</script>
<div id="target"></div>
5 changes: 4 additions & 1 deletion Userland/Libraries/LibWeb/CSS/Length.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,14 @@ class Length {
{
if (is_auto())
return 0;
if (is_absolute())
return absolute_length_to_px();
if (is_font_relative())
return font_relative_length_to_px(font_metrics, root_font_metrics);
if (is_viewport_relative())
return viewport_relative_length_to_px(viewport_rect);
return absolute_length_to_px();

VERIFY_NOT_REACHED();
}

ALWAYS_INLINE CSSPixels absolute_length_to_px() const
Expand Down
23 changes: 21 additions & 2 deletions Userland/Libraries/LibWeb/CSS/StyleValues/CSSMathValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,23 @@ static double resolve_value(CSSMathValue::CalculationResult::Value value, Option
[](Angle const& angle) { return angle.to_degrees(); },
[](Flex const& flex) { return flex.to_fr(); },
[](Frequency const& frequency) { return frequency.to_hertz(); },
[&context](Length const& length) { return length.to_px(*context).to_double(); },
[](Percentage const& percentage) { return percentage.value(); },
[](Resolution const& resolution) { return resolution.to_dots_per_pixel(); },
[](Time const& time) { return time.to_seconds(); });
[](Time const& time) { return time.to_seconds(); },
[&context](Length const& length) {
// Handle some common cases first, so we can resolve more without a context
if (length.is_auto())
return 0.0;

if (length.is_absolute())
return length.absolute_length_to_px().to_double();

// If we dont have a context, we cant resolve the length, so return NAN
if (!context.has_value())
return Number(Number::Type::Number, NAN).value();

return length.to_px(*context).to_double();
});
}

static Optional<CSSNumericType> add_the_types(Vector<NonnullOwnPtr<CalculationNode>> const& nodes, PropertyID property_id)
Expand Down Expand Up @@ -2390,6 +2403,12 @@ void CSSMathValue::CalculationResult::add_or_subtract_internal(SumOperation op,
}
},
[&](Length const& length) {
if (!context.has_value()) {
dbgln("CSSMathValue::CalculationResult::add_or_subtract_internal: Length without context");
m_value = Length::make_px(0);
return;
}

auto this_px = length.to_px(*context);
if (other.m_value.has<Length>()) {
auto other_px = other.m_value.get<Length>().to_px(*context);
Expand Down
Loading