Harden against layout passes triggered when iterating through HTMLFormElement::associ...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jan 2018 08:19:16 +0000 (08:19 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jan 2018 08:19:16 +0000 (08:19 +0000)
commite2f55fb08db1cee6a049db7d2181e5e9823d5349
tree907f98dffc5cd6df9543c88136031783b4be53b6
parent4516cb2ed7812b847cd536ac3b5277d19d7c8004
Harden against layout passes triggered when iterating through HTMLFormElement::associatedElements
https://bugs.webkit.org/show_bug.cgi?id=182037
<rdar://problem/36747812>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Observe that HTMLFormElement::associatedElements returns a const reference to a Vector of raw
FormAssociatedElement pointers. In various call sites that iterate through these associated elements using this
function, some require synchronous layout updates per iteration, which can lead to a bad time when combined with
the first observation.

To address this, we introduce HTMLFormElement::copyAssociatedElementsVector. This returns a new vector
containing strong Refs to each associated element. From each call site that may trigger synchronous layout and
execute arbitrary script while iterating over associated form elements, we instead use iterate over protected
FormAssociatedElements.

From each call site that currently doesn't (and shouldn't) require a layout update, we use the old version that
returns a list of raw FormAssociatedElement pointers, but add ScriptDisallowedScopes to ensure that we never
execute script there in the future.

Test: fast/forms/form-data-associated-element-iteration.html

* html/DOMFormData.cpp:
(WebCore::DOMFormData::DOMFormData):

Change to use copyAssociatedElementsVector().

* html/FormController.cpp:
(WebCore::recordFormStructure):
(WebCore::FormController::restoreControlStateIn):

Change to use copyAssociatedElementsVector().

* html/HTMLFieldSetElement.cpp:
(WebCore::HTMLFieldSetElement::copyAssociatedElementsVector const):
(WebCore:: const):
(WebCore::HTMLFieldSetElement::length const):

Refactor to use unsafeAssociatedElements().

* html/HTMLFieldSetElement.h:
* html/HTMLFormControlsCollection.cpp:
(WebCore:: const):
(WebCore::HTMLFormControlsCollection::copyFormControlElementsVector const):
(WebCore::HTMLFormControlsCollection::customElementAfter const):
(WebCore::HTMLFormControlsCollection::updateNamedElementCache const):

Refactor these to use unsafeAssociatedElements().

* html/HTMLFormControlsCollection.h:
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::unsafeAssociatedElements const):
(WebCore::HTMLFormElement::copyAssociatedElementsVector const):
* html/HTMLFormElement.h:
* loader/FormSubmission.cpp:
(WebCore::FormSubmission::create):

Refactor to use copyAssociatedElementsVector().

Source/WebKitLegacy/mac:

Rename associatedElements() to unsafeAssociatedElements(), and add ScriptDisallowedScopes. See WebCore ChangeLog
for more details.

* WebView/WebHTMLRepresentation.mm:
(-[WebHTMLRepresentation elementWithName:inForm:]):
(-[WebHTMLRepresentation controlsInForm:]):

LayoutTests:

Add a new layout test covering these hardening changes. See WebCore ChangeLog for more details.

* fast/forms/form-data-associated-element-iteration-expected.txt: Added.
* fast/forms/form-data-associated-element-iteration.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227479 268f45cc-cd09-0410-ab3c-d52691b4dbfc
15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/form-data-associated-element-iteration-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/form-data-associated-element-iteration.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/DOMFormData.cpp
Source/WebCore/html/FormController.cpp
Source/WebCore/html/HTMLFieldSetElement.cpp
Source/WebCore/html/HTMLFieldSetElement.h
Source/WebCore/html/HTMLFormControlsCollection.cpp
Source/WebCore/html/HTMLFormControlsCollection.h
Source/WebCore/html/HTMLFormElement.cpp
Source/WebCore/html/HTMLFormElement.h
Source/WebCore/loader/FormSubmission.cpp
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebHTMLRepresentation.mm