Repository navigation
reject overlong and surrogate UTF-8 in ippValidateAttribute - #180
michaelrsweet merged 2 commits into
Conversation
michaelrsweet
left a comment
There was a problem hiding this comment.
OK, if we are going down this rabbit hole we need the code to be a bit more readable... I suggest simply calculating the Unicode character and doing a range comparison. Aside from using long UTF-8 sequences and surrogates, we should also report an error if we see control characters from 0x80 to 0x9f, CR without LF (for text values), or a leading BOM - see RFC 5198 which is the governing standard for IPP name and text values.
Also, any validation error needs to reflect the issue and not just fall back on the generic "bad UTF-8 sequence" error message that we have now.
…ibute Move the name and text checks into ipp_validate_string, which decodes each UTF-8 sequence to a Unicode character and range-checks it. Reject overlong sequences, surrogates, characters above U+10FFFF, C1 controls, CR without LF in text values and a leading BOM, each with its own error message.
|
Reworked it. The name and text checks now go through a single
|
michaelrsweet
left a comment
There was a problem hiding this comment.
Needs a little cleanup but LGTM!
|
Thanks for merging, and for pointing me at RFC 5198. |
ippValidateAttributechecks name and text values for well-formed UTF-8 and rejects control characters, but its UTF-8 loops only look at the lead-byte class and the10xxxxxxshape of the continuation bytes. That lets through non-shortest forms (C0/C1leads,E0 80-9F,F0 80-8F), UTF-16 surrogates written as UTF-8 (ED A0-BF) and code points above U+10FFFF (F4 90+,F5-F7leads). Because the control-character test only sees single bytes, an overlong control character gets past it: ajob-nameof"a\xC0\x8Ab"(overlong LF) or"a\xE0\x80\x8Db"(overlong CR) validates, while"a\nb"is rejected. A server that vets client requests withippValidateAttributestherefore accepts names that a lenient UTF-8 decoder further down turns back into CR/LF, andcupsUTF8ToUTF32intranscode.calready rejects these same sequences as non-shortest, so the validator and libcups's own decoder disagree. The lead and second-byte checks in both loops now follow the RFC 3629 well-formed ranges, so valid input including U+D7FF, U+E000 and U+10FFFF is still accepted. Threetestippcases cover a valid multi-byte name, an overlong name and a surrogate in text; the last two fail without the fix.