Aller au contenu
login
arrow_backRetour aux issues
WonderForgeLabs/gooey #351

markup: a namespaced attribute is silently accepted under its local name (xml:Style becomes Style)

ecoDébutant bug good first issue

descriptionDescription

**Latent today. Found while doing something else** (the body-whitespace work in #349) and deliberately not fixed there — nothing in the tree triggers it, and it wants its own change. ## The bug `markup/markup.go`'s `parse` collects attributes keyed by **local name only**, after handling namespace *declarations*: ```go for _, a := range t.Attr { if a.Name.Space == "xmlns" { ns[a.Name.Local] = a.Value continue } if a.Name.Space == "" && a.Name.Local == "xmlns" { continue // the default namespace is decorative versioning } e.Attrs[a.Name.Local] = a.Value // <-- the namespace is DISCARDED } ``` So a namespaced attribute arrives with its namespace thrown away, and `Attrs` cannot tell `foo:Style` from `Style`. ## Why it is a silent-acceptance bug and not just a curiosity The two cases behave oppositely, and only one of them is safe: - **`xml:lang="en"`** lands as `Attrs["lang"]`, hits the unknown-attribute check, and is rejected with `no such attribute lang`. That **fails closed — but only by accident**: it is rejected because `lang` happens not to be in the vocabulary, not because anything noticed a namespace. - **`xml:Style="x"` on a ``** lands as `Attrs["Style"]`, which **is** in the vocabulary. It is **silently accepted and applied as if the author had written `Style="x"`**. No error, no warning. Any prefix does this, not just `xml:` — `zz:Style="x"` behaves identically. The same collision would let a bare `space="preserve"` and a namespaced `xml:space="preserve"` become indistinguishable if anyone ever adds such an attribute, which is what made me look. This is the same defect class `markup/attrcheck.go` was written to delete. Its own doc comment: > Before this, an attribute nobody recognized was DROPPED IN SILENCE. […] The bare forms were accepted, ignored, and left the element sitting at the origin with nothing on screen, and nothing in any error, to say why. Here it is worse than dropped — it is *honoured under a name the author did not write*. ## Empirical finding about `encoding/xml` worth recording I verified this rather than assuming it, and it corrects a natural guess. For **`xml:space` with no `xmlns:xml` declaration**, Go reports the **full URI**, not the prefix: ``` attr space="http://www.w3.org/XML/1998/namespace" local="space" value="preserve" ``` An **undeclared** prefix is reported as the **raw prefix**: ``` zz:space="preserve" -> attr space="zz" local="space" ``` So `xml` is special-cased by the decoder and always resolves to the W3C URI, declared or not. Anyone writing the fix should discriminate on the **URI**, not on the string `"xml"`. Two further decoder facts from the same probe, in case they save someone a round trip: - `xmlns:xml="…"` arrives as `Space="xmlns" Local="xml"` and would land in the `ns` table like any other declaration. - `encoding/xml` normalises CR and CRLF to LF in character data, per the XML spec. ## Suggested shape (not prescriptive) Reject what cannot be meant, rather than flattening it. In `parse`, before the `Attrs` assignment: - an attribute in the **W3C XML namespace** that the loader does not understand → a load error naming it as `xml:`; - an attribute in **any other** non-empty namespace → a load error, since no element vocabulary is namespaced today. That keeps everything resolvable failing at **load time**, which is the markup contract, and leaves the door open for `xml:space` or genuine `xmlns:` handler attributes later — both would then be *added* deliberately rather than working by accident. ## Not urgent No `.gooey` file in the repo uses a prefixed attribute (checked all 65), and no Go-embedded markup does either. Nothing is broken right now; this is a trap armed for whoever first writes one. ## Reproducing — verified, not asserted Run against `markup` at `f687a4c`, building each through `markup.Build` with `accent` registered as a red style: ``` hi
codeOuvre sur GitHub