Browse Source

chore: cherry-pick 55f6cb37 from chromium (#32794)

* chore: cherry-pick 55f6cb37 from chromium

Backports https://chromium-review.googlesource.com/c/chromium/src/+/3279207

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <[email protected]>
Robo 3 years ago
parent
commit
f6d2b9dc63

+ 1 - 0
patches/chromium/.patches

@@ -133,3 +133,4 @@ cherry-pick-f781748dcb3c.patch
 cherry-pick-c5571653d932.patch
 fix_crash_when_saving_edited_pdf_files.patch
 cherry-pick-1284367.patch
+merge_m-97_serial_check_for_detached_buffers_when_writing.patch

+ 122 - 0
patches/chromium/merge_m-97_serial_check_for_detached_buffers_when_writing.patch

@@ -0,0 +1,122 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Reilly Grant <[email protected]>
+Date: Fri, 12 Nov 2021 20:09:12 +0000
+Subject: serial: Check for detached buffers when writing
+
+This change adds check in SerialPortUnderlyingSink::WriteData() to
+ensure that the V8BufferSource being written to the Mojo data pipe has
+not been detached since it was passed to the WritableStream.
+
+(cherry picked from commit 7ce1516b49e86430c9216d0df8e23a325104a8c5)
+
+Bug: 1267627
+Change-Id: I63d48584eb0be1c1d87c27115900aa5c17931fcf
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3269348
+Commit-Queue: Reilly Grant <[email protected]>
+Auto-Submit: Reilly Grant <[email protected]>
+Reviewed-by: Hongchan Choi <[email protected]>
+Cr-Original-Commit-Position: refs/heads/main@{#940631}
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3279207
+Bot-Commit: Rubber Stamper <[email protected]>
+Cr-Commit-Position: refs/branch-heads/4692@{#132}
+Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
+
+diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
+index 08ab2c7e05668710b77712f3ffc0d5aeef4dd213..7876baf19a1f547c71e2a115db8a2cc4ccd43a3b 100644
+--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
++++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
+@@ -172,12 +172,25 @@ void SerialPortUnderlyingSink::WriteData() {
+   DCHECK(buffer_source_);
+ 
+   DOMArrayPiece array_piece(buffer_source_);
++  // From https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy, if the
++  // buffer source is detached then an empty byte sequence is returned, which
++  // means the write is complete.
++  if (array_piece.IsDetached()) {
++    buffer_source_ = nullptr;
++    offset_ = 0;
++    pending_operation_->Resolve();
++    pending_operation_ = nullptr;
++    return;
++  }
++
+   if (array_piece.ByteLength() > std::numeric_limits<uint32_t>::max()) {
+-    pending_exception_ = DOMException::Create(
+-        "Buffer size exceeds maximum heap object size.", "DataError");
++    pending_exception_ = MakeGarbageCollected<DOMException>(
++        DOMExceptionCode::kDataError,
++        "Buffer size exceeds maximum heap object size.");
+     PipeClosed();
+     return;
+   }
++
+   const uint8_t* data = array_piece.Bytes();
+   const uint32_t length = static_cast<uint32_t>(array_piece.ByteLength());
+ 
+diff --git a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
+index 9728af7de5051dce874e10082e1443a3ca9fa7dc..5e3b8548a91ddc2a0afa9793dea167f8e89defe3 100644
+--- a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
++++ b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
+@@ -70,7 +70,7 @@ serial_test(async (t, fake) => {
+   compareArrays(data, value);
+ 
+   await port.close();
+-}, 'Can read a large amount of data');
++}, 'Can write a large amount of data');
+ 
+ serial_test(async (t, fake) => {
+   const {port, fakePort} = await getFakeSerialPort(fake);
+diff --git a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js
+new file mode 100644
+index 0000000000000000000000000000000000000000..828e877726b1c63dba14efc36324d9a16aa4e62f
+--- /dev/null
++++ b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js
+@@ -0,0 +1,48 @@
++// META: script=/resources/test-only-api.js
++// META: script=/serial/resources/common.js
++// META: script=resources/automation.js
++
++function detachBuffer(buffer) {
++  const channel = new MessageChannel();
++  channel.port1.postMessage('', [buffer]);
++}
++
++serial_test(async (t, fake) => {
++  const {port, fakePort} = await getFakeSerialPort(fake);
++  await port.open({baudRate: 9600, bufferSize: 64});
++
++  const writer = port.writable.getWriter();
++  const data = new Uint8Array(64);
++  detachBuffer(data.buffer);
++
++  // Writing a detached buffer is equivalent to writing an empty buffer so this
++  // should trivially succeed.
++  await writer.write(data);
++  writer.releaseLock();
++
++  await port.close();
++}, 'Writing a detached buffer is safe');
++
++serial_test(async (t, fake) => {
++  const {port, fakePort} = await getFakeSerialPort(fake);
++  // Select a buffer size smaller than the amount of data transferred.
++  await port.open({baudRate: 9600, bufferSize: 64});
++
++  // Start writing a buffer much larger than bufferSize above so that it can't
++  // all be transfered in a single operation.
++  const writer = port.writable.getWriter();
++  const data = new Uint8Array(1024);
++  const promise = writer.write(data);
++  writer.releaseLock();
++
++  // Read half of the written data and then detach the buffer.
++  await fakePort.readable();
++  await fakePort.readWithLength(data.byteLength / 2);
++  detachBuffer(data.buffer);
++
++  // When the buffer is detached its length becomes zero and so the write should
++  // succeed but it is undefined how much data was written before that happened.
++  await promise;
++
++  await port.close();
++}, 'Detaching a buffer while writing is safe');