Files
reverse-engineering-anything/src/native/pwntools/PwntoolsInputLimit.test.ts
T
The one -Niuandmorluto c44d17fd3c fix(pwntools): let callers widen the artifact input bound (#2486)
* fix(pwntools): let callers widen the artifact input bound

The pwntools adapters rejected every artifact over 32 MiB before any
analysis ran, and nothing in configuration, environment, CLI or MCP
could raise that bound, so real recorded core dumps stayed unanalyzable.

Resolve the bound from REA_PWNTOOLS_MAX_INPUT_BYTES in front of the
shipped default. An absent value keeps 32 MiB, and a value outside
1..1073741824 bytes is refused as unusable provider configuration before
the artifact is read instead of falling back silently.

* fix(pwntools): name the bound variable in its own refusal

An unusable REA_PWNTOOLS_MAX_INPUT_BYTES travelled through the shared
engine-absence helper, which always stamped configuration_key
REA_PWNTOOLS_PYTHON, so a caller following that field was pointed at the
Python executable instead of the bound it had just set. The guide also
described the refusal as an invalid request while the decoder reports
provider_unavailable.

Let the failure context carry the key under review and pass the bound's
own name at that call site, then state the code callers actually receive
in the guide. Assert the key on the projected rejection so the engine
default and the bound override each stay attributed to the right setting.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:18:12 +08:00

97 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { pwntoolsInputBytes } from "./PwntoolsInputLimit.js";
import { pwntoolsUnavailable } from "./PwntoolsFailures.js";
import {
PWNTOOLS_LIMITS,
PWNTOOLS_PROVIDER_IDENTITY,
} from "./PwntoolsRelease.js";
const CONSTRAINT =
"REA_PWNTOOLS_MAX_INPUT_BYTES must be a decimal integer from 1 to " +
"1073741824 bytes, and REA never installs Python or packages.";
describe("pwntools input bound", () => {
it("keeps the shipped default when the override is absent", () => {
expect(pwntoolsInputBytes({})).toEqual({
configured: true,
bytes: PWNTOOLS_LIMITS.inputBytes,
});
expect(PWNTOOLS_LIMITS.inputBytes).toBe(32 * 1024 * 1024);
});
it.each([
["1", 1],
["67108864", 64 * 1024 * 1024],
["172879872", 172_879_872],
["1073741824", 1024 * 1024 * 1024],
] as const)("accepts %s as %s bytes", (value, expected) => {
expect(pwntoolsInputBytes({ REA_PWNTOOLS_MAX_INPUT_BYTES: value })).toEqual(
{ configured: true, bytes: expected },
);
});
it.each([
"",
"0",
"-1",
"33554432.0",
"1e8",
" 67108864",
"67_108_864",
"0x2000000",
"1073741825",
"99999999999999999999",
"not-a-number",
])("rejects %s instead of widening the bound silently", (value) => {
expect(pwntoolsInputBytes({ REA_PWNTOOLS_MAX_INPUT_BYTES: value })).toEqual(
{
configured: false,
error: CONSTRAINT,
},
);
});
it("rejects a value above the ceiling that a float would round", () => {
const ceiling = pwntoolsInputBytes({
REA_PWNTOOLS_MAX_INPUT_BYTES: "1073741824",
});
const above = pwntoolsInputBytes({
REA_PWNTOOLS_MAX_INPUT_BYTES: "10737418241",
});
expect(ceiling.configured).toBe(true);
expect(above).toEqual({ configured: false, error: CONSTRAINT });
});
it("never narrows the bound below the shipped default implicitly", () => {
const accepted = [1, 1024, PWNTOOLS_LIMITS.inputBytes].map((bytes) =>
pwntoolsInputBytes({ REA_PWNTOOLS_MAX_INPUT_BYTES: String(bytes) }),
);
expect(accepted.every((limit) => limit.configured)).toBe(true);
});
});
describe("pwntools unavailability configuration key", () => {
const context = {
operation: "inspect_binary_layout",
providerId: PWNTOOLS_PROVIDER_IDENTITY.id,
};
const reportedKey = (configurationKey?: string) =>
pwntoolsUnavailable(
CONSTRAINT,
"/caller-selected/python",
undefined,
undefined,
configurationKey === undefined
? context
: { ...context, configurationKey },
).rejections[0]?.diagnostics["configuration_key"];
it("keeps the engine key unless the failure is about the bound", () => {
expect(reportedKey()).toBe("REA_PWNTOOLS_PYTHON");
expect(reportedKey("REA_PWNTOOLS_MAX_INPUT_BYTES")).toBe(
"REA_PWNTOOLS_MAX_INPUT_BYTES",
);
});
});