Browse Source

fix: crash on `getUserMedia` with invalid `chromeMediaSourceId` (#45755)

* fix: crash on getUserMedia with invalid chromeMediaSourceId

Co-authored-by: Shelley Vohr <[email protected]>

* test: add a test

Co-authored-by: Shelley Vohr <[email protected]>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 1 month ago
parent
commit
05b57a2f07
2 changed files with 30 additions and 9 deletions
  1. 13 9
      shell/browser/web_contents_permission_helper.cc
  2. 17 0
      spec/api-media-handler-spec.ts

+ 13 - 9
shell/browser/web_contents_permission_helper.cc

@@ -101,16 +101,20 @@ void HandleUserMediaRequest(const content::MediaStreamRequest& request,
             : "");
   }
 
-  if (request.video_type == MediaStreamType::GUM_TAB_VIDEO_CAPTURE ||
-      request.video_type == MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE) {
+  if (request.video_type == MediaStreamType::GUM_TAB_VIDEO_CAPTURE) {
+    devices_ref.video_device =
+        blink::MediaStreamDevice(request.video_type, "", "");
+  } else if (request.video_type == MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE) {
+    // If the DesktopMediaID can't be successfully parsed, throw an
+    // Invalid state error to match upstream.
+    auto dm_id = GetScreenId(request.requested_video_device_ids);
+    if (dm_id.is_null()) {
+      std::move(callback).Run(blink::mojom::StreamDevicesSet(),
+                              MediaStreamRequestResult::INVALID_STATE, nullptr);
+      return;
+    }
     devices_ref.video_device = blink::MediaStreamDevice(
-        request.video_type,
-        request.video_type == MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE
-            ? GetScreenId(request.requested_video_device_ids).ToString()
-            : "",
-        request.video_type == MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE
-            ? "Screen"
-            : "");
+        request.video_type, dm_id.ToString(), "Screen");
   }
 
   bool empty = !devices_ref.audio_device.has_value() &&

+ 17 - 0
spec/api-media-handler-spec.ts

@@ -400,6 +400,23 @@ describe('setDisplayMediaRequestHandler', () => {
     expect(ok).to.be.true(message);
   });
 
+  it('throws an error when calling legacy getUserMedia with invalid chromeMediaSourceId', async () => {
+    const w = new BrowserWindow({ show: false });
+    await w.loadURL(serverUrl);
+    const { ok, message } = await w.webContents.executeJavaScript(`
+      new Promise((resolve, reject) => navigator.getUserMedia({
+         video: {
+          mandatory: {
+            chromeMediaSource: 'desktop',
+            chromeMediaSourceId: undefined,
+          },
+        },
+      }, x => resolve({ok: x instanceof MediaStream}), e => resolve({ ok: false, message: e.message })))
+    `);
+    expect(ok).to.be.false();
+    expect(message).to.equal('Invalid state');
+  });
+
   it('can remove a displayMediaRequestHandler', async () => {
     const ses = session.fromPartition('' + Math.random());