Skip to content

feat(anchors): validate stellar.toml schema version before use - #832

Open
woahwhattheheck wants to merge 2 commits into
Stellar-split:mainfrom
woahwhattheheck:feat/779-toml-version-validation
Open

feat(anchors): validate stellar.toml schema version before use#832
woahwhattheheck wants to merge 2 commits into
Stellar-split:mainfrom
woahwhattheheck:feat/779-toml-version-validation

Conversation

@woahwhattheheck

Copy link
Copy Markdown

Closes #779.

StellarTomlParser parsed stellar.toml without ever reading VERSION. A
document written against a future SEP-1 schema — where a field has moved or
changed type — parses "successfully" and yields plausible but wrong data, with
nothing to signal it. The parser now gates on the declared version, as the
first validation after a successful parse.

Changes

src/anchors/StellarTomlParser.ts:

  • SUPPORTED_TOML_VERSIONS — exported, ["2.0", "2.1"].
  • UnsupportedTomlVersionError — carries version (exactly as it appeared),
    domain, and supportedVersions.
  • The check runs immediately after toml.parse succeeds, before the metadata
    object is assembled or cached.

Version comparison

Versions are compared as major.minor, because the same version is written
several ways in the wild:

In the document Parsed as Normalised
VERSION = "2.0" string 2.0
VERSION = "2.0.0" string 2.0
VERSION = "2" string 2.0
VERSION = 2.0 number 2 2.0

The unquoted form matters: TOML reads 2.0 as a float, so a strict string
comparison would reject a perfectly ordinary document.

A malformed minor is not rounded down — "2.x" is rejected rather than
being read as "2.0", so a typo can't quietly select the wrong schema.

A document with no VERSION is still accepted

SEP-1 does not require the field and many published stellar.toml files omit
it, so treating absence as a failure would reject valid anchors. Only a
declared-and-unsupported version fails.

Rejected documents are not cached

The throw happens before the cache write, so a rejected domain leaves no entry
behind and a later corrected document is fetched normally rather than being
masked by a poisoned cache. There's a test for this.

Validation

  • npx vitest run test/stellarTomlParser.version.test.ts — 13/13 passing.
    Covers the supported forms above, absent VERSION, older (1.9) and future
    (3.0) versions, malformed 2.x, the error's fields and message, and the
    cache behaviour. Network-free: fetch is stubbed.
  • npx tsc --noEmit reports 210 errors on this branch and 210 on unmodified
    main
    — identical, with none in src/anchors/StellarTomlParser.ts.
    That baseline is pre-existing and unrelated to this change.

A future SEP-1 schema may move or re-type fields; parsing it with the current
logic yields plausible but wrong data instead of an error. The parser now
checks VERSION first, immediately after a successful parse, and throws
UnsupportedTomlVersionError naming the version it found.

A document declaring no VERSION is still accepted: SEP-1 does not require the
field and many published files omit it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate TOML schema version compatibility in StellarTomlParser

1 participant