mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
fix(wasm): preserve core inspection with optional metadata warnings
Retain warnings from validator, objdump and decoder through one diagnostic owner. Keep uninterpretable name bytes and explicit name-metadata coverage in complete results and summaries. Fixes #6812
This commit is contained in:
+17
-8
@@ -62,14 +62,23 @@ returns `resource_constraint` with resource `file-size` and its fixed byte
|
||||
allowance in `reported_limits.maximum_input_bytes`; retrying the unchanged file
|
||||
does not raise that allowance. WASM bytes are copied
|
||||
into a private workspace as read-only `module.wasm`; its digest is rechecked
|
||||
before and after each tool. WABT validates with `--enable-all`,
|
||||
reports sections through `wasm-objdump -h -x`, and decodes through
|
||||
`wasm2wat --enable-all`. The result retains selected byte SHA-256 and size,
|
||||
section payload ranges, full header/detail output (including module-name
|
||||
preambles), exact import/export WAT
|
||||
forms, decoded WAT and its UTF-8 SHA-256. Producer format drift and invalid or
|
||||
truncated modules are failures, with validation diagnostics and partial Evidence
|
||||
retaining selected byte identity and tool provenance.
|
||||
before and after each tool. WABT validates with
|
||||
`wasm-validate --enable-all --ignore-custom-section-errors`, reports sections
|
||||
through `wasm-objdump -h -x`, and decodes through
|
||||
`wasm2wat --enable-all --ignore-custom-section-errors`. The result retains
|
||||
selected byte SHA-256 and size, section payload ranges, full header/detail output
|
||||
(including module-name preambles), exact import/export WAT forms, decoded WAT
|
||||
and its UTF-8 SHA-256. Producer format drift and invalid or truncated modules
|
||||
are failures, with validation diagnostics and partial Evidence retaining
|
||||
selected byte identity and tool provenance.
|
||||
|
||||
Core validation remains authoritative when an optional custom section cannot
|
||||
be interpreted. WABT warning output is preserved in `custom_section_warnings`;
|
||||
`debug_name_metadata` reports whether the optional name section was absent,
|
||||
fully interpreted, or uninterpretable. Older portable reports retain their
|
||||
original strict command profile; missing metadata coverage is `unknown` and
|
||||
missing warning history is `null`. The raw custom section remains in the
|
||||
decoded WAT. An uninterpretable name section leaves debug module names unknown.
|
||||
|
||||
The tool profile preserves upstream release/source identity, resolved executable
|
||||
paths, executable digests, exact banners and arguments. Executable digests are
|
||||
|
||||
@@ -22,7 +22,7 @@ export const INSPECT_WASM_ARTIFACT_CONTRACT = {
|
||||
...toolContractMetadata("inspect_wasm_artifact"),
|
||||
kind: "artifact-provider",
|
||||
description:
|
||||
'Validate an explicit local WASM artifact with caller-supplied WABT 1.0.42. Omitted or complete detail returns exact byte SHA-256, sections, upstream import/export WAT forms and decoded WAT inline as Evidence. For counts, validation and WAT identity without WAT text, pass detail: "summary" on this first call; it retains the complete original Evidence and returns the same typed summary as inspect_analysis_view, avoiding oversized complete delivery. Read exact imports/exports or WAT pages with inspect_analysis_view using normalized_result.parent_evidence_id. Delivery selection does not change analysis, provider inputs or source identity. Adjust command_timeout_ms for each WABT command (default 30000 ms), separately from the client deadline; input/output safety limits stay fixed. Optionally associate selected JavaScript glue literals with explicit local candidates while preserving ambiguous URL/basename matches. Configure absolute REA_WABT_BIN_DIRECTORY. No installation, implicit fetch, WASM execution or original-source claim.',
|
||||
'Validate an explicit local WASM artifact with caller-supplied WABT 1.0.42. Optional custom-section interpretation errors do not invalidate the core module; warnings and name-section interpretation status remain in the result. Omitted or complete detail returns exact byte SHA-256, sections, upstream import/export WAT forms and decoded WAT inline as Evidence. For counts, validation and WAT identity without WAT text, pass detail: "summary" on this first call; it retains the complete original Evidence and returns the same typed summary as inspect_analysis_view, avoiding oversized complete delivery. Read exact imports/exports or WAT pages with inspect_analysis_view using normalized_result.parent_evidence_id. Delivery selection does not change analysis, provider inputs or source identity. Adjust command_timeout_ms for each WABT command (default 30000 ms), separately from the client deadline; input/output safety limits stay fixed. Optionally associate selected JavaScript glue literals with explicit local candidates while preserving ambiguous URL/basename matches. Configure absolute REA_WABT_BIN_DIRECTORY. No installation, implicit fetch, WASM execution or original-source claim.',
|
||||
inputSchema: wasmArtifactInspectionInputSchema,
|
||||
outputSchema: analysisDetailOutputSchemaOf(
|
||||
wasmArtifactSchema,
|
||||
|
||||
@@ -50,6 +50,8 @@ export const wasmViewItemSchema = z.union([
|
||||
export const wasmSummarySchema = z.strictObject({
|
||||
bytes: wasmArtifactSchema.shape.artifact.shape.bytes,
|
||||
validation: wasmArtifactSchema.shape.validation,
|
||||
debug_name_metadata: wasmArtifactSchema.shape.debug_name_metadata,
|
||||
custom_section_warnings: wasmArtifactSchema.shape.custom_section_warnings,
|
||||
available_counts: z.strictObject({
|
||||
sections: z.int().nonnegative(),
|
||||
imports: z.int().nonnegative(),
|
||||
@@ -133,6 +135,8 @@ export const projectWasmArtifactView = (
|
||||
summary: {
|
||||
bytes: report.artifact.bytes,
|
||||
validation: report.validation,
|
||||
debug_name_metadata: report.debug_name_metadata,
|
||||
custom_section_warnings: report.custom_section_warnings,
|
||||
available_counts: {
|
||||
sections: report.sections.length,
|
||||
imports: report.imports.length,
|
||||
|
||||
@@ -48,6 +48,18 @@ export const wasmArtifactSchema = z
|
||||
interface: wasmInterfaceSchema.exactOptional(),
|
||||
imports: z.array(z.string()),
|
||||
exports: z.array(z.string()),
|
||||
debug_name_metadata: z
|
||||
.enum(["unknown", "not-present", "complete", "uninterpretable"])
|
||||
.default("unknown"),
|
||||
custom_section_warnings: z
|
||||
.array(
|
||||
z.strictObject({
|
||||
tool: z.enum(["wasm-validate", "wasm-objdump", "wasm2wat"]),
|
||||
text: z.string().min(1),
|
||||
}),
|
||||
)
|
||||
.nullable()
|
||||
.default(null),
|
||||
headers: z.string(),
|
||||
details: z.string(),
|
||||
wat: z.strictObject({
|
||||
@@ -119,12 +131,18 @@ export const wasmArtifactSchema = z
|
||||
path: ["candidates"],
|
||||
message: "Selected candidate does not match artifact identity.",
|
||||
});
|
||||
const tolerantCustomSections =
|
||||
value.tool_profile.commands[0]?.arguments.includes(
|
||||
"--ignore-custom-section-errors",
|
||||
);
|
||||
for (const [index, command] of value.tool_profile.commands.entries()) {
|
||||
const expected = ["wasm-validate", "wasm-objdump", "wasm2wat"][index];
|
||||
const argumentsExpected =
|
||||
command.tool === "wasm-objdump"
|
||||
? ["-h", "-x", "module.wasm"]
|
||||
: ["--enable-all", "module.wasm"];
|
||||
: tolerantCustomSections
|
||||
? ["--enable-all", "--ignore-custom-section-errors", "module.wasm"]
|
||||
: ["--enable-all", "module.wasm"];
|
||||
if (
|
||||
command.tool !== expected ||
|
||||
command.version_banner.trim() !== "1.0.42" ||
|
||||
|
||||
@@ -207,6 +207,77 @@ const createWabtArtifactFixture = async () => {
|
||||
return { selectedRoot, path, bytes, dump };
|
||||
};
|
||||
|
||||
it("keeps core WASM usable when optional name-section metadata is malformed", async () => {
|
||||
const fixture = await createWabtArtifactFixture();
|
||||
const diagnostic =
|
||||
"0000011: warning: invalid sub-section size: extends past end\n";
|
||||
const dump = [
|
||||
"",
|
||||
"module.wasm:\tfile format wasm 0x1",
|
||||
"",
|
||||
"Sections:",
|
||||
"",
|
||||
' Custom start=0x0000000a end=0x0000004c (size=0x00000042) "name"',
|
||||
"",
|
||||
"Section Details:",
|
||||
"",
|
||||
].join("\n");
|
||||
const provider = new WabtArtifactProvider(
|
||||
{ REA_WABT_BIN_DIRECTORY: fixture.selectedRoot },
|
||||
(input) => {
|
||||
const version = input.arguments[0] === "--version";
|
||||
const isObjdump = input.command.includes("wasm-objdump");
|
||||
const isDecoder = input.command.includes("wasm2wat");
|
||||
const stdout = version
|
||||
? "1.0.42\n"
|
||||
: isObjdump
|
||||
? dump
|
||||
: isDecoder
|
||||
? '(module (@custom "name" "abc"))\n'
|
||||
: "";
|
||||
const stderr = version ? "" : diagnostic;
|
||||
return spawnOwnedProviderProcess({
|
||||
...input,
|
||||
hostEnvironment: nodeHostEnvironment(input.hostEnvironment),
|
||||
command: process.execPath,
|
||||
arguments: [
|
||||
"-e",
|
||||
`process.stdout.write(${JSON.stringify(stdout)}); process.stderr.write(${JSON.stringify(stderr)});`,
|
||||
],
|
||||
expectedCommand: null,
|
||||
});
|
||||
},
|
||||
);
|
||||
try {
|
||||
const result = await provider.inspect({
|
||||
path: fixture.path,
|
||||
glue_paths: [],
|
||||
candidate_paths: [],
|
||||
});
|
||||
if (!result.ok) throw result.error;
|
||||
expect(result.value.result).toMatchObject({
|
||||
validation: "valid",
|
||||
debug_name_metadata: "uninterpretable",
|
||||
custom_section_warnings: [
|
||||
{ tool: "wasm-validate", text: diagnostic },
|
||||
{ tool: "wasm-objdump", text: diagnostic },
|
||||
{ tool: "wasm2wat", text: diagnostic },
|
||||
],
|
||||
sections: [{ kind: "Custom", start: 10, end: 76, description: '"name"' }],
|
||||
limitations: expect.arrayContaining([
|
||||
expect.stringContaining("optional WebAssembly name custom section"),
|
||||
]),
|
||||
});
|
||||
expect(
|
||||
wasmArtifactSchema.parse(result.value.result).tool_profile.commands[0]
|
||||
?.arguments,
|
||||
).toContain("--ignore-custom-section-errors");
|
||||
expect(await readFile(fixture.path)).toEqual(fixture.bytes);
|
||||
} finally {
|
||||
await provider.close();
|
||||
}
|
||||
});
|
||||
|
||||
const assertModeOutcome = (
|
||||
mode: OutcomeMode,
|
||||
result: Awaited<ReturnType<WabtArtifactProvider["inspect"]>>,
|
||||
|
||||
@@ -59,6 +59,11 @@ type Launcher = NonNullable<Parameters<typeof runOwnedCommand>[2]>["launcher"];
|
||||
const OPERATION = "inspect_wasm_artifact";
|
||||
const digest = (text: string) =>
|
||||
createHash("sha256").update(text).digest("hex");
|
||||
const warningOutput = (text: string): readonly string[] | null => {
|
||||
if (text === "") return [];
|
||||
const lines = text.trimEnd().split("\n");
|
||||
return lines.every((line) => /^\S+: warning: /u.test(line)) ? lines : null;
|
||||
};
|
||||
/** Run caller-supplied WABT against private copies of exactly selected bytes. */
|
||||
export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
readonly #resources = new ArtifactResourceScope();
|
||||
@@ -123,13 +128,17 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
"REA_WABT_BIN_DIRECTORY must be an absolute tool directory.",
|
||||
);
|
||||
const commands: {
|
||||
tool: string;
|
||||
tool: "wasm-validate" | "wasm-objdump" | "wasm2wat";
|
||||
path: string;
|
||||
sha256: string;
|
||||
version_banner: string;
|
||||
arguments: string[];
|
||||
}[] = [];
|
||||
for (const tool of ["wasm-validate", "wasm-objdump", "wasm2wat"]) {
|
||||
for (const tool of [
|
||||
"wasm-validate",
|
||||
"wasm-objdump",
|
||||
"wasm2wat",
|
||||
] as const) {
|
||||
const path = await realpath(
|
||||
join(
|
||||
directory,
|
||||
@@ -152,7 +161,11 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
arguments:
|
||||
tool === "wasm-objdump"
|
||||
? ["-h", "-x", "module.wasm"]
|
||||
: ["--enable-all", "module.wasm"],
|
||||
: [
|
||||
"--enable-all",
|
||||
"--ignore-custom-section-errors",
|
||||
"module.wasm",
|
||||
],
|
||||
});
|
||||
}
|
||||
const root = await this.createRuntime();
|
||||
@@ -349,7 +362,7 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
confidence: "observed",
|
||||
locations: [{ kind: "artifact-path", path: input.path }],
|
||||
limitations: [
|
||||
"WABT rejected these exact selected bytes with --enable-all; no complete inspection or target execution occurred.",
|
||||
"WABT rejected these exact selected bytes with --enable-all and --ignore-custom-section-errors; no complete inspection or target execution occurred.",
|
||||
],
|
||||
},
|
||||
),
|
||||
@@ -364,28 +377,51 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
path: ["path"],
|
||||
reason: "invalid_format",
|
||||
message:
|
||||
"Selected bytes failed WABT validation with --enable-all; inspect retained upstream diagnostics.",
|
||||
"Selected bytes failed WABT validation with --enable-all and --ignore-custom-section-errors; inspect retained upstream diagnostics.",
|
||||
},
|
||||
],
|
||||
);
|
||||
const customSectionWarnings: {
|
||||
tool: (typeof commands)[number]["tool"];
|
||||
text: string;
|
||||
}[] = [];
|
||||
const optionalLimitations: string[] = [];
|
||||
const retainWarnings = (
|
||||
tool: (typeof commands)[number]["tool"],
|
||||
output: typeof validation,
|
||||
) => {
|
||||
const warnings = warningOutput(output.stderr.text);
|
||||
if (warnings === null)
|
||||
throw new AnalysisOutputError(
|
||||
OPERATION,
|
||||
"Unexpected WABT diagnostic output.",
|
||||
{
|
||||
capturedOutput: {
|
||||
stdout: output.stdout.text,
|
||||
stderr: output.stderr.text,
|
||||
truncated: false,
|
||||
},
|
||||
},
|
||||
);
|
||||
if (warnings.length > 0)
|
||||
customSectionWarnings.push({ tool, text: output.stderr.text });
|
||||
};
|
||||
retainWarnings("wasm-validate", validation);
|
||||
const dump = await execute(objdump, objdump.arguments);
|
||||
capturedOutput = {
|
||||
stdout: dump.stdout.text,
|
||||
stderr: dump.stderr.text,
|
||||
truncated: false,
|
||||
};
|
||||
if (dump.stderr.text !== "")
|
||||
throw new AnalysisOutputError(
|
||||
OPERATION,
|
||||
"Unexpected WABT section output.",
|
||||
);
|
||||
retainWarnings("wasm-objdump", dump);
|
||||
const wat = await execute(decode, decode.arguments);
|
||||
capturedOutput = {
|
||||
stdout: wat.stdout.text,
|
||||
stderr: wat.stderr.text,
|
||||
truncated: false,
|
||||
};
|
||||
if (!wat.stdout.text.startsWith("(module") || wat.stderr.text !== "")
|
||||
retainWarnings("wasm2wat", wat);
|
||||
if (!wat.stdout.text.startsWith("(module"))
|
||||
throw new AnalysisOutputError(
|
||||
OPERATION,
|
||||
"Unexpected WABT decoding output.",
|
||||
@@ -395,8 +431,17 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
exports,
|
||||
customSectionNames,
|
||||
debugModuleNames,
|
||||
debugNameMetadata,
|
||||
interface: interfaceFacts,
|
||||
} = parseWabtWat(wat.stdout.text);
|
||||
if (debugNameMetadata === "uninterpretable")
|
||||
optionalLimitations.push(
|
||||
"The optional WebAssembly name custom section could not be interpreted; its original custom-section payload remains in decoded WAT, while debug module names are unavailable.",
|
||||
);
|
||||
if (customSectionWarnings.length > 0)
|
||||
optionalLimitations.push(
|
||||
"WABT reported optional custom-section interpretation warnings; exact warning output is retained in custom_section_warnings.",
|
||||
);
|
||||
capturedOutput = {
|
||||
stdout: dump.stdout.text,
|
||||
stderr: dump.stderr.text,
|
||||
@@ -414,6 +459,7 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
"JavaScript references are AST-observed static literals only. Candidate matches are associations, not proven data flow, URL-to-file identity or runtime loading. Computed references and aliases are not resolved.",
|
||||
"No target execution or implicit fetch. WABT tools are trusted caller-supplied executables; SHA-256 identifies their bytes, not publisher authenticity. No OS memory sandbox is claimed.",
|
||||
`Each WABT command has a ${String(commandTimeoutMs)} ms deadline and a fixed 32 MiB combined output budget. The deadline is not a whole-inspection budget. Oversized output fails instead of producing truncated success.`,
|
||||
...optionalLimitations,
|
||||
];
|
||||
const report = wasmArtifactSchema.parse({
|
||||
artifact,
|
||||
@@ -422,6 +468,8 @@ export class WabtArtifactProvider implements WasmArtifactPort {
|
||||
imports,
|
||||
exports,
|
||||
interface: interfaceFacts,
|
||||
debug_name_metadata: debugNameMetadata,
|
||||
custom_section_warnings: customSectionWarnings,
|
||||
headers,
|
||||
details,
|
||||
wat: {
|
||||
|
||||
@@ -196,8 +196,12 @@ it.each([
|
||||
it.each([
|
||||
'(module (@custom "name" "\\00\\06\\05name"))',
|
||||
'(module (@custom "name" "\\00\\05\\05name"))',
|
||||
])("rejects incomplete decoded module-name metadata: %s", (text) => {
|
||||
expect(() => parseWabtWat(text)).toThrow(/metadata/u);
|
||||
])("retains an uninterpretable optional name section: %s", (text) => {
|
||||
expect(parseWabtWat(text)).toMatchObject({
|
||||
customSectionNames: ["name"],
|
||||
debugModuleNames: [],
|
||||
debugNameMetadata: "uninterpretable",
|
||||
});
|
||||
});
|
||||
it("frames custom section names at their NUL-terminated objdump display", async () => {
|
||||
const text = await golden();
|
||||
|
||||
+32
-18
@@ -2,7 +2,7 @@ import { parseWabtInterface } from "./WabtInterface.js";
|
||||
import { watString, watStringEnd } from "./WabtString.js";
|
||||
|
||||
/** Read only module-name metadata from WABT's preserved name-section payload. */
|
||||
const moduleNames = (bytes: Uint8Array): string[] => {
|
||||
const moduleNames = (bytes: Uint8Array): string[] | null => {
|
||||
const names: string[] = [];
|
||||
let offset = 0;
|
||||
const uint32 = (end: number): number => {
|
||||
@@ -16,23 +16,27 @@ const moduleNames = (bytes: Uint8Array): string[] => {
|
||||
}
|
||||
throw new Error("Incomplete WABT name-section metadata.");
|
||||
};
|
||||
while (offset < bytes.length) {
|
||||
const type = uint32(bytes.length);
|
||||
const size = uint32(bytes.length);
|
||||
const end = offset + size;
|
||||
if (end > bytes.length)
|
||||
throw new Error("Incomplete WABT name-section metadata.");
|
||||
if (type === 0 && size !== 0) {
|
||||
const length = uint32(end);
|
||||
if (offset + length !== end)
|
||||
throw new Error("Incomplete WABT module-name metadata.");
|
||||
names.push(
|
||||
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
||||
bytes.subarray(offset, end),
|
||||
),
|
||||
);
|
||||
try {
|
||||
while (offset < bytes.length) {
|
||||
const type = uint32(bytes.length);
|
||||
const size = uint32(bytes.length);
|
||||
const end = offset + size;
|
||||
if (end > bytes.length)
|
||||
throw new Error("Incomplete WABT name-section metadata.");
|
||||
if (type === 0 && size !== 0) {
|
||||
const length = uint32(end);
|
||||
if (offset + length !== end)
|
||||
throw new Error("Incomplete WABT module-name metadata.");
|
||||
names.push(
|
||||
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
||||
bytes.subarray(offset, end),
|
||||
),
|
||||
);
|
||||
}
|
||||
offset = end;
|
||||
}
|
||||
offset = end;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return names;
|
||||
};
|
||||
@@ -46,6 +50,8 @@ export const parseWabtWat = (text: string) => {
|
||||
const exports: string[] = [];
|
||||
const customSectionNames: string[] = [];
|
||||
const debugModuleNames: string[] = [];
|
||||
let debugNameMetadata: "not-present" | "complete" | "uninterpretable" =
|
||||
"not-present";
|
||||
let depth = 0;
|
||||
let start = 0;
|
||||
let commentDepth = 0;
|
||||
@@ -126,7 +132,14 @@ export const parseWabtWat = (text: string) => {
|
||||
form,
|
||||
nameString.end + payloadPrefix[0].length,
|
||||
);
|
||||
debugModuleNames.push(...moduleNames(payload.bytes));
|
||||
const names = moduleNames(payload.bytes);
|
||||
if (names === null) {
|
||||
debugNameMetadata = "uninterpretable";
|
||||
debugModuleNames.length = 0;
|
||||
} else if (debugNameMetadata !== "uninterpretable") {
|
||||
debugNameMetadata = "complete";
|
||||
debugModuleNames.push(...names);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,6 +155,7 @@ export const parseWabtWat = (text: string) => {
|
||||
exports,
|
||||
customSectionNames,
|
||||
debugModuleNames,
|
||||
debugNameMetadata,
|
||||
interface: parseWabtInterface(forms),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
||||
cliTest(
|
||||
"compares portable Evidence identically through CLI and retained MCP with schema/provenance",
|
||||
async ({ cli }) => {
|
||||
const sources = (["i32", "i64"] as const).map((parameter) => {
|
||||
const sources = (["i32", "i64"] as const).map((parameter, index) => {
|
||||
const report = wasmArtifactFixture();
|
||||
report.interface = {
|
||||
state: "complete",
|
||||
@@ -33,6 +33,18 @@ cliTest(
|
||||
},
|
||||
],
|
||||
};
|
||||
// The left source predates optional-metadata coverage fields and the
|
||||
// tolerant custom-section profile. Portable Evidence remains readable.
|
||||
const {
|
||||
debug_name_metadata: _debugNames,
|
||||
custom_section_warnings: _warnings,
|
||||
...legacyReport
|
||||
} = report;
|
||||
if (index === 0)
|
||||
for (const command of legacyReport.tool_profile.commands)
|
||||
command.arguments = command.arguments.filter(
|
||||
(argument) => argument !== "--ignore-custom-section-errors",
|
||||
);
|
||||
return createEvidence(
|
||||
{
|
||||
path: report.artifact.path,
|
||||
@@ -43,7 +55,7 @@ cliTest(
|
||||
{
|
||||
operation: "inspect_wasm_artifact",
|
||||
parameters: { path: report.artifact.path },
|
||||
result: report,
|
||||
result: index === 0 ? legacyReport : report,
|
||||
confidence: "observed",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -60,6 +60,10 @@ const assertFirstSummaryDelivery = async (
|
||||
code_units: value.wat.text.length,
|
||||
});
|
||||
expect(summary.summary.wat).not.toHaveProperty("text");
|
||||
expect(summary.summary).toMatchObject({
|
||||
debug_name_metadata: value.debug_name_metadata,
|
||||
custom_section_warnings: value.custom_section_warnings,
|
||||
});
|
||||
const retained = harness.session.evidenceById(summary.parent_evidence_id);
|
||||
if (retained === undefined) throw new Error("Summary lost original Evidence");
|
||||
expect(retained.normalized_result).toEqual(value);
|
||||
@@ -424,6 +428,13 @@ it("reads an oversized completed WASM result through its reported retained refer
|
||||
...wasmArtifactFixture(),
|
||||
imports: ['(import "env" "memory.with punctuation" (memory 1))'],
|
||||
exports: ['(export "first" (func 0))', '(export "second" (func 1))'],
|
||||
debug_name_metadata: "uninterpretable" as const,
|
||||
custom_section_warnings: [
|
||||
{
|
||||
tool: "wasm-validate" as const,
|
||||
text: "0000011: warning: invalid sub-section size: extends past end\n",
|
||||
},
|
||||
],
|
||||
wat: {
|
||||
text,
|
||||
sha256: createHash("sha256").update(text, "utf8").digest("hex"),
|
||||
|
||||
Vendored
+2
-1
@@ -2,7 +2,8 @@
|
||||
|
||||
`module.wat` is source-owned. WABT 1.0.42 `wat2wasm module.wat -o module.wasm`
|
||||
produced the binary used for `wasm-objdump -h -x module.wasm` (`objdump.txt`) and
|
||||
`wasm2wat --enable-all module.wasm` (`decoded.wat`). No binary is checked in.
|
||||
`wasm2wat --enable-all --ignore-custom-section-errors module.wasm`
|
||||
(`decoded.wat`). No binary is checked in.
|
||||
The module has an imported function, exported memory/function and a `test`
|
||||
custom section. The custom payload is retained as an `@custom` annotation in decoded WAT.
|
||||
|
||||
|
||||
Vendored
+3
-1
@@ -11,6 +11,8 @@ export const wasmArtifactFixture = (
|
||||
sections: [],
|
||||
imports: [],
|
||||
exports: [],
|
||||
debug_name_metadata: "not-present",
|
||||
custom_section_warnings: [],
|
||||
headers: "",
|
||||
details: "",
|
||||
wat: {
|
||||
@@ -31,7 +33,7 @@ export const wasmArtifactFixture = (
|
||||
arguments:
|
||||
tool === "wasm-objdump"
|
||||
? ["-h", "-x", "module.wasm"]
|
||||
: ["--enable-all", "module.wasm"],
|
||||
: ["--enable-all", "--ignore-custom-section-errors", "module.wasm"],
|
||||
}),
|
||||
),
|
||||
timeout_ms: 30_000,
|
||||
|
||||
Reference in New Issue
Block a user