Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: cherry-pick 55f6cb375 from chromium (#32806)
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
- Loading branch information
1 parent
5bf4483
commit 1082e6c
Showing
2 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
patches/chromium/merge_m-97_serial_check_for_detached_buffers_when_writing.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Reilly Grant <reillyg@chromium.org> | ||
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 <reillyg@chromium.org> | ||
Auto-Submit: Reilly Grant <reillyg@chromium.org> | ||
Reviewed-by: Hongchan Choi <hongchan@chromium.org> | ||
Cr-Original-Commit-Position: refs/heads/main@{#940631} | ||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3279207 | ||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> | ||
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'); |