Bug 1495790 [wpt PR 13316] - sensors: Ensure a document without an associated frame does not crash, a=testonly
authorRaphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
Tue, 09 Oct 2018 04:13:07 +0000
changeset 488504 6da27d08b97b8245c0ea7596dd7e6a6b88e7b88a
parent 488503 e743d75e71fede566171d8e418d489b9f3838495
child 488505 578584d3e8e54f6080253acc575231460ca17e0c
push id246
push userfmarier@mozilla.com
push dateSat, 13 Oct 2018 00:15:40 +0000
reviewerstestonly
bugs1495790, 13316, 889754, 861675, 1256826, 595958
milestone64.0a1
Bug 1495790 [wpt PR 13316] - sensors: Ensure a document without an associated frame does not crash, a=testonly Automatic update from web-platform-testssensors: Ensure a document without an associated frame does not crash Commit d1034e1e6 ("sensors: Make SensorProviderProxy supplement Document, not LocalFrame") tied a sensor's lifetime to a document rather than a frame, but we continued to assume Document::GetFrame() would never return null. This is not true, as evidenced by the crash reports in bug 889754, caused by SensorProxy::ShouldSuspendUpdates() trying to invoke methods on a LocalFrame that can actually be a nullptr. The original backtrace in the bug report seems to come from sensor creation, but it is easier to trigger the same crash with a focus change after destroying a sensor's document's frame. Bug: 861675, 889754 Change-Id: Idb9ed5c18a655e113e2fb76cde6615aeefcc544a Reviewed-on: https://chromium-review.googlesource.com/1256826 Reviewed-by: Reilly Grant <reillyg@chromium.org> Commit-Queue: Raphael Kubo da Costa (CET) <raphael.kubo.da.costa@intel.com> Cr-Commit-Position: refs/heads/master@{#595958} -- wpt-commits: 27d87552c9a67481fb2d6ca82a71622c24ce7090 wpt-pr: 13316
testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
--- a/testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
+++ b/testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
@@ -1,16 +1,15 @@
 async function send_message_to_iframe(iframe, message, reply) {
   if (reply === undefined) {
     reply = 'success';
   }
 
   return new Promise((resolve, reject) => {
     let messageHandler = e => {
-
       if (e.data.command !== message.command) {
         return;
       }
       window.removeEventListener('message', messageHandler);
       if (e.data.result === reply) {
         resolve();
       } else {
         reject();
@@ -126,9 +125,36 @@ function run_generic_sensor_iframe_tests
     assert_greater_than(sensor.timestamp, cachedTimeStamp);
     sensor.stop();
     await send_message_to_iframe(iframe, {command: 'reset_sensor_backend'});
 
     // Remove iframe from main document.
     iframe.parentNode.removeChild(iframe);
   }, `${sensorName}: sensor is not suspended when focus traverses from\
  to same-origin frame`);
+
+  sensor_test(async t => {
+    assert_true(sensorName in self);
+    const iframe = document.createElement('iframe');
+    iframe.allow = featurePolicies.join(';') + ';';
+    iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+
+    // Create sensor in the iframe (we do not care whether this is a
+    // cross-origin nested context in this test).
+    const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
+    document.body.appendChild(iframe);
+    await iframeLoadWatcher.wait_for('load');
+    await send_message_to_iframe(iframe, {command: 'create_sensor',
+                                          type: sensorName});
+    iframe.contentWindow.focus();
+    await send_message_to_iframe(iframe, {command: 'start_sensor'});
+
+    // Remove iframe from main document and change focus. When focus changes,
+    // we need to determine whether a sensor must have its execution suspended
+    // or resumed (section 4.2.3, "Focused Area" of the Generic Sensor API
+    // spec). In Blink, this involves querying a frame, which might no longer
+    // exist at the time of the check.
+    // Note that we cannot send the "reset_sensor_backend" command because the
+    // iframe is discarded with the removeChild call.
+    iframe.parentNode.removeChild(iframe);
+    window.focus();
+  }, `${sensorName}: losing a document's frame with an active sensor does not crash`);
 }