Skip to content

Commit d117567

Browse files
authored
Merge pull request #5195 from cloudflare/jasnell/fixup-jsg-ser
Fixup handling of ab/sab in jsg serialization
2 parents d1e54a5 + 50e6731 commit d117567

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

src/workerd/api/tests/global-scope-test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,3 +777,35 @@ export const reuseCtx = {
777777
ctx.reused = true;
778778
},
779779
};
780+
781+
export const structuredCloneError = {
782+
test() {
783+
// If it doesn't crash, we're good.
784+
var globalProp = {
785+
get p1() {
786+
return this;
787+
},
788+
get trigger() {
789+
function createSab() {
790+
var sab = new SharedArrayBuffer(4096);
791+
return sab;
792+
}
793+
var prop = {};
794+
Object.defineProperty(prop, 'constructor', {
795+
writable: true,
796+
value: createSab,
797+
});
798+
return prop.constructor();
799+
},
800+
get p1() {
801+
var gTCtor = globalThis.Intl.constructor;
802+
var returnVal;
803+
try {
804+
returnVal = gTCtor.entries(this);
805+
} catch (e) {}
806+
return returnVal;
807+
},
808+
};
809+
globalThis.structuredClone(globalProp);
810+
},
811+
};

src/workerd/jsg/ser.c++

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,16 @@ Serializer::Serializer(Lock& js, Options options)
159159

160160
v8::Maybe<uint32_t> Serializer::GetSharedArrayBufferId(
161161
v8::Isolate* isolate, v8::Local<v8::SharedArrayBuffer> sab) {
162+
auto& js = jsg::Lock::from(isolate);
162163
uint32_t n;
163164
auto value = JsValue(sab);
164165
for (n = 0; n < sharedArrayBuffers.size(); n++) {
165166
// If the SharedArrayBuffer has already been added, return the existing ID for it.
166-
if (sharedArrayBuffers[n] == value) {
167+
if (sharedArrayBuffers[n].getHandle(js) == value) {
167168
return v8::Just(n);
168169
}
169170
}
170-
sharedArrayBuffers.add(value);
171+
sharedArrayBuffers.add(jsg::JsRef(js, value));
171172
sharedBackingStores.add(sab->GetBackingStore());
172173
return v8::Just(n);
173174
}
@@ -352,11 +353,11 @@ void Serializer::transfer(Lock& js, const JsValue& value) {
352353
uint32_t n;
353354
for (n = 0; n < arrayBuffers.size(); n++) {
354355
// If the ArrayBuffer has already been added, we do not want to try adding it again.
355-
if (arrayBuffers[n] == value) {
356+
if (arrayBuffers[n].getHandle(js) == value) {
356357
return;
357358
}
358359
}
359-
arrayBuffers.add(value);
360+
arrayBuffers.add(jsg::JsRef(js, value));
360361

361362
backingStores.add(arrayBuffer->GetBackingStore());
362363
check(arrayBuffer->Detach(v8::Local<v8::Value>()));

src/workerd/jsg/ser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ class Serializer final: v8::ValueSerializer::Delegate {
197197

198198
kj::Maybe<ExternalHandler&> externalHandler;
199199

200-
kj::Vector<JsValue> sharedArrayBuffers;
201-
kj::Vector<JsValue> arrayBuffers;
200+
kj::Vector<jsg::JsRef<JsValue>> sharedArrayBuffers;
201+
kj::Vector<jsg::JsRef<JsValue>> arrayBuffers;
202202
kj::Vector<std::shared_ptr<v8::BackingStore>> sharedBackingStores;
203203
kj::Vector<std::shared_ptr<v8::BackingStore>> backingStores;
204204
bool released = false;

0 commit comments

Comments
 (0)