Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit f04ec0f

Browse files
REGRESSION (r162334): RenderTableCol::styleDidChange uses out-of-date table information
https://bugs.webkit.org/show_bug.cgi?id=129561 Reviewed by Antti Koivisto. Source/WebCore: Test: fast/table/update-col-width-and-remove-table-cell-crash.html Fixes an issue where a table column or table column group may query an out- of-date model of its associated table as part of its process to propagate style changes to affected table cells. * rendering/RenderTableCol.cpp: (WebCore::RenderTableCol::styleDidChange): Ensure that all sections in the table are up-to-date before querying for a table cell. * rendering/RenderTableSection.cpp: (WebCore::RenderTableSection::recalcCells): Update comment to read well. In particular, remove the reference to RenderTableSection::fillRowsWithDefaultStartingAtPosition() as this function was removed in <http://trac.webkit.org/changeset/99919>. (WebCore::RenderTableSection::setNeedsCellRecalc): Clear the grid preemptively to to ensure that accessors cannot access stale data. We'll build the grid again in RenderTableSection::recalcCells(). (WebCore::RenderTableSection::numColumns): Add ASSERT(!m_needsCellRecalc) to assert that the grid cells are up-to-date. That is, we don't need to calculate them again. * rendering/RenderTableSection.h: Add ASSERT(!m_needsCellRecalc) or call recalcCellsIfNeeded() before accessing the grid to ensure that it's up-to-date. LayoutTests: Add a test to ensure that a table column propagates a style change to applicable table cells. * fast/table/update-col-width-and-remove-table-cell-crash-expected.txt: Added. * fast/table/update-col-width-and-remove-table-cell-crash.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@165837 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent bc5c3ab commit f04ec0f

File tree

7 files changed

+124
-9
lines changed

7 files changed

+124
-9
lines changed

LayoutTests/ChangeLog

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
2014-03-18 Daniel Bates <[email protected]>
2+
3+
REGRESSION (r162334): RenderTableCol::styleDidChange uses out-of-date table information
4+
https://bugs.webkit.org/show_bug.cgi?id=129561
5+
6+
Reviewed by Antti Koivisto.
7+
8+
Add a test to ensure that a table column propagates a style change to applicable
9+
table cells.
10+
11+
* fast/table/update-col-width-and-remove-table-cell-crash-expected.txt: Added.
12+
* fast/table/update-col-width-and-remove-table-cell-crash.html: Added.
13+
114
2014-03-18 Daniel Bates <[email protected]>
215

316
REGRESSION (r163560): ASSERTION FAILED: childrenInline() in WebCore::RenderSVGText::layout
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This test PASSED if it doesn't cause a crash, especially when run with Guard Malloc or MallocScribble enabled.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script>
5+
if (window.testRunner)
6+
testRunner.dumpAsText();
7+
8+
function runTest() {
9+
document.getElementById("column1").width = "90";
10+
var firstRow = document.getElementById("firstRow");
11+
firstRow.removeChild(firstRow.firstElementChild);
12+
document.getElementById("row").offsetWidth;
13+
}
14+
</script>
15+
<style>
16+
.column2 {
17+
width: 10px;
18+
}
19+
</style>
20+
</head>
21+
<body onload="runTest()">
22+
<table>
23+
<colgroup>
24+
<col id="column1" class="column1">
25+
<col class="column2">
26+
</colgroup>
27+
<tbody>
28+
<tr id="firstRow">
29+
<td colspan="4"></td>
30+
</tr>
31+
<tr id="row">
32+
<td colspan="4"></td>
33+
</tr>
34+
</tbody>
35+
</table>
36+
<p>This test PASSED if it doesn't cause a crash, especially when run with Guard Malloc or MallocScribble enabled.</p>
37+
</body>
38+
</html>

Source/WebCore/ChangeLog

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
2014-03-18 Daniel Bates <[email protected]>
2+
3+
REGRESSION (r162334): RenderTableCol::styleDidChange uses out-of-date table information
4+
https://bugs.webkit.org/show_bug.cgi?id=129561
5+
6+
Reviewed by Antti Koivisto.
7+
8+
Test: fast/table/update-col-width-and-remove-table-cell-crash.html
9+
10+
Fixes an issue where a table column or table column group may query an out-
11+
of-date model of its associated table as part of its process to propagate
12+
style changes to affected table cells.
13+
14+
* rendering/RenderTableCol.cpp:
15+
(WebCore::RenderTableCol::styleDidChange): Ensure that all sections in the table
16+
are up-to-date before querying for a table cell.
17+
* rendering/RenderTableSection.cpp:
18+
(WebCore::RenderTableSection::recalcCells): Update comment to read well. In
19+
particular, remove the reference to RenderTableSection::fillRowsWithDefaultStartingAtPosition()
20+
as this function was removed in <http://trac.webkit.org/changeset/99919>.
21+
(WebCore::RenderTableSection::setNeedsCellRecalc): Clear the grid preemptively to
22+
to ensure that accessors cannot access stale data. We'll build the grid again
23+
in RenderTableSection::recalcCells().
24+
(WebCore::RenderTableSection::numColumns): Add ASSERT(!m_needsCellRecalc) to assert
25+
that the grid cells are up-to-date. That is, we don't need to calculate them again.
26+
* rendering/RenderTableSection.h: Add ASSERT(!m_needsCellRecalc) or call recalcCellsIfNeeded()
27+
before accessing the grid to ensure that it's up-to-date.
28+
129
2014-03-18 Daniel Bates <[email protected]>
230

331
REGRESSION (r163560): ASSERTION FAILED: childrenInline() in WebCore::RenderSVGText::layout

Source/WebCore/rendering/RenderTableCol.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void RenderTableCol::styleDidChange(StyleDifference diff, const RenderStyle* old
5555
if (table && !table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle && oldStyle->border() != style().border())
5656
table->invalidateCollapsedBorders();
5757
else if (oldStyle->width() != style().width()) {
58+
table->recalcSectionsIfNeeded();
5859
for (auto& section : childrenOfType<RenderTableSection>(*table)) {
5960
unsigned nEffCols = table->numEffCols();
6061
for (unsigned j = 0; j < nEffCols; j++) {

Source/WebCore/rendering/RenderTableSection.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,9 +1361,9 @@ void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*)
13611361
void RenderTableSection::recalcCells()
13621362
{
13631363
ASSERT(m_needsCellRecalc);
1364-
// We reset the flag here to ensure that |addCell| works. This is safe to do as
1365-
// fillRowsWithDefaultStartingAtPosition makes sure we match the table's columns
1366-
// representation.
1364+
// We reset the flag here to ensure that addCell() works. This is safe to do because we clear the grid
1365+
// and update its dimensions to be consistent with the table's column representation before we rebuild
1366+
// the grid using addCell().
13671367
m_needsCellRecalc = false;
13681368

13691369
m_cCol = 0;
@@ -1403,12 +1403,17 @@ void RenderTableSection::rowLogicalHeightChanged(unsigned rowIndex)
14031403
void RenderTableSection::setNeedsCellRecalc()
14041404
{
14051405
m_needsCellRecalc = true;
1406+
1407+
// Clear the grid now to ensure that we don't hold onto any stale pointers (e.g. a cell renderer that is being removed).
1408+
m_grid.clear();
1409+
14061410
if (RenderTable* t = table())
14071411
t->setNeedsSectionRecalc();
14081412
}
14091413

14101414
unsigned RenderTableSection::numColumns() const
14111415
{
1416+
ASSERT(!m_needsCellRecalc);
14121417
unsigned result = 0;
14131418

14141419
for (unsigned r = 0; r < m_grid.size(); ++r) {

Source/WebCore/rendering/RenderTableSection.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,30 @@ class RenderTableSection final : public RenderBox {
142142
const RenderTableCell* firstRowCellAdjoiningTableStart() const;
143143
const RenderTableCell* firstRowCellAdjoiningTableEnd() const;
144144

145-
CellStruct& cellAt(unsigned row, unsigned col) { return m_grid[row].row[col]; }
146-
const CellStruct& cellAt(unsigned row, unsigned col) const { return m_grid[row].row[col]; }
145+
CellStruct& cellAt(unsigned row, unsigned col)
146+
{
147+
recalcCellsIfNeeded();
148+
return m_grid[row].row[col];
149+
}
150+
151+
const CellStruct& cellAt(unsigned row, unsigned col) const
152+
{
153+
ASSERT(!m_needsCellRecalc);
154+
return m_grid[row].row[col];
155+
}
156+
147157
RenderTableCell* primaryCellAt(unsigned row, unsigned col)
148158
{
159+
recalcCellsIfNeeded();
149160
CellStruct& c = m_grid[row].row[col];
150161
return c.primaryCell();
151162
}
152163

153-
RenderTableRow* rowRendererAt(unsigned row) const { return m_grid[row].rowRenderer; }
164+
RenderTableRow* rowRendererAt(unsigned row) const
165+
{
166+
ASSERT(!m_needsCellRecalc);
167+
return m_grid[row].rowRenderer;
168+
}
154169

155170
void appendColumn(unsigned pos);
156171
void splitColumn(unsigned pos, unsigned first);
@@ -194,7 +209,12 @@ class RenderTableSection final : public RenderBox {
194209
return styleForCellFlow->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
195210
}
196211

197-
unsigned numRows() const { return m_grid.size(); }
212+
unsigned numRows() const
213+
{
214+
ASSERT(!m_needsCellRecalc);
215+
return m_grid.size();
216+
}
217+
198218
unsigned numColumns() const;
199219
void recalcCells();
200220
void recalcCellsIfNeeded()
@@ -206,7 +226,11 @@ class RenderTableSection final : public RenderBox {
206226
bool needsCellRecalc() const { return m_needsCellRecalc; }
207227
void setNeedsCellRecalc();
208228

209-
LayoutUnit rowBaseline(unsigned row) { return m_grid[row].baseline; }
229+
LayoutUnit rowBaseline(unsigned row)
230+
{
231+
recalcCellsIfNeeded();
232+
return m_grid[row].baseline;
233+
}
210234

211235
void rowLogicalHeightChanged(unsigned rowIndex);
212236

@@ -263,7 +287,12 @@ class RenderTableSection final : public RenderBox {
263287
bool hasOverflowingCell() const { return m_overflowingCells.size() || m_forceSlowPaintPathWithOverflowingCell; }
264288
void computeOverflowFromCells(unsigned totalRows, unsigned nEffCols);
265289

266-
CellSpan fullTableRowSpan() const { return CellSpan(0, m_grid.size()); }
290+
CellSpan fullTableRowSpan() const
291+
{
292+
ASSERT(!m_needsCellRecalc);
293+
return CellSpan(0, m_grid.size());
294+
}
295+
267296
CellSpan fullTableColumnSpan() const { return CellSpan(0, table()->columns().size()); }
268297

269298
// Flip the rect so it aligns with the coordinates used by the rowPos and columnPos vectors.

0 commit comments

Comments
 (0)