A cancelled GDB startup whose process stop could not be confirmed retained a
capability error. The next cleanup retry then reported "This analysis is
unavailable for the current target" instead of the caller's cancellation.
Move Rizin's retention rule (the #5963 fix) into one shared
retainedDebuggerCleanupFailure in src/process/ownedDebuggerSession.ts and use
it from both session managers. The GDB command-cancel path now retains the
cancellation itself, so retry reports no longer depend on Set insertion order.
Fifteen domain schema files each declared z.string().min(1), eight of them
as boundedTextSchema although it bounds nothing. They now share
nonEmptyTextSchema from src/domain/textSchemas.ts; the one trimming copy in
reconstructionCoverage.ts is renamed trimmedTextSchema.
Three private UTF-8 prefix truncators (gdb recent MI records, rizin
diagnostics, environment replay) and src/process/boundedUtf8Text.ts are
replaced by utf8HeadExcerpt in src/domain/utf8HeadExcerpt.ts, which encodes
only the retained prefix and returns a slice of the source text.
The fake application now leaves a marker when its children never report
ready, and the tests' session requests throw on it, so capture releases the
children and the test fails at once instead of waiting for its deadline.
Refs #10366
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The readiness wait from the previous commit continued after its bound
even when a child had not installed its TERM trap, so a slow runner
would reintroduce the race silently. It now exits with an error after
five seconds, and the state line keeps its original escaping.
Refs #10366
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The parser's work budget was a fixed 64 Mi units, so a real 26 MB .NET 8
NativeAOT image (bflat 8.0.2) stopped frozen-string recovery at 4,433 of
6,685 strings and reported partial. Give each image a base budget plus 8
units per admitted source byte, bounded by the source-byte ceiling, and
record the scaling in the analysis profile (contract revision v11). With it,
that image completes with all 6,685 frozen strings using 71.6 M units.
Only the budget scaling of #4559 is taken: main already resolves the
base-type closure in linear time.
Fixes#4445
Supersedes #4559
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
RFC 6891 makes a second OPT record a format error. Reading every OPT record
let a later one with extended RCODE 0 clear an earlier nonzero one, so an
error response could attribute its addresses.
Refs #10211
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A retroactive protocol conformance sets flag bit 0x40. The static
witness check admitted only the type-reference kind bits (0x38), so a
retroactive conformance lost its static witness table. The admitted
mask is now 0x78; conditional requirements, resilient witnesses and
generic witness tables stay unadmitted.
Fixes#7445
Only the mask change and its tests are taken from #7489.
Supersedes #7489
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
An XML plist whose DOCTYPE ends in an empty internal subset ("[]",
optionally with whitespace) declares nothing that could expand, but the
preflight refused it as internal entity expansion. Interface Builder
bundles then omitted the nib and blamed aggregate decode budget
exhaustion. Skip whitespace-only subsets; any declaration still refuses.
Fixes#8407
Supersedes #8438
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The nesting guard ran on a child visit of GgufHeader#value, so an empty
innermost array never produced one and a 33rd frame parsed as success
while the reported limit stayed maximum_array_frames: 32. Charge the
frame when entering the ARRAY branch instead, so the bound counts the
advertised unit and no longer depends on a scalar child that is not a
frame.
Fixes#7312
Supersedes #7698
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
inspect-native-exports treated any nonzero byte in .dynsym entry 0 as a
malformed table. That is right when the reserved slot holds a real symbol,
which was #7389, but some Android arm64 libraries set only st_name. Those
files were rejected before any export could be read.
Skip that entry, keep the inventory complete, and record the nonzero
st_name in limitations. Any other nonzero field still fails the table.
Fixes#9700
Supersedes #9752
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Charge the manifest split facts against the native inventory's retained JSON
allowance and refuse more than 64 split types or 256-character names as an
unknown, so a crafted manifest cannot overflow the response. Reports saved
before split facts existed still parse: the report schema treats absent
facts as optional while the live bridge contract requires them. The JADX
regression now decodes a generated binary manifest through
nativeDeclarations, with named and resource-ID-only attributes.
Refs #9756
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A base APK whose manifest requires ABI or density splits keeps its native
libraries in those splits, yet inspect_android_jni_bindings reported a
complete library inventory with zero libraries. The bridge's native
declaration inventory now also decodes the root binary manifest without a
session and reports its requiredSplitTypes and isSplitRequired facts, or why
they are unknown (bridge identity 11). When splits are required or unknown,
the library inventory is partial with an unknown that says so, and a binding
without a candidate is unknown instead of unmatched.
The binary manifest fixture from #9769 was used to check the bridge with the
real jadx-headless-mcp 0.7.1 JAR, including stripped attribute names that
resolve through framework resource IDs.
Fixes#9756
Co-Authored-By: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com>
Co-Authored-By: Phon <twilyt1@proton.me>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Setup's result is agent-only, so incur hides it when stdout is a terminal and
no format was chosen. Only an interactive setup or a fully interactive TTY dry
run rendered a summary, so `rea setup --yes` printed nothing. Render the dry
run plan or the existing result summary under incur's own hidden-output
condition instead.
Fixes#10531
Supersedes #2185
Co-Authored-By: balkan16 <57933796+balkan16@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
JSON.parse keeps only the last value for a repeated name, so an ASAR header
that declared a path twice listed one member, hid the other and still
reported complete coverage.
Add findDuplicateJsonMember, an iterative scan of validated JSON text that
does not recurse, so the deeply nested headers REA already admits stay
readable. readAsarHeader now refuses a repeated member name as a malformed
index, the same way the listing refuses unsafe path components.
trace_native_values ended at a provider-classified thunk whose model
holds only a synthetic return (an external import) or borrows its
target's operations, without saying the target was never examined, so
a stub's small model read as the end of the call chain. Thunk targets
are now reconciled after traversal: one another path traced, attempted
or queued is left to that path, and the rest are reported in unknowns
with the target in a new optional related_procedure field.
Fixes#8476
Supersedes #8678
Based on #8678 and rebased onto main's separate call-binding module.
related_procedure is exactOptional and set only on the thunk unknown,
so other unknowns and retained traces keep their shape.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
When the macOS process-ownership helper's swiftc compile hit
REA_SWIFTC_COMPILE_TIMEOUT_MS, inspect-macho and other native commands
reported a non-retryable provider failure, while process capture
already treated the same fact as retryable. The helper's error now owns
that interpretation (compilerTimedOut and compileTimeout, with its
deadline, message and recovery). Native commands return a retryable
AnalysisTimeoutError naming REA_SWIFTC_COMPILE_TIMEOUT_MS, and process
capture reads the same fact.
Fixes#8936
Supersedes #8938
Based on #8938; the interpretation moves to the error's owner so both
consumers share it.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A worker heap too small for REA's bridge stops the JVM before the protocol
handshake, so the launcher's retained stderr is the only evidence, and the
failure was reported as capability_unavailable with configuration advice.
When that stderr carries HotSpot's java.lang.OutOfMemoryError heap reasons,
report resource_constraint for memory with observed_max_heap_bytes null and
the same REA_JADX_HEAP_MIB remediation the bridge-reported heap failure uses,
now shared and stating -Xmx precedence. Other launcher stops are unchanged.
Refs #3517
Supersedes #3573
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
planOutputTree admits the destination before writeOutputTree creates any
parents, so the parent-creation defect fixed for environment bundles does not
reach desktop exports. Keep that sibling comparison as a test.
Refs #7688
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Desktop capture used XDG_* values without checking that they are
absolute, so a relative XDG_CONFIG_HOME (or data, state, cache) moved
state-directory, desktop-entry and build-secret lookups under the
working directory. The XDG Base Directory Specification says to ignore
a relative value; one xdgBase helper now applies that rule and falls
back to the home default.
Fixes#9702
Squashed from #9705 and rebased onto main. Setup's client registration
paths are left unchanged: each client's own handling of a relative
XDG_CONFIG_HOME has to be verified before REA writes elsewhere.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The witness seed accepted its folder with a readdir check that follows
symlinks, treats a missing path as usable, and reports a regular-file
parent as "not empty". The record is later saved through planOutputTree,
so a seed could accept a folder the save then refused. The seed now
admits the folder with planOutputTree too, and returns its refusal.
Fixes#9291
The MCP boundary test is from #9292 by viniciusdsandrade; its parallel
admission helper is not taken, since planOutputTree already owns the
rule and export already uses it.
Co-Authored-By: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
environment-build/export ran an unclassified recursive mkdir of the
destination's parent before SafeOutputTree validated anything. A
trailing `..` therefore created directories before it was refused, and
a regular file in the parent path surfaced as unreadable_output instead
of refusing the selection.
SafeOutputTree.create gains a createParents option that admits the
root's own syntax first, then creates the parents, mapping EEXIST and
ENOTDIR to a destination refusal. The environment bundle writer uses it
instead of its own mkdir.
Fixes#7688Fixes#7571
The non-directory mapping comes from #7734 by HeadmasterEggy, and the
syntax-first check from #7588 by harshitethic; their tests are kept.
Co-Authored-By: Avocado <headmastereggy@gmail.com>
Co-Authored-By: Harshit Sharma <66710144+harshitethic@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The block branch of the symbolic return flow already appended without a
call spread, but the adjacent if branch and both continuation-condition
joins still spread, so a generated wrapper with a wide tree of unknown
conditions could still overflow the argument limit.
Refs #10445
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
`target.push(...items)` passes every item as a call argument and
overflows the stack once a target-sized array grows past the engine's
argument limit. This class was fixed one site at a time in #10304,
#10343, #10362 and #8632. Add one shared appendAll helper in
src/domain and use it at the remaining sites whose arrays grow with the
input: XML member counting, app-task row suggestions, native call
routes and unresolved calls, call-path caveats, environment-manifest
merges, reference-source import entries, dyld trace edges and JS
symbolic flow values. The web bundle merge from the previous commit now
uses the shared helper too.
Bounded spreads (fixed literals, page-sized reads) are left as they are.
Refs #10445
Refs #10342
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Older Babel keeps a BigInt literal's source digits, which may carry a
0x/0o/0b prefix, so a hexadecimal zero read as truthy and a falsy socket host
such as 0x0n could drop a valid acquisition. Parse the value with BigInt.
Refs #10002
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The alias walk followed `var saved=s; var s=n(K)` to the later Electron load
although `saved` captured undefined. Each hop now checks, as the consumer
read already did, that the aliased binding's stable origin is available at
that read. The walk also shares one visited set instead of copying it at
every hop.
Refs #4490
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Static blocks and static field values run when a class is defined, so a
getter that returns a class whose static work writes through an alias of the
getter's receiver changes that receiver. The definition-time walk now visits
static work too; `this` inside it stays the class.
Refs #9229
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
net and tls connect through options.host || "localhost" and throw
ERR_INVALID_ARG_TYPE from the call when that is not a string, so a truthy
non-string host leaves no socket. Read the final host, path and TLS socket
members through one option reader shared with the TLS protocol-version
check, and drop the acquisition only when the host is statically truthy and
not a string while no truthy path or TLS socket, or an Object.prototype
write that may supply one, skips the host read.
The truthy and falsy host tests come from #9380. Its intrinsic-prototype
gating changes are not included.
Fixes#10002
Co-Authored-By: 吴佳浩 <wujiahao@supremind.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
General provenance only knew a literal require, so a bundled Electron
external held in one binding and destructured from another
(`const s=n(K);const{BrowserWindow}=s`) lost its windows and IPC. The
Electron binding origin now follows stable lexical aliases, and stops at
a rebindable binding that direct eval may have changed.
Fixes#4490
Supersedes #6993
Squashed from #6993 and rebased onto main. Rebase adaptation: the walk
uses the caller-selectable precision.alias_selections budget (the fixed
SEMANTIC_ALIAS_SELECTION_LIMIT it used was removed by #9706) and records
alias-selections when it stops there; a test pins that an over-budget
chain is not claimed and the limit is reported.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Defining a computed class or object member converts its key to a property
name, so preserve that coercion escape alongside the key expression walk.
Reuse javaScriptComputedDefinitionKey for computed-key ownership in the
getter result walker instead of repeating the check.
Refs #9229
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Computed keys and superclass expressions evaluate against the enclosing
getter receiver. Visit those definition-time expressions when collecting
accessor effects, and walk past class/method boundaries in #ownsThis when
the path arrives from heritage or a computed key so receiver writes are
not dropped.
Fixes#9229
Supersedes #9233
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
When recording a completed partial observation failed, delivery always
returned it as inline Evidence with retention "unknown" and dropped
the ledger's error, although the ledger already says whether the record
is retained (retained-evidence) or not (unretained-evidence) on a
capacity refusal. Delivery now uses that fact when the ledger names
this record, falls back to unknown only without one, and adds the
refusal as retention_error (without repeating the partial), the same
shape the MCP response-budget replacement already uses.
Refs #8425
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
decompile_all inline failure rows (failures and last_failures) carried
only address, code, message and name, so the provider's typed
pseudocode_absence reason stayed in the index only. Rows now include
pseudocode_absence. When the inline budget is short the name is dropped
first, then the reason, before the row; the index always keeps both.
Fixes#8731
The report and an earlier manifest-note approach are from #8735 by
wunianze666-netizen.
Co-Authored-By: wunianze666-netizen <wunianze666@gmail.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A successful batch_decompile item carried no item-level provenance:
only the batch Evidence aggregated limitations, so when a provider such
as Kuna answered repeated selectors from different sources, the caveat
did not say which occurrence it applied to. Successful items now keep
their own observation's limitations (exactOptional, so retained records
still parse), and the retained items view projects them.
The batch unavailable item also dropped the provider's typed
pseudocodeAbsence reason; it now carries pseudocode_absence.
Fixes#8350
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>