#[non_exhaustive]pub enum ToolsetArgsError {
DangerousKey {
matched_key: &'static str,
},
NestingTooDeep {
depth: usize,
max_depth: usize,
},
TooManyNodes {
count_limit: usize,
},
}Expand description
All distinct reasons crate::validate_toolset_tool_args can reject a payload.
The set is #[non_exhaustive] — the validator may grow new check classes in
future versions and callers should match with a _ => fallback.
(Unlike crate::ToolsetFormatError, which is exhaustive by design, this type
intentionally carries the #[non_exhaustive] attribute.)
§Redaction guarantee
No variant Display output ever contains:
- The inbound argument key string (even the rejected one).
- Any byte from any argument value.
Error messages reference only compile-time &'static str constants from the
denylist, ensuring that a crafted payload carrying secret-shaped values cannot
leak through Display.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
DangerousKey
The argument payload contains a key that is in the JS-runtime-dangerous denylist at some depth (including within arrays).
The matched_key field holds the matched &'static str constant from
crate::ARGS_KEY_DENYLIST, NOT the input key string. This ensures the
error message never echoes attacker-controlled bytes.
§Why this class of key is dangerous
When the wallet’s JSON output is consumed by a downstream JavaScript agent runtime, certain property names have special semantics that can be exploited:
toJSON— custom serialisation hook; overridesJSON.stringify.then— presence makes an object “thenable”, hijackingawait/Promise.resolve.__proto__— prototype pollution viaObject.assignor spread.constructor/prototype— class-hierarchy tampering.toString/valueOf— coercion hooks invoked in string + number contexts.__defineGetter__/__defineSetter__/__lookupGetter__/__lookupSetter__—Object.prototypeaccessor-injection vectors.
These keys have NO legitimate use in any matrix-tool argument struct
(StellarPayArgs, StellarPayCommitArgs, StellarBalancesArgs, SEP
tool args). Their presence at any depth is unambiguously attacker-authored.
Fields
matched_key: &'static strThe matched &'static str constant from crate::ARGS_KEY_DENYLIST.
This is NOT the input key string — it is the constant from the denylist that the input key matched. The Display output is therefore attacker-controlled-bytes-free.
NestingTooDeep
The argument payload nesting depth exceeds crate::TOOLSET_ARGS_MAX_DEPTH.
Excessively-nested payloads are refused to prevent work-stack exhaustion
and to bound the cost of the iterative walk. The depth bound is set
substantially above the deepest legitimate matrix-tool arg shape
(see crate::TOOLSET_ARGS_MAX_DEPTH documentation for the sizing rationale).
depth is the exact depth of the first node that exceeded the bound
(the walk short-circuits at that node and never descends further).
Fields
TooManyNodes
The argument payload total node count exceeds crate::TOOLSET_ARGS_MAX_NODES.
Payloads with an excessive number of nodes (deep OR wide) are refused to bound the total work performed by the iterative walk.
§Why this bound is necessary
The depth bound (TOOLSET_ARGS_MAX_DEPTH) prevents stack-like traversal cost
but does not bound WIDTH: a flat object or array with N million elements
pushes N million references onto the work-stack in a single iteration. The
node-count cap closes this O(payload-width) unbounded case.
The MCP transport bounds message size via the frame-size limit, but the
CLI --args consumer does NOT have that guard. This cap ensures the walk
is bounded on both transports.
count_limit is the only field — no attacker-controlled value is echoed.
Trait Implementations§
Source§impl Debug for ToolsetArgsError
impl Debug for ToolsetArgsError
Source§impl Display for ToolsetArgsError
impl Display for ToolsetArgsError
Source§impl Error for ToolsetArgsError
impl Error for ToolsetArgsError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()