[protocol spec] Consensus rules about canonical encodings are misstated in the spec
In section 4.4 we have the abstract definition of a Spend description, and the following consensus rule:
Elements of a Spend description MUST be canonical encodings of the types given above.
This does not strictly make sense, because the elements are the abstract entities, not the encoded byte sequences. (Also, what encoding? No encodings are defined up to this point in the spec.)
The intended consensus rule is something like "Fields of an encoded Spend description, each encoded as specified in §7.3 Encoding of Spend Descriptions, MUST be canonical encodings of the types given above."
except that it would probably make more sense to move the rule to section 7.3 in that case.
Similarly for Output descriptions (sections 4.5 and 7.4).
This has no security impact; the implementation in zcashd is as intended.
There's a similar but subtly different problem with JoinSplit descriptions. The corresponding consensus rule in section 4.3 is:
Elements of a JoinSplit description MUST have the types given above (for example: 0 ≤ vpubold ≤ MAX_MONEY and 0 ≤ vpubnew ≤ MAX_MONEY).
which does not say what it means. Strictly speaking, saying that elements have their types is redundant because type errors either can't happen, or are mistakes in the spec. (Speaking of which, we should make interpretation rules like that more explicit.) What this sentence meant was something about the fields in an encoded JoinSplit description as specified in section 7.2.
This only affects the fields vpub_old, vpub_new, and zkproof because those are the only ones that could have invalid encodings.