fix(browser): advance storage pages by examined rows
This commit is contained in:
1 parent
242a0f2880
commit
83bbad2b2f
2 files changed
+112
-7
No files matched your search
@@ -140,3 +140,106 @@ it("keeps an omitted IndexedDB remote value unknown", async () => {
|
||||
expect(record).toMatchObject({ value_sha256: null, complete: false });
|
||||
expect(value.fingerprints_complete).toBe(false);
|
||||
});
|
||||
|
||||
it.each(["indexed_db", "cache"] as const)(
|
||||
"advances %s pagination past malformed rows without repeating evidence",
|
||||
async (scope) => {
|
||||
const offsets: unknown[] = [];
|
||||
const record = {
|
||||
key: { type: "number", value: 1 },
|
||||
primaryKey: { type: "number", value: 1 },
|
||||
value: { type: "string", value: "first" },
|
||||
};
|
||||
const cacheEntry = {
|
||||
requestURL: "https://example.test/first",
|
||||
requestMethod: "GET",
|
||||
requestHeaders: [],
|
||||
};
|
||||
const replies: Record<string, unknown> = {
|
||||
"Storage.getUsageAndQuota": { usage: 0, quota: 1000 },
|
||||
"DOMStorage.getDOMStorageItems": { entries: [] },
|
||||
"IndexedDB.requestDatabaseNames": {
|
||||
databaseNames: scope === "indexed_db" ? ["db"] : [],
|
||||
},
|
||||
"CacheStorage.requestCacheNames": {
|
||||
caches:
|
||||
scope === "cache" ? [{ cacheName: "cache", cacheId: "id" }] : [],
|
||||
},
|
||||
"Network.getCookies": { cookies: [] },
|
||||
"IndexedDB.requestDatabase": {
|
||||
databaseWithObjectStores: {
|
||||
name: "db",
|
||||
version: 1,
|
||||
objectStores: [
|
||||
{
|
||||
name: "records",
|
||||
keyPath: { type: "string", string: "id" },
|
||||
autoIncrement: false,
|
||||
indexes: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
"CacheStorage.requestCachedResponse": { response: { body: "" } },
|
||||
};
|
||||
const connection = {
|
||||
async send(
|
||||
method: string,
|
||||
params: Record<string, unknown>,
|
||||
): Promise<unknown> {
|
||||
if (
|
||||
method === "IndexedDB.requestData" ||
|
||||
method === "CacheStorage.requestEntries"
|
||||
) {
|
||||
offsets.push(params.skipCount);
|
||||
// The first page includes a malformed row; offset 1 repeats valid evidence.
|
||||
const rows =
|
||||
params.skipCount === 0
|
||||
? [null, scope === "indexed_db" ? record : cacheEntry]
|
||||
: params.skipCount === 1
|
||||
? [scope === "indexed_db" ? record : cacheEntry]
|
||||
: [
|
||||
scope === "indexed_db"
|
||||
? {
|
||||
...record,
|
||||
key: { type: "number", value: 2 },
|
||||
primaryKey: { type: "number", value: 2 },
|
||||
}
|
||||
: {
|
||||
...cacheEntry,
|
||||
requestURL: "https://example.test/second",
|
||||
},
|
||||
];
|
||||
return method === "IndexedDB.requestData"
|
||||
? { objectStoreDataEntries: rows, hasMore: params.skipCount === 0 }
|
||||
: { cacheDataEntries: rows, returnCount: 3 };
|
||||
}
|
||||
if (!(method in replies)) throw new Error(method);
|
||||
return replies[method];
|
||||
},
|
||||
} as unknown as CdpConnection;
|
||||
const { value } = await captureStorage(
|
||||
{
|
||||
connection,
|
||||
sessionId: undefined,
|
||||
input: inspectWebPageInputSchema.parse({
|
||||
cdp_endpoint: "http://127.0.0.1:9222",
|
||||
target_id: "page",
|
||||
include_storage_keys: true,
|
||||
include_storage_fingerprints: true,
|
||||
}),
|
||||
},
|
||||
"https://example.test/",
|
||||
[],
|
||||
);
|
||||
expect(offsets).toEqual([0, 2]);
|
||||
expect(
|
||||
value.content_fingerprints.filter(
|
||||
(item) =>
|
||||
item.scope ===
|
||||
(scope === "indexed_db" ? "indexed_db_record" : "cache_entry"),
|
||||
),
|
||||
).toHaveLength(2);
|
||||
expect(value.fingerprints_complete).toBe(false);
|
||||
},
|
||||
);
|
||||
@@ -313,6 +313,7 @@ const addIndexedDbRecords = async (
|
||||
run.state.complete = false;
|
||||
return;
|
||||
}
|
||||
const examinedCount = result.objectStoreDataEntries.length;
|
||||
const entries = recordsValue(result.objectStoreDataEntries);
|
||||
if (entries.length !== result.objectStoreDataEntries.length)
|
||||
run.state.complete = false;
|
||||
@@ -335,13 +336,13 @@ const addIndexedDbRecords = async (
|
||||
}
|
||||
if (result.hasMore !== true) return;
|
||||
if (
|
||||
entries.length === 0 ||
|
||||
skipCount > Number.MAX_SAFE_INTEGER - entries.length
|
||||
examinedCount === 0 ||
|
||||
skipCount > Number.MAX_SAFE_INTEGER - examinedCount
|
||||
) {
|
||||
run.state.complete = false;
|
||||
return;
|
||||
}
|
||||
skipCount += entries.length;
|
||||
skipCount += examinedCount;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -373,20 +374,21 @@ const addCaches = async (
|
||||
run.state.complete = false;
|
||||
break;
|
||||
}
|
||||
const examinedCount = result.cacheDataEntries.length;
|
||||
const entries = recordsValue(result.cacheDataEntries);
|
||||
if (entries.length !== result.cacheDataEntries.length)
|
||||
run.state.complete = false;
|
||||
for (const entry of entries) await addCacheEntry(run, cache, entry);
|
||||
returnCount = result.returnCount;
|
||||
if (skipCount + entries.length >= returnCount) break;
|
||||
if (skipCount + examinedCount >= returnCount) break;
|
||||
if (
|
||||
entries.length === 0 ||
|
||||
skipCount > Number.MAX_SAFE_INTEGER - entries.length
|
||||
examinedCount === 0 ||
|
||||
skipCount > Number.MAX_SAFE_INTEGER - examinedCount
|
||||
) {
|
||||
run.state.complete = false;
|
||||
break;
|
||||
}
|
||||
skipCount += entries.length;
|
||||
skipCount += examinedCount;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user