REGRESSION(98738): RenderTableSection::recalcCells does not properly shrink the RowStruct grid
https://bugs.webkit.org/show_bug.cgi?id=71246
Reviewed by Darin Adler.
Source/WebCore:
Tests: fast/table/crash-empty-section-calcBorder.html
fast/table/crash-empty-section-fixed-layout-calcArray.html
The refactoring in r98738 changed the way we handle the size to avoid throwing off
the memory. The new logic would end up never shrinking the grid's size (prior to that
we would grow to the appropriate size and throw the excess capacity with shrinkToFit).
Not shrinking would mean that we would potentially read RowStruct with the default values
(for instance no |rowRenderer|).
addCell will properly grow the grid as needed to accomodate the rows and the protruding
cells with a rowspan so we introduce a variable to keep track of the size needed. At the
end, we just shrink it to this size.
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::recalcCells):
Introduce a variable to keep the grid size and shrink to that size to match the old code.
LayoutTests:
Those tests checks that an empty section would not lead to reading
RowStruct without a |rowRenderer| which would crash.
* fast/table/crash-empty-section-calcBorder-expected.txt: Added.
* fast/table/crash-empty-section-calcBorder.html: Added.
* fast/table/crash-empty-section-fixed-layout-calcArray-expected.txt: Added.
* fast/table/crash-empty-section-fixed-layout-calcArray.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@98980 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index 555687c..63d9e23 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -1122,6 +1122,9 @@
m_cRow = 0;
fillRowsWithDefaultStartingAtPosition(0);
+ // The grid size is at least as big as the number of rows in the markup but can grow bigger
+ // if we have a cell protruding because it uses a rowspan spannig out of the table.
+ unsigned gridSize = 0;
for (RenderObject* row = firstChild(); row; row = row->nextSibling()) {
if (row->isTableRow()) {
unsigned insertionRow = m_cRow;
@@ -1135,13 +1138,18 @@
setRowLogicalHeightToRowStyleLogicalHeightIfNotRelative(m_grid[insertionRow]);
for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (cell->isTableCell())
- addCell(toRenderTableCell(cell), tableRow);
+ if (!cell->isTableCell())
+ continue;
+
+ RenderTableCell* tableCell = toRenderTableCell(cell);
+ gridSize = max(gridSize, insertionRow + tableCell->rowSpan());
+ addCell(tableCell, tableRow);
}
}
}
- m_grid.shrinkToFit();
+ gridSize = max(gridSize, m_cRow);
+ m_grid.shrink(gridSize);
m_needsCellRecalc = false;
setNeedsLayout(true);
}