From b19684fde92aafa67577429552ae6c39f59b145c Mon Sep 17 00:00:00 2001 From: Nicholas Molnar <65710+neekolas@users.noreply.github.com> Date: Mon, 12 Oct 2026 17:53:58 -0700 Subject: [PATCH] Avoid duplicate browser migration archive copy --- crates/xmtp_legacy_migration/src/wasm.rs | 5 ++++- .../test/platform/migration/archive-read-limit.mjs | 12 +++++++++++- .../test/platform/migration/read-limit-worker.mjs | 8 ++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/xmtp_legacy_migration/src/wasm.rs b/crates/xmtp_legacy_migration/src/wasm.rs index b904f7a29c..90f4071594 100644 --- a/crates/xmtp_legacy_migration/src/wasm.rs +++ b/crates/xmtp_legacy_migration/src/wasm.rs @@ -144,5 +144,8 @@ pub(crate) async fn read(path: &str) -> Result, MigrationError> { let bytes = read_output(path) .await .map_err(|value| MigrationError::Output(OutputError::Browser { value }))?; - Ok(js_sys::Uint8Array::new(&bytes).to_vec()) + Ok(bytes + .dyn_into::() + .map_err(output)? + .to_vec()) } diff --git a/sdks/browser/test/platform/migration/archive-read-limit.mjs b/sdks/browser/test/platform/migration/archive-read-limit.mjs index 1a2238929c..1ce8ef65a7 100644 --- a/sdks/browser/test/platform/migration/archive-read-limit.mjs +++ b/sdks/browser/test/platform/migration/archive-read-limit.mjs @@ -5,6 +5,7 @@ import { createMigrationServer, withMigrationPage } from "./server.mjs"; const limit = 100_000_000; const allocations = []; +const copies = []; const server = await createMigrationServer( "crates/xmtp_legacy_migration/fixtures", ["stable"], @@ -17,6 +18,10 @@ try { allocations.push( Number(event.text().slice("MIGRATION_ARCHIVE_READ ".length)), ); + if (event.text().startsWith("MIGRATION_ARCHIVE_COPY ")) + copies.push( + Number(event.text().slice("MIGRATION_ARCHIVE_COPY ".length)), + ); }); // verifies: MIG-008 const result = await page.evaluate(async (limit) => { @@ -127,6 +132,11 @@ try { assert.equal(result.retry, true); assert.equal(result.sourceUnchanged, true); assert.ok(allocations.includes(limit), "boundary read was not observed"); + assert.equal( + copies.includes(limit), + false, + "archive read made a duplicate 100 MB byte-array copy", + ); assert.equal( allocations.includes(limit + 1), false, @@ -134,7 +144,7 @@ try { ); }); console.log( - "Browser archive read: inclusive 100 MB limit, rejection before allocation, preservation, and retry passed", + "Browser archive read: inclusive 100 MB limit, no duplicate copy, rejection before allocation, preservation, and retry passed", ); } finally { await browser.close(); diff --git a/sdks/browser/test/platform/migration/read-limit-worker.mjs b/sdks/browser/test/platform/migration/read-limit-worker.mjs index 302866129e..00a6485869 100644 --- a/sdks/browser/test/platform/migration/read-limit-worker.mjs +++ b/sdks/browser/test/platform/migration/read-limit-worker.mjs @@ -1,6 +1,14 @@ // Observe the real OPFS archive read without replacing it. const pending = []; self.onmessage = (event) => pending.push(event); +const NativeUint8Array = Uint8Array; +globalThis.Uint8Array = new Proxy(NativeUint8Array, { + construct(target, args, newTarget) { + if (args[0] instanceof NativeUint8Array) + console.log("MIGRATION_ARCHIVE_COPY " + args[0].byteLength); + return Reflect.construct(target, args, newTarget); + }, +}); const read = Blob.prototype.arrayBuffer; Blob.prototype.arrayBuffer = function (...args) { if (this instanceof File && this.name.startsWith("archive-"))