FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(runtime): keep clone-only message reads read-only, and see an uncloneable brand created mid-clone by adrian-niculescu · Pull Request #490 · NativeScript/ios · GitHub

Repository navigation

Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .cpp  (1) .js  (2) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
17 changes: 13 additions & 4 deletions NativeScript/runtime/StructuredSerialization.cpp
This file contains hidden or 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
Expand Up @@ -161,6 +161,11 @@ class SerializerDelegate : public ValueSerializer::Delegate {
if (object->InternalFieldCount() > 0) {
return Just(true);
}
if (uncloneableBrand_.IsEmpty()) {
// markAsUncloneable creates the brand on its first call in an isolate,
// which a getter in the graph being written can make.
uncloneableBrand_ = messaging::UncloneableBrandIfAny(isolate);
}
if (!uncloneableBrand_.IsEmpty()) {
bool uncloneable = false;
if (!object->HasPrivate(isolate->GetCurrentContext(), uncloneableBrand_)
Expand Down Expand Up @@ -622,7 +627,8 @@ MaybeLocal<Value> SerializedValue::Deserialize(Isolate* isolate,
"A message carrying transferred objects can only be read once.");
return MaybeLocal<Value>();
}
if (HasTransferables()) {
const bool singleReceiver = HasTransferables();
if (singleReceiver) {
consumed_ = true;
}

Expand Down Expand Up @@ -716,9 +722,12 @@ MaybeLocal<Value> SerializedValue::Deserialize(Isolate* isolate,
ArrayBuffer::New(isolate, std::move(transferredBuffers_[i])));
}
// Handed over above; the vectors would otherwise keep reporting
// transferables that are no longer here.
transferredBuffers_.clear();
transferredPorts_.clear();
// transferables that are no longer here. Only the single receiver writes
// them: the other readers share this value with no lock.
if (singleReceiver) {
transferredBuffers_.clear();
transferredPorts_.clear();
}

Local<Value> result;
{
Expand Down
18 changes: 18 additions & 0 deletions TestRunner/app/tests/MessagingTests.js
This file contains hidden or 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
Expand Up @@ -295,6 +295,24 @@ describe("Messaging runtime edges", function () {
});
});

describe("markAsUncloneable", function () {
it("rejects an object marked while the clone that reaches it is written", function (done) {
var worker = new Worker("./messaging/uncloneableInGetterWorker.js");
worker.onmessage = function (event) {
expect(event.data).toEqual({ threw: true, name: "DataCloneError" });
worker.terminate();
done();
};
// fail() throws in this runner, which would skip done() when called
// from an event handler.
worker.onerror = function (error) {
expect("worker error: " + error.message).toBeNull();
worker.terminate();
done();
};
});
});

describe("worker error reporting", function () {
// A worker boots on its own thread, so the first error arrives whenever
// the runner gets to it; specs wait for it and only then settle for
Expand Down
This file contains hidden or 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,19 @@
// A fresh isolate: the markAsUncloneable call in the getter below is the first
// one this isolate has seen, and it happens while the clone that reaches the
// marked object is already being written.
var markAsUncloneable = require("node:worker_threads").markAsUncloneable;
var graph = {
get inner() {
var marked = { a: 1 };
markAsUncloneable(marked);
return marked;
},
};
var result;
try {
structuredClone(graph);
result = { threw: false };
} catch (e) {
result = { threw: true, name: e && e.name };
}
postMessage(result);
Loading

Back | FazBrowse Home | New Git URL