Changeset 247161 in webkit


Ignore:
Timestamp:
Jul 5, 2019 9:58:06 AM (5 years ago)
Author:
Wenson Hsieh
Message:

Click events on outer page are not being dispatched correctly after touch-zooming within an iframe
https://bugs.webkit.org/show_bug.cgi?id=185001
<rdar://problem/40569615>

Reviewed by Simon Fraser.

Source/WebKit:

Mitigations introduced in r227759 prevent a touch inside a document of origin A to result in a click event being
dispatched on an element inside a document of origin B. It accomplishes this by keeping track of the security
origin of the last touch via m_potentialTapSecurityOrigin on WebPage. However, there exists a corner case in
which m_potentialTapSecurityOrigin, set after touching a document in a subframe, may persist even after the user
has finished interacting, causing taps in subsequent documents to not result in synthetic click events due to
mismatched potential tap origins.

This may happen if the first user gesture happens inside an element in a subframe with touch event handlers, but
no click event handler (and the touch is additionally not over some clickable element). In this case,
m_potentialTapNode is set to null in WebPage::potentialTapAtPosition, and when we consult it in
WebPage::commitPotentialTap, we just end up calling commitPotentialTapFailed(); and return early. This means
that m_potentialTapNode, m_potentialTapLocation, and (importantly) m_potentialTapSecurityOrigin are not reset.
This causes subsequent taps in the top-level document to never dispatch click events, if the security origin
does not match with that of the subframe.

To fix this, we add a new async IPC message from the UI process to the web process to ensure that our current
security origin is reset before attempting to handle a tap.

Test: http/tests/events/touch/ios/click-after-handling-touch-in-cross-origin-frame.https.html

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::resetPotentialTapSecurityOrigin):

Reset any stale potential tap security origin if needed.

  • UIProcess/WebPageProxy.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView _webTouchEventsRecognized:]):

Send the new IPC message when starting a touch.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::resetPotentialTapSecurityOrigin):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:

LayoutTests:

Add a new layout test to verify that after interacting with an element with touch event handlers in a cross-
origin subframe, the user is still able to click on elements on the top level document.

  • http/tests/events/touch/ios/click-after-handling-touch-in-cross-origin-frame.https-expected.txt: Added.
  • http/tests/events/touch/ios/click-after-handling-touch-in-cross-origin-frame.https.html: Added.
  • http/tests/events/touch/ios/resources/touch-target.html: Added.
Location:
trunk
Files:
3 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r247158 r247161  
     12019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Click events on outer page are not being dispatched correctly after touch-zooming within an iframe
     4        https://bugs.webkit.org/show_bug.cgi?id=185001
     5        <rdar://problem/40569615>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Add a new layout test to verify that after interacting with an element with touch event handlers in a cross-
     10        origin subframe, the user is still able to click on elements on the top level document.
     11
     12        * http/tests/events/touch/ios/click-after-handling-touch-in-cross-origin-frame.https-expected.txt: Added.
     13        * http/tests/events/touch/ios/click-after-handling-touch-in-cross-origin-frame.https.html: Added.
     14        * http/tests/events/touch/ios/resources/touch-target.html: Added.
     15
    1162019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
    217
  • trunk/Source/WebKit/ChangeLog

    r247158 r247161  
     12019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Click events on outer page are not being dispatched correctly after touch-zooming within an iframe
     4        https://bugs.webkit.org/show_bug.cgi?id=185001
     5        <rdar://problem/40569615>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Mitigations introduced in r227759 prevent a touch inside a document of origin A to result in a click event being
     10        dispatched on an element inside a document of origin B. It accomplishes this by keeping track of the security
     11        origin of the last touch via m_potentialTapSecurityOrigin on WebPage. However, there exists a corner case in
     12        which m_potentialTapSecurityOrigin, set after touching a document in a subframe, may persist even after the user
     13        has finished interacting, causing taps in subsequent documents to not result in synthetic click events due to
     14        mismatched potential tap origins.
     15
     16        This may happen if the first user gesture happens inside an element in a subframe with touch event handlers, but
     17        no click event handler (and the touch is additionally not over some clickable element). In this case,
     18        m_potentialTapNode is set to null in WebPage::potentialTapAtPosition, and when we consult it in
     19        WebPage::commitPotentialTap, we just end up calling commitPotentialTapFailed(); and return early. This means
     20        that m_potentialTapNode, m_potentialTapLocation, and (importantly) m_potentialTapSecurityOrigin are not reset.
     21        This causes subsequent taps in the top-level document to never dispatch click events, if the security origin
     22        does not match with that of the subframe.
     23
     24        To fix this, we add a new async IPC message from the UI process to the web process to ensure that our current
     25        security origin is reset before attempting to handle a tap.
     26
     27        Test: http/tests/events/touch/ios/click-after-handling-touch-in-cross-origin-frame.https.html
     28
     29        * UIProcess/WebPageProxy.cpp:
     30        (WebKit::WebPageProxy::resetPotentialTapSecurityOrigin):
     31
     32        Reset any stale potential tap security origin if needed.
     33
     34        * UIProcess/WebPageProxy.h:
     35        * UIProcess/ios/WKContentViewInteraction.mm:
     36        (-[WKContentView _webTouchEventsRecognized:]):
     37
     38        Send the new IPC message when starting a touch.
     39
     40        * WebProcess/WebPage/WebPage.cpp:
     41        (WebKit::WebPage::resetPotentialTapSecurityOrigin):
     42        * WebProcess/WebPage/WebPage.h:
     43        * WebProcess/WebPage/WebPage.messages.in:
     44
    1452019-07-05  Wenson Hsieh  <wenson_hsieh@apple.com>
    246
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r247146 r247161  
    26582658}
    26592659
     2660void WebPageProxy::resetPotentialTapSecurityOrigin()
     2661{
     2662    if (!hasRunningProcess())
     2663        return;
     2664
     2665    m_process->send(Messages::WebPage::ResetPotentialTapSecurityOrigin(), m_pageID);
     2666}
     2667
    26602668void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
    26612669{
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r247146 r247161  
    829829
    830830#if ENABLE(IOS_TOUCH_EVENTS)
     831    void resetPotentialTapSecurityOrigin();
    831832    void handleTouchEventSynchronously(NativeWebTouchEvent&);
    832833    void handleTouchEventAsynchronously(const NativeWebTouchEvent&);
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r247132 r247161  
    13161316        _layerTreeTransactionIdAtLastTouchStart = downcast<WebKit::RemoteLayerTreeDrawingAreaProxy>(*_page->drawingArea()).lastCommittedLayerTreeTransactionID();
    13171317
     1318#if ENABLE(TOUCH_EVENTS)
     1319        _page->resetPotentialTapSecurityOrigin();
     1320#endif
     1321
    13181322        WebKit::InteractionInformationRequest positionInformationRequest { WebCore::IntPoint(_lastInteractionLocation) };
    13191323        [self doAfterPositionInformationUpdate:[assistant = WeakObjCPtr<WKActionSheetAssistant>(_actionSheetAssistant.get())] (WebKit::InteractionInformationAtPosition information) {
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r247158 r247161  
    29172917}
    29182918
     2919void WebPage::resetPotentialTapSecurityOrigin()
     2920{
     2921    m_potentialTapSecurityOrigin = nullptr;
     2922}
     2923
    29192924void WebPage::updatePotentialTapSecurityOrigin(const WebTouchEvent& touchEvent, bool wasHandled)
    29202925{
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r247158 r247161  
    13211321#if ENABLE(IOS_TOUCH_EVENTS)
    13221322    void touchEventSync(const WebTouchEvent&, CompletionHandler<void(bool)>&&);
     1323    void resetPotentialTapSecurityOrigin();
    13231324    void updatePotentialTapSecurityOrigin(const WebTouchEvent&, bool wasHandled);
    13241325#elif ENABLE(TOUCH_EVENTS)
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r246938 r247161  
    127127
    128128#if ENABLE(IOS_TOUCH_EVENTS)
     129    ResetPotentialTapSecurityOrigin()
    129130    TouchEventSync(WebKit::WebTouchEvent event) -> (bool handled) Synchronous
    130131#endif
Note: See TracChangeset for help on using the changeset viewer.