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
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index 39f594c..e84691b 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -1361,9 +1361,9 @@
 void RenderTableSection::recalcCells()
 {
     ASSERT(m_needsCellRecalc);
-    // We reset the flag here to ensure that |addCell| works. This is safe to do as
-    // fillRowsWithDefaultStartingAtPosition makes sure we match the table's columns
-    // representation.
+    // We reset the flag here to ensure that addCell() works. This is safe to do because we clear the grid
+    // and update its dimensions to be consistent with the table's column representation before we rebuild
+    // the grid using addCell().
     m_needsCellRecalc = false;
 
     m_cCol = 0;
@@ -1403,12 +1403,17 @@
 void RenderTableSection::setNeedsCellRecalc()
 {
     m_needsCellRecalc = true;
+
+    // Clear the grid now to ensure that we don't hold onto any stale pointers (e.g. a cell renderer that is being removed).
+    m_grid.clear();
+
     if (RenderTable* t = table())
         t->setNeedsSectionRecalc();
 }
 
 unsigned RenderTableSection::numColumns() const
 {
+    ASSERT(!m_needsCellRecalc);
     unsigned result = 0;
     
     for (unsigned r = 0; r < m_grid.size(); ++r) {