Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/thick-spiders-invite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: Correctly handle shared memory when decoding binary form data
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/form-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export async function deserialize_binary_form(request) {
`Could not deserialize binary form: got version ${header[0]}, expected version ${BINARY_FORM_VERSION}`
);
}
const header_view = new DataView(header.buffer);
const header_view = new DataView(header.buffer, header.byteOffset, header.byteLength);
const data_length = header_view.getUint32(1, true);
const file_offsets_length = header_view.getUint16(5, true);

Expand Down
29 changes: 29 additions & 0 deletions packages/kit/src/runtime/form-utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,33 @@ describe('binary form serializer', () => {
expect(await world_slice.text()).toBe('World');
expect(world_slice.type).toBe(file.type);
});

// Regression test for https://github.com/sveltejs/kit/issues/14971
test('DataView offset for shared memory', async () => {
const { blob } = serialize_binary_form({ a: 1 }, {});
const chunk = new Uint8Array(await blob.arrayBuffer());
// Simulate a stream that has extra bytes at the start in the underlying buffer
const stream = new ReadableStream({
start(controller) {
const offset_buffer = new Uint8Array(chunk.byteLength + 10);
offset_buffer.fill(255);
offset_buffer.set(chunk, 10);
controller.enqueue(offset_buffer.subarray(10));
}
});

const res = await deserialize_binary_form(
new Request('http://test', {
method: 'POST',
body: stream,
// @ts-expect-error duplex required in node
duplex: 'half',
headers: {
'Content-Type': BINARY_FORM_CONTENT_TYPE
}
})
);

expect(res.data).toEqual({ a: 1 });
});
});
Loading