URLFormEncoder does not escape all reserved characters
Opened this issue · 3 comments
Describe the issue
URLFormEncoder should be encoding characters like $, but does not
Vapor version
4.92.5
Operating system and version
macOS 14.3
Swift version
5.9.0
Steps to reproduce
let form = ["hello": "world$"]
let encoder = try ContentConfiguration.global.requireEncoder(for: .urlEncodedForm)
var buffer = ByteBuffer()
var headers = HTTPHeaders()
try encoder.encode(form, to: &buffer, headers: &headers)
print(String(bytes: ByteBufferView(buffer), encoding: .utf8)!)
Outcome
This should print hello=world%24
. Instead, it prints hello=world$
.
Additional notes
According to Wikipedia, the reserved characters include $
and should be percent-escaped.
I believe that this CharacterSet is not excluding all the characters it should be.
Ok me and @gwynne did some diving into this and it's definitely a bug - I have no idea how it's been undiscovered this long. There doesn't appear to be a good actual RFC spec to refer to, but the best we've found is https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-set
The application/x-www-form-urlencoded percent-encode set contains all code points, except the ASCII alphanumeric,
U+002A
(*
),U+002D
(-
),U+002E
(.
), andU+005F
(_
).
Will schedule a fix for this asap