Skip to content

No pre-decode validation seam for Rational -- setWire clamps hostile wire input instead of rejecting #131

Description

@Yaraslaut

Summary

No pre-decode validation seam exists for morph::math::RationalRational::setWire (the glaze wire-codec entry point) silently clamps hostile wire input to a plausible value instead of rejecting the decode. A wire payload like {"num":5,"den":0,"dp":2} decodes into a plausible 5/1 rather than failing, and every dispatch path decodes before any model-level validate() runs, so an application has no seam to catch a clamped value as clamped — it only ever sees an already-plausible Rational.

Evidence

include/morph/util/rational.hpp's codec: Rational::setWire rebuilds through the canonicalising constructor, which silently clamps den == 0 to 1 (among other clamps: out-of-range dp, INT64_MIN components whose negation would overflow) instead of asserting or rejecting.

Confirmed via a real test (examples/ledger/tests/test_ledger_model.cpp, rung 5 / ledger): decoding {"num":5,"den":0,"dp":2} through glz::read_json into a Rational succeeds silently, producing 5/1. A ledger-shaped application's own zero-sum business invariant happens to catch most clamped legs incidentally (a clamped value is unlikely to still sum to zero) — but that's coincidental protection from a business rule, not a validation guarantee the framework provides. An application with a less-convenient invariant (or none at all) would have no way to know the value it received was ever clamped.

Suggested direction

A pre-decode validation hook — reject rather than clamp by default, or at minimum a decode-time flag surfacing "this value was clamped" that a caller can check — would close the gap for any application whose own invariants don't happen to catch it incidentally.

Reference

Filed from LASTRADA-Software/morph, branch ladder-ledger-rung5 (not yet merged), as docs/findings/002-rational-no-predecode-validation-seam.md (see that file for the same summary in the ladder's own findings-pipeline format, examples/FINDINGS.md) and the "clamped Rational leg" test in examples/ledger/tests/test_ledger_model.cpp for the reproducing test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions