1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:07:44 +00:00

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.
This commit is contained in:
MacDue 2023-04-05 23:11:00 +01:00 committed by Linus Groh
parent 064ca625df
commit 26e56bdd08

View file

@ -144,8 +144,10 @@ void Path::close_all_subpaths()
Optional<FloatPoint> cursor, start_of_subpath; Optional<FloatPoint> cursor, start_of_subpath;
bool is_first_point_in_subpath { false }; bool is_first_point_in_subpath { false };
for (auto& segment : m_segments) { auto segment_count = m_segments.size();
switch (segment->type()) { 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: { case Segment::Type::MoveTo: {
if (cursor.has_value() && !is_first_point_in_subpath) { if (cursor.has_value() && !is_first_point_in_subpath) {
// This is a move from a subpath to another // 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()); append_segment<LineSegment>(start_of_subpath.value());
} }
is_first_point_in_subpath = true; is_first_point_in_subpath = true;
cursor = segment->point(); cursor = m_segments[i]->point();
break; break;
} }
case Segment::Type::LineTo: case Segment::Type::LineTo:
@ -168,7 +170,7 @@ void Path::close_all_subpaths()
start_of_subpath = cursor; start_of_subpath = cursor;
is_first_point_in_subpath = false; is_first_point_in_subpath = false;
} }
cursor = segment->point(); cursor = m_segments[i]->point();
break; break;
case Segment::Type::Invalid: case Segment::Type::Invalid:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();