Files
amethyst/quartz/src
Claude 509075abde fix(quartz): guard trusted-list member hints and drop member-scan allocations
Audit of the Trusted List family turned up one real bug, one indexing
inconsistency and two allocation problems.

Fabricated relay hints. RelayUrlNormalizer.normalizeOrNull("alice") returns
wss://alice/, so parsing index 2 of a member tag unconditionally turned any
non-url there -- a petname, a label, the empty-string padding's non-empty
cousins -- into a relay hint that then reached pubKeyHints()/eventHints() and
the hint indexer. Member tags now apply the same length + isRelayUrl gate PTag
uses on that slot. The trailing-field parsing that all four member types share
moves into MemberTagFields, which also removes the three copies of the score
parser.

AddressMemberTag.parseAsHint accepted any non-empty value, so a malformed `a`
tag produced an AddressHint keyed on a non-coordinate. It now requires the
value to look like a coordinate, matching ATag.parseAsHint.

memberValues() and memberCount() ran through members(), building one member
object per tag just to read a value or a length -- on lists that the spec
expects to carry thousands of entries. Both now read the tags directly via two
protected hooks each kind implements with its own isTag/parse-value pair, so
the objects are only built when a caller actually wants the hints and scores.
A test pins memberCount() == members().size, including over malformed tags,
since the two predicates have to stay in step.

Also aligns TrustedListContentMember.memberValue with the property form used
by TrustedListMemberTag, and emits list metadata ahead of the membership in
build() so a large list does not bury its own header tags.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011f6dt4Zo3g8TAayhCU4tTD
2026-08-20 21:48:30 +00:00
..