mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibWeb: Fix out-of-bound crash when there's more table cells than cols
Added a getter to ensure we are within a valid range. This behavior is accepted by other browsers, and crashed on some pages.
This commit is contained in:
parent
cd5d8f4d95
commit
5dabd468ed
Notes:
github-actions[bot]
2024-11-06 09:37:32 +00:00
Author: https://github.com/OHermesJunior Commit: https://github.com/LadybirdBrowser/ladybird/commit/5dabd468ed0 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2169 Reviewed-by: https://github.com/AtkinsSJ ✅
4 changed files with 111 additions and 14 deletions
|
@ -0,0 +1,69 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x19 children: not-inline
|
||||||
|
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
TableWrapper <(anonymous)> at (8,8) content-size 53.0625x19 [BFC] children: not-inline
|
||||||
|
Box <table> at (8,8) content-size 53.0625x19 table-box [TFC] children: not-inline
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <colgroup> (not painted) table-column-group children: not-inline
|
||||||
|
BlockContainer <col> (not painted) children: not-inline
|
||||||
|
BlockContainer <col> (not painted) children: not-inline
|
||||||
|
BlockContainer <col> (not painted) children: not-inline
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
Box <tbody> at (8,8) content-size 53.0625x19 table-row-group children: not-inline
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
Box <tr> at (8,8) content-size 53.0625x19 table-row children: not-inline
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <td> at (9,9) content-size 14.265625x17 table-cell [BFC] children: inline
|
||||||
|
frag 0 from TextNode start: 0, length: 1, rect: [9,9 14.265625x17] baseline: 13.296875
|
||||||
|
"A"
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <td> at (25.265625,9) content-size 9.34375x17 table-cell [BFC] children: inline
|
||||||
|
frag 0 from TextNode start: 0, length: 1, rect: [25.265625,9 9.34375x17] baseline: 13.296875
|
||||||
|
"B"
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <td> at (36.609375,9) content-size 10.3125x17 table-cell [BFC] children: inline
|
||||||
|
frag 0 from TextNode start: 0, length: 1, rect: [36.609375,9 10.3125x17] baseline: 13.296875
|
||||||
|
"C"
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <td> at (48.921875,9) content-size 11.140625x17 table-cell [BFC] children: inline
|
||||||
|
frag 0 from TextNode start: 0, length: 1, rect: [48.921875,9 11.140625x17] baseline: 13.296875
|
||||||
|
"D"
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> (not painted) children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <(anonymous)> at (8,27) content-size 784x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x19]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0]
|
||||||
|
PaintableWithLines (TableWrapper(anonymous)) [8,8 53.0625x19]
|
||||||
|
PaintableBox (Box<TABLE>) [8,8 53.0625x19]
|
||||||
|
PaintableBox (Box<TBODY>) [8,8 53.0625x19]
|
||||||
|
PaintableBox (Box<TR>) [8,8 53.0625x19]
|
||||||
|
PaintableWithLines (BlockContainer<TD>) [8,8 16.265625x19]
|
||||||
|
TextPaintable (TextNode<#text>)
|
||||||
|
PaintableWithLines (BlockContainer<TD>) [24.265625,8 11.34375x19]
|
||||||
|
TextPaintable (TextNode<#text>)
|
||||||
|
PaintableWithLines (BlockContainer<TD>) [35.609375,8 12.3125x19]
|
||||||
|
TextPaintable (TextNode<#text>)
|
||||||
|
PaintableWithLines (BlockContainer<TD>) [47.921875,8 13.140625x19]
|
||||||
|
TextPaintable (TextNode<#text>)
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,27 784x0]
|
|
@ -0,0 +1,23 @@
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<colgroup>
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>A</td>
|
||||||
|
<td>B</td>
|
||||||
|
<td>C</td>
|
||||||
|
<td>D</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
|
@ -1504,22 +1504,20 @@ void TableFormattingContext::BorderConflictFinder::collect_row_group_conflicting
|
||||||
void TableFormattingContext::BorderConflictFinder::collect_column_group_conflicting_edges(Vector<ConflictingEdge>& result, Cell const& cell, TableFormattingContext::ConflictingSide edge) const
|
void TableFormattingContext::BorderConflictFinder::collect_column_group_conflicting_edges(Vector<ConflictingEdge>& result, Cell const& cell, TableFormattingContext::ConflictingSide edge) const
|
||||||
{
|
{
|
||||||
// Left edge of the column group.
|
// Left edge of the column group.
|
||||||
if (m_col_elements_by_index[cell.column_index] && edge == ConflictingSide::Left) {
|
if (auto col_element = get_col_element(cell.column_index); col_element && edge == ConflictingSide::Left) {
|
||||||
result.append({ m_col_elements_by_index[cell.column_index], Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Left, {}, cell.column_index });
|
result.append({ col_element, Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Left, {}, cell.column_index });
|
||||||
}
|
}
|
||||||
// Right edge of the column group to the left.
|
// Right edge of the column group to the left.
|
||||||
if (cell.column_index >= cell.column_span && m_col_elements_by_index[cell.column_index - cell.column_span] && edge == ConflictingSide::Left) {
|
if (auto col_element = get_col_element(cell.column_index - cell.column_span); col_element && cell.column_index >= cell.column_span && edge == ConflictingSide::Left) {
|
||||||
auto left_column_index = cell.column_index - cell.column_span;
|
result.append({ col_element, Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Right, {}, cell.column_index - cell.column_span });
|
||||||
result.append({ m_col_elements_by_index[left_column_index], Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Right, {}, left_column_index });
|
|
||||||
}
|
}
|
||||||
// Right edge of the column group.
|
// Right edge of the column group.
|
||||||
if (m_col_elements_by_index[cell.column_index] && edge == ConflictingSide::Right) {
|
if (auto col_element = get_col_element(cell.column_index); col_element && edge == ConflictingSide::Right) {
|
||||||
result.append({ m_col_elements_by_index[cell.column_index], Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Right, {}, cell.column_index });
|
result.append({ col_element, Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Right, {}, cell.column_index });
|
||||||
}
|
}
|
||||||
// Left edge of the column group to the right.
|
// Left edge of the column group to the right.
|
||||||
if (cell.column_index + cell.column_span < m_col_elements_by_index.size() && m_col_elements_by_index[cell.column_index + cell.column_span] && edge == ConflictingSide::Right) {
|
if (auto col_element = get_col_element(cell.column_index - cell.column_span); col_element && edge == ConflictingSide::Right) {
|
||||||
auto right_column_index = cell.column_index + cell.column_span;
|
result.append({ col_element, Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Left, {}, cell.column_index + cell.column_span });
|
||||||
result.append({ m_col_elements_by_index[right_column_index], Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Left, {}, right_column_index });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1527,15 +1525,15 @@ void TableFormattingContext::BorderConflictFinder::collect_table_box_conflicting
|
||||||
{
|
{
|
||||||
// Top edge from column group or table. Left and right edges of the column group are handled in collect_column_group_conflicting_edges.
|
// Top edge from column group or table. Left and right edges of the column group are handled in collect_column_group_conflicting_edges.
|
||||||
if (cell.row_index == 0 && edge == ConflictingSide::Top) {
|
if (cell.row_index == 0 && edge == ConflictingSide::Top) {
|
||||||
if (m_col_elements_by_index[cell.column_index]) {
|
if (auto col_element = get_col_element(cell.column_index); col_element) {
|
||||||
result.append({ m_col_elements_by_index[cell.column_index], Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Top, {}, cell.column_index });
|
result.append({ col_element, Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Top, {}, cell.column_index });
|
||||||
}
|
}
|
||||||
result.append({ &m_context->table_box(), Painting::PaintableBox::ConflictingElementKind::Table, ConflictingSide::Top, {}, {} });
|
result.append({ &m_context->table_box(), Painting::PaintableBox::ConflictingElementKind::Table, ConflictingSide::Top, {}, {} });
|
||||||
}
|
}
|
||||||
// Bottom edge from column group or table. Left and right edges of the column group are handled in collect_column_group_conflicting_edges.
|
// Bottom edge from column group or table. Left and right edges of the column group are handled in collect_column_group_conflicting_edges.
|
||||||
if (cell.row_index + cell.row_span == m_context->m_rows.size() && edge == ConflictingSide::Bottom) {
|
if (cell.row_index + cell.row_span == m_context->m_rows.size() && edge == ConflictingSide::Bottom) {
|
||||||
if (m_col_elements_by_index[cell.column_index]) {
|
if (auto col_element = get_col_element(cell.column_index); col_element) {
|
||||||
result.append({ m_col_elements_by_index[cell.column_index], Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Bottom, {}, cell.column_index });
|
result.append({ col_element, Painting::PaintableBox::ConflictingElementKind::ColumnGroup, ConflictingSide::Bottom, {}, cell.column_index });
|
||||||
}
|
}
|
||||||
result.append({ &m_context->table_box(), Painting::PaintableBox::ConflictingElementKind::Table, ConflictingSide::Bottom, {}, {} });
|
result.append({ &m_context->table_box(), Painting::PaintableBox::ConflictingElementKind::Table, ConflictingSide::Bottom, {}, {} });
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,13 @@ private:
|
||||||
void collect_column_group_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const;
|
void collect_column_group_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const;
|
||||||
void collect_table_box_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const;
|
void collect_table_box_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const;
|
||||||
|
|
||||||
|
JS::GCPtr<Node const> get_col_element(size_t index) const
|
||||||
|
{
|
||||||
|
if (index >= m_col_elements_by_index.size())
|
||||||
|
return {};
|
||||||
|
return m_col_elements_by_index[index];
|
||||||
|
}
|
||||||
|
|
||||||
struct RowGroupInfo {
|
struct RowGroupInfo {
|
||||||
JS::GCPtr<Node const> row_group;
|
JS::GCPtr<Node const> row_group;
|
||||||
size_t start_index;
|
size_t start_index;
|
||||||
|
|
Loading…
Reference in a new issue