Browse Source

chore: cherry-pick 70579363ce7b from chromium (#25025)

* chore: cherry-pick 70579363ce7b from chromium

* update patches

Co-authored-by: Electron Bot <[email protected]>
Jeremy Rose 4 years ago
parent
commit
08aa4522c9
2 changed files with 79 additions and 0 deletions
  1. 1 0
      patches/chromium/.patches
  2. 78 0
      patches/chromium/cherry-pick-70579363ce7b.patch

+ 1 - 0
patches/chromium/.patches

@@ -120,3 +120,4 @@ backport_1090543.patch
 backport_1081722.patch
 backport_1073409.patch
 backport_1074340.patch
+cherry-pick-70579363ce7b.patch

+ 78 - 0
patches/chromium/cherry-pick-70579363ce7b.patch

@@ -0,0 +1,78 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Reilly Grant <[email protected]>
+Date: Wed, 22 Jul 2020 04:00:16 +0000
+Subject: usb: Prevent iterator invalidation during Promise resolution
+
+This change swaps sets of ScriptPromiseResolvers into local variables in
+a number of places where it was possible for script to execute during
+the call to Resolve() or Reject() and modify the set being iterated
+over, thus invalidating the iterator.
+
+(cherry picked from commit dbc6c3c3652680e287c60b3c6551622748543439)
+
+Bug: 1106773
+Change-Id: Id4eb0cd444a7dbb5de23038ec80f44fee649cfe4
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2304538
+Auto-Submit: Reilly Grant <[email protected]>
+Commit-Queue: James Hollyer <[email protected]>
+Reviewed-by: James Hollyer <[email protected]>
+Cr-Original-Commit-Position: refs/heads/master@{#790217}
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2310964
+Reviewed-by: Reilly Grant <[email protected]>
+Commit-Queue: Reilly Grant <[email protected]>
+Cr-Commit-Position: refs/branch-heads/4183@{#842}
+Cr-Branched-From: 740e9e8a40505392ba5c8e022a8024b3d018ca65-refs/heads/master@{#782793}
+
+diff --git a/third_party/blink/renderer/modules/webusb/usb.cc b/third_party/blink/renderer/modules/webusb/usb.cc
+index cbe336ae6991d42aa7082aa99a95c4a380aa790f..ce38760e569e03bef1f64b14fca1122d7f98b452 100644
+--- a/third_party/blink/renderer/modules/webusb/usb.cc
++++ b/third_party/blink/renderer/modules/webusb/usb.cc
+@@ -264,15 +264,22 @@ void USB::OnDeviceRemoved(UsbDeviceInfoPtr device_info) {
+ void USB::OnServiceConnectionError() {
+   service_.reset();
+   client_receiver_.reset();
+-  for (ScriptPromiseResolver* resolver : get_devices_requests_)
++
++  // Move the set to a local variable to prevent script execution in Resolve()
++  // from invalidating the iterator used by the loop.
++  HeapHashSet<Member<ScriptPromiseResolver>> get_devices_requests;
++  get_devices_requests.swap(get_devices_requests_);
++  for (auto& resolver : get_devices_requests)
+     resolver->Resolve(HeapVector<Member<USBDevice>>(0));
+-  get_devices_requests_.clear();
+ 
+-  for (ScriptPromiseResolver* resolver : get_permission_requests_) {
++  // Move the set to a local variable to prevent script execution in Reject()
++  // from invalidating the iterator used by the loop.
++  HeapHashSet<Member<ScriptPromiseResolver>> get_permission_requests;
++  get_permission_requests.swap(get_permission_requests_);
++  for (auto& resolver : get_permission_requests) {
+     resolver->Reject(MakeGarbageCollected<DOMException>(
+         DOMExceptionCode::kNotFoundError, kNoDeviceSelected));
+   }
+-  get_permission_requests_.clear();
+ }
+ 
+ void USB::AddedEventListener(const AtomicString& event_type,
+diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
+index da7d3003c3a38cdf650ec0ab5c131fecd80ee4e5..23856abc9a59770f816c6d18cd12602e6d0dae58 100644
+--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
++++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
+@@ -1099,11 +1099,15 @@ void USBDevice::AsyncReset(ScriptPromiseResolver* resolver, bool success) {
+ void USBDevice::OnConnectionError() {
+   device_.reset();
+   opened_ = false;
+-  for (ScriptPromiseResolver* resolver : device_requests_) {
++
++  // Move the set to a local variable to prevent script execution in Reject()
++  // from invalidating the iterator used by the loop.
++  HeapHashSet<Member<ScriptPromiseResolver>> device_requests;
++  device_requests.swap(device_requests_);
++  for (auto& resolver : device_requests) {
+     resolver->Reject(MakeGarbageCollected<DOMException>(
+         DOMExceptionCode::kNotFoundError, kDeviceDisconnected));
+   }
+-  device_requests_.clear();
+ }
+ 
+ bool USBDevice::MarkRequestComplete(ScriptPromiseResolver* resolver) {