fix: reject an '@'-prefixed member name, and never reify an Attribute's type - #17
Merged
Conversation
…'s type
Two fixes for one bug. A Relationship carrying a sub-attribute named
"@referredType" (TS 104-175 § 5.2.2.3 gives a name a grammar starting at a
letter, so this is not a legal name) came back from a GET as
"@referredType": { "type": { "type": "Property", "value": "Property" },
"value": { "type": "Property", "value": "Organization" } }
which is not an Attribute representation at all.
ldKeywordCheck - registered with the new corJsonld callback - answers 400
BadRequestData for any '@'-prefixed member name that is not a JSON-LD keyword.
JSON-LD 1.1 drops such a member with a warning; silently dropping a member of
an Entity the client asked us to store is the worse of the two readings, since
the write then returns 201 with the data absent. Neither reading is written
down - spec-doubt #125. The rule is about name positions only: inside a value
(a Property's value, a JsonProperty's json, a LanguageProperty's languageMap,
where "@none" is the core context's own key) member names are opaque JSON.
hasExplicitAttrType now STAMPS the node it recognizes, exactly as addTypeField
stamps the one it creates. That is the real defect: the function decided "this
node is the Attribute's type" by name, while the sub-attribute recursion
decided "this node is a sub-attribute" by the KJF_ATTR_TERM bit - two oracles
for one node, and when they disagreed the Attribute's own type was wrapped
into a sub-Property. They disagreed whenever expansion had not visited the
subtree. Stamping at the point of recognition closes that off whatever route
the object took to get here, independently of the 400.
Verified separately: with the expander fix reverted, the stamp alone restores
"type": "Property" as a string.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo7DQD14mrErQD4N2v99d2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fixes for one bug — SEAMWARE/coraine#70. Depends on SEAMWARE/corJsonld#5; merge that first.
A Relationship carrying a sub-attribute named
@referredTypecame back from a GET aswhich is not an Attribute representation at all.
1. The 400 —
ldKeywordCheckRegistered with the new corJsonld callback. Any
@-prefixed member name that is not a JSON-LD keyword gets 400BadRequestData.JSON-LD 1.1 (Expansion Algorithm, step 13.1) drops such a member with a warning. Silently dropping a member of an Entity the client asked us to store is the worse of the two readings — the write returns 201 and the data is not there. TS 104-175 § 5.2.2.3 gives a name a grammar starting at a letter, so an
@-prefixed name is not a legal Attribute name either. Neither reading is written down: spec-doubt #125.Name positions only. Inside a value — a Property's
value, a JsonProperty'sjson, a LanguageProperty'slanguageMap, where@noneis the core context's own key for an unlabelled entry — member names are opaque JSON.2. The guard —
hasExplicitAttrTypestamps what it recognizesThis is the real defect, and it is worth fixing independently of the 400.
hasExplicitAttrType()decided "that node is the Attribute's type" by name. The sub-attribute recursion three lines below decided "that node is a sub-attribute" by theKJF_ATTR_TERMbit. Two oracles for one node — and when they disagreed, the Attribute's own type was wrapped into a sub-Property.They disagreed whenever expansion had not visited the subtree, since that is where the bit is set. Stamping at the point of recognition — exactly as
addTypeFieldstamps the node it creates — makes recognition and marking one act, and closes this off whatever route the object took to get here.No strcmp chain was re-introduced into the recursion: that list is what the
KJF_ATTR_TERMbit replaced, and it had already drifted once (it omittedvalueType). The stamp rides on the strcmphasExplicitAttrTypewas already doing.Verification
"type": "Property"as a plain string (valuestays reified — that half is what the 400 removes).🤖 Generated with Claude Code
https://claude.ai/code/session_01Mo7DQD14mrErQD4N2v99d2