mirror of
https://github.com/morluto/rea
synced 2026-10-27 14:42:18 -04:00
3cfa00a29c
Validate XML bytes before shared syntax parsing so literal U+FFFD remains valid while malformed bytes and declaration mismatches fail at their producing boundary. Validation: 92 focused checks, 3 selected fake Apktool boundary checks, 6 final encoding controls, check:fast and docs:check. Ghidra coverage uses tiny real files and descriptors, without a real engine or Windows qualification. Refs #4712
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import { mkdir, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { expect, it } from "vitest";
|
|
import { readGhidraLanguageCatalog } from "../../../src/ghidra/GhidraLanguageCatalog.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
|
|
const xml =
|
|
'<language_definitions><language id="toy:LE:32:default" description="�"><compiler id="default"/></language></language_definitions>';
|
|
it.each([
|
|
{ name: "literal U+FFFD", bytes: Buffer.from(xml), expectedError: null },
|
|
{
|
|
name: "UTF-8 BOM",
|
|
bytes: Buffer.concat([Buffer.from([0xef, 0xbb, 0xbf]), Buffer.from(xml)]),
|
|
expectedError: null,
|
|
},
|
|
{
|
|
name: "UTF-16 BOM/declaration",
|
|
bytes: Buffer.concat([
|
|
Buffer.from([0xff, 0xfe]),
|
|
Buffer.from('<?xml version="1.0" encoding="UTF-16"?>' + xml, "utf16le"),
|
|
]),
|
|
expectedError: null,
|
|
},
|
|
{
|
|
name: "malformed UTF-8",
|
|
bytes: Buffer.concat([
|
|
Buffer.from('<language_definitions description="'),
|
|
Buffer.from([0xff]),
|
|
Buffer.from(
|
|
'"><language id="toy:LE:32:default"/></language_definitions>',
|
|
),
|
|
]),
|
|
expectedError: "invalid-bytes",
|
|
},
|
|
{
|
|
name: "encoding mismatch",
|
|
bytes: Buffer.from('<?xml version="1.0" encoding="UTF-16"?>' + xml),
|
|
expectedError: "encoding-mismatch",
|
|
},
|
|
{
|
|
name: "malformed XML alongside U+FFFD",
|
|
bytes: Buffer.from(xml.replace('id="toy:LE:32:default"', "id=unquoted")),
|
|
expectedError: "malformed",
|
|
},
|
|
])(
|
|
"reads $name at the language-file byte boundary",
|
|
async ({ bytes, expectedError }) => {
|
|
const root = await createTestTempDirectory("rea-ghidra-xml-encoding-");
|
|
const directory = join(
|
|
root,
|
|
"Ghidra",
|
|
"Processors",
|
|
"toy",
|
|
"data",
|
|
"languages",
|
|
);
|
|
await mkdir(directory, { recursive: true });
|
|
await writeFile(join(directory, "toy.ldefs"), bytes);
|
|
if (expectedError === null)
|
|
expect(await readGhidraLanguageCatalog(root)).toEqual([
|
|
{ id: "toy:LE:32:default", compilerSpecIds: ["default"] },
|
|
]);
|
|
else
|
|
await expect(readGhidraLanguageCatalog(root)).rejects.toMatchObject({
|
|
reason: expectedError,
|
|
});
|
|
},
|
|
);
|