47 lines
2.9 KiB
TypeScript
47 lines
2.9 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
const root = path.resolve(import.meta.dirname, "../../..");
|
|
const source = fs.readFileSync(path.join(root, "tests/files/web/m12_glb_desktop_v1/mesh.glb"));
|
|
const maxBytes = 512 * 1024;
|
|
|
|
function rewriteJson(mutator: (document: any) => void): Buffer {
|
|
const jsonLength = source.readUInt32LE(12);
|
|
const document = JSON.parse(source.subarray(20, 20 + jsonLength).toString("utf8").trim());
|
|
mutator(document);
|
|
const json = Buffer.from(JSON.stringify(document));
|
|
const paddedLength = (json.length + 3) & ~3;
|
|
const output = Buffer.alloc(12 + 8 + paddedLength + (source.length - (20 + jsonLength)));
|
|
output.writeUInt32LE(0x46546c67, 0); output.writeUInt32LE(2, 4); output.writeUInt32LE(output.length, 8);
|
|
output.writeUInt32LE(paddedLength, 12); output.writeUInt32LE(0x4e4f534a, 16); json.copy(output, 20);
|
|
output.fill(0x20, 20 + json.length, 20 + paddedLength);
|
|
output.writeUInt32LE(source.readUInt32LE(20 + jsonLength), 20 + paddedLength);
|
|
output.writeUInt32LE(source.readUInt32LE(24 + jsonLength), 24 + paddedLength);
|
|
source.subarray(28 + jsonLength).copy(output, 28 + paddedLength);
|
|
return output;
|
|
}
|
|
|
|
test("rejects GLB sparse, extension, external URI and over-budget cases in a Chromium Worker", async ({ page }) => {
|
|
await page.goto("/");
|
|
const cases = [
|
|
{ id: "sparse", bytes: rewriteJson((document) => { document.accessors[0].sparse = { count: 1 }; }) },
|
|
{ id: "extension", bytes: rewriteJson((document) => { document.extensionsUsed = ["KHR_draco_mesh_compression"]; }) },
|
|
{ id: "external-uri", bytes: rewriteJson((document) => { document.buffers[0].uri = "external.bin"; }) },
|
|
{ id: "over-budget", bytes: Buffer.concat([source, Buffer.alloc(maxBytes + 1 - source.length)]) },
|
|
].map((candidate) => ({ id: candidate.id, bytes: Array.from(candidate.bytes) }));
|
|
const result = await page.evaluate((input) => new Promise<{ ok: boolean; results?: Array<{ id: string; code: string }>; error?: string }>((resolve, reject) => {
|
|
const worker = new Worker("/src/workers/glb-negative-cases-test.worker.ts", { type: "module" });
|
|
worker.onmessage = (event: MessageEvent<{ ok: boolean; results?: Array<{ id: string; code: string }>; error?: string }>) => { worker.terminate(); resolve(event.data); };
|
|
worker.onerror = (event) => { worker.terminate(); reject(new Error(event.message)); };
|
|
const cases = input.map((candidate) => ({ id: candidate.id, bytes: Uint8Array.from(candidate.bytes).buffer }));
|
|
worker.postMessage({ cases }, cases.map((candidate) => candidate.bytes));
|
|
}), cases);
|
|
expect(result).toEqual({ ok: true, results: [
|
|
{ id: "sparse", code: "GLB_SPARSE_ACCESSOR_UNSUPPORTED" },
|
|
{ id: "extension", code: "GLB_EXTENSION_UNSUPPORTED" },
|
|
{ id: "external-uri", code: "GLB_EXTERNAL_URI_BLOCKED" },
|
|
{ id: "over-budget", code: "GLB_IMPORT_BUDGET_EXCEEDED" },
|
|
] });
|
|
});
|