mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 08:39:22 +00:00
LibWeb: Verify that save/restore are balanced within paintable
Unbalanced save/restore within display list items recorded for a paintable means that some state only relevant for the paintable leaks to subsequent paintables, which is never expected behavior.
This commit is contained in:
parent
ac4151a00b
commit
3dffd71695
Notes:
github-actions[bot]
2025-07-06 17:22:32 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 3dffd71695
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5329
3 changed files with 15 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023-2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
* Copyright (c) 2023-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -275,16 +275,19 @@ void DisplayListRecorder::translate(Gfx::IntPoint delta)
|
||||||
|
|
||||||
void DisplayListRecorder::save()
|
void DisplayListRecorder::save()
|
||||||
{
|
{
|
||||||
|
++m_save_nesting_level;
|
||||||
append(Save {});
|
append(Save {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::save_layer()
|
void DisplayListRecorder::save_layer()
|
||||||
{
|
{
|
||||||
|
++m_save_nesting_level;
|
||||||
append(SaveLayer {});
|
append(SaveLayer {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListRecorder::restore()
|
void DisplayListRecorder::restore()
|
||||||
{
|
{
|
||||||
|
--m_save_nesting_level;
|
||||||
append(Restore {});
|
append(Restore {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,6 +422,8 @@ void DisplayListRecorder::apply_opacity(float opacity)
|
||||||
|
|
||||||
void DisplayListRecorder::apply_compositing_and_blending_operator(Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
void DisplayListRecorder::apply_compositing_and_blending_operator(Gfx::CompositingAndBlendingOperator compositing_and_blending_operator)
|
||||||
{
|
{
|
||||||
|
// Implementation of this item does saveLayer(), so we need to increment the nesting level.
|
||||||
|
m_save_nesting_level++;
|
||||||
append(ApplyCompositeAndBlendingOperator { .compositing_and_blending_operator = compositing_and_blending_operator });
|
append(ApplyCompositeAndBlendingOperator { .compositing_and_blending_operator = compositing_and_blending_operator });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023-2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
* Copyright (c) 2023-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -161,6 +161,8 @@ public:
|
||||||
|
|
||||||
void append(Command&& command);
|
void append(Command&& command);
|
||||||
|
|
||||||
|
int m_save_nesting_level { 0 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<Optional<i32>> m_scroll_frame_id_stack;
|
Vector<Optional<i32>> m_scroll_frame_id_stack;
|
||||||
DisplayList& m_command_list;
|
DisplayList& m_command_list;
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2022, Andreas Kling <andreas@ladybird.org>
|
* Copyright (c) 2020-2022, Andreas Kling <andreas@ladybird.org>
|
||||||
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
|
#include <AK/TemporaryChange.h>
|
||||||
#include <LibGfx/AffineTransform.h>
|
#include <LibGfx/AffineTransform.h>
|
||||||
#include <LibGfx/Matrix4x4.h>
|
#include <LibGfx/Matrix4x4.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
|
@ -24,9 +25,13 @@ namespace Web::Painting {
|
||||||
|
|
||||||
static void paint_node(Paintable const& paintable, PaintContext& context, PaintPhase phase)
|
static void paint_node(Paintable const& paintable, PaintContext& context, PaintPhase phase)
|
||||||
{
|
{
|
||||||
|
TemporaryChange save_nesting_level(context.display_list_recorder().m_save_nesting_level, 0);
|
||||||
|
|
||||||
paintable.before_paint(context, phase);
|
paintable.before_paint(context, phase);
|
||||||
paintable.paint(context, phase);
|
paintable.paint(context, phase);
|
||||||
paintable.after_paint(context, phase);
|
paintable.after_paint(context, phase);
|
||||||
|
|
||||||
|
VERIFY(context.display_list_recorder().m_save_nesting_level == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
StackingContext::StackingContext(PaintableBox& paintable, StackingContext* parent, size_t index_in_tree_order)
|
StackingContext::StackingContext(PaintableBox& paintable, StackingContext* parent, size_t index_in_tree_order)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue