summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2023-04-05 23:11:00 +0100
committerLinus Groh <mail@linusgroh.de>2023-04-09 18:42:45 +0200
commit26e56bdd0856fb09900ec9255569e44e70653430 (patch)
treec58ee07d155461cc255f136a7cadaba86feb88b3
parent064ca625dffe29c5a8f20efdd82fa52250f233e0 (diff)
downloadserenity-26e56bdd0856fb09900ec9255569e44e70653430.zip
LibGfx: Fix crash due to vector resize in close_all_subpaths()
Since close_all_subpaths() appends while iterating, the vector can end up being resized and the iterator invalidated. Previously, this led to a crash/UAF in some cases.
-rw-r--r--Userland/Libraries/LibGfx/Path.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/Userland/Libraries/LibGfx/Path.cpp b/Userland/Libraries/LibGfx/Path.cpp
index 79e47e6fd3..088d726dad 100644
--- a/Userland/Libraries/LibGfx/Path.cpp
+++ b/Userland/Libraries/LibGfx/Path.cpp
@@ -144,8 +144,10 @@ void Path::close_all_subpaths()
Optional<FloatPoint> cursor, start_of_subpath;
bool is_first_point_in_subpath { false };
- for (auto& segment : m_segments) {
- switch (segment->type()) {
+ auto segment_count = m_segments.size();
+ for (size_t i = 0; i < segment_count; i++) {
+ // Note: We need to use m_segments[i] as append_segment() may invalidate any references.
+ switch (m_segments[i]->type()) {
case Segment::Type::MoveTo: {
if (cursor.has_value() && !is_first_point_in_subpath) {
// This is a move from a subpath to another
@@ -157,7 +159,7 @@ void Path::close_all_subpaths()
append_segment<LineSegment>(start_of_subpath.value());
}
is_first_point_in_subpath = true;
- cursor = segment->point();
+ cursor = m_segments[i]->point();
break;
}
case Segment::Type::LineTo:
@@ -168,7 +170,7 @@ void Path::close_all_subpaths()
start_of_subpath = cursor;
is_first_point_in_subpath = false;
}
- cursor = segment->point();
+ cursor = m_segments[i]->point();
break;
case Segment::Type::Invalid:
VERIFY_NOT_REACHED();