Files
MeshChatX/tests/frontend/mediaLottieStickerGifs.fuzzing.test.js

92 lines
2.7 KiB
JavaScript

import { gzipSync } from "node:zlib";
import { describe, it, expect, beforeAll } from "vitest";
import { decodeTgsBuffer } from "@/js/tgsDecode.js";
beforeAll(() => {
const ctx = {
fillStyle: "",
strokeStyle: "",
fillRect: vi.fn(),
clearRect: vi.fn(),
save: vi.fn(),
restore: vi.fn(),
translate: vi.fn(),
scale: vi.fn(),
rotate: vi.fn(),
beginPath: vi.fn(),
closePath: vi.fn(),
moveTo: vi.fn(),
lineTo: vi.fn(),
arc: vi.fn(),
fill: vi.fn(),
stroke: vi.fn(),
setTransform: vi.fn(),
drawImage: vi.fn(),
measureText: vi.fn(() => ({ width: 0 })),
createLinearGradient: vi.fn(() => ({ addColorStop: vi.fn() })),
createRadialGradient: vi.fn(() => ({ addColorStop: vi.fn() })),
};
HTMLCanvasElement.prototype.getContext = vi.fn(() => ctx);
});
function randomUint8Array(n) {
const u = new Uint8Array(n);
crypto.getRandomValues(u);
return u;
}
function randomJsonValue(depth) {
if (depth <= 0) {
return null;
}
const r = Math.random();
if (r < 0.2) {
return null;
}
if (r < 0.4) {
return Math.floor(Math.random() * 1_000_000);
}
if (r < 0.55) {
return String.fromCharCode(32 + Math.floor(Math.random() * 80));
}
if (r < 0.75) {
const n = Math.floor(Math.random() * 8);
return Array.from({ length: n }, () => randomJsonValue(depth - 1));
}
const n = Math.floor(Math.random() * 6);
const o = {};
for (let i = 0; i < n; i++) {
o[`k${i}`] = randomJsonValue(depth - 1);
}
return o;
}
describe("fuzzing: TGS decode", () => {
it("fuzzing: decodeTgsBuffer handles random buffers without unhandled rejection", async () => {
for (let i = 0; i < 2000; i++) {
const len = Math.floor(Math.random() * 6144);
const buf = randomUint8Array(len).buffer;
try {
await decodeTgsBuffer(buf);
} catch {
/* JSON.parse, gzip, or missing DecompressionStream */
}
}
expect(true).toBe(true);
});
it("fuzzing: decodeTgsBuffer handles gzip-compressed random JSON", async () => {
for (let i = 0; i < 400; i++) {
const payload = JSON.stringify(randomJsonValue(6));
const gz = gzipSync(Buffer.from(payload, "utf8"));
const ab = gz.buffer.slice(gz.byteOffset, gz.byteOffset + gz.byteLength);
try {
await decodeTgsBuffer(ab);
} catch {
/* invalid JSON after decompress */
}
}
expect(true).toBe(true);
});
});