mirror of
https://github.com/zap-proto/zip.git
synced 2026-10-19 15:38:57 +00:00
A URL carries a segment percent-encoded — it has to: a space, a slash, a percent or anything outside the unreserved set has no other spelling between two slashes. The router matched on the raw text and handed that same text on, so a handler addressed at /v1/secrets/café was given "caf%C3%A9" and looked up a name nobody has. Measured against a live listener before this: every path parameter carrying such a character arrived encoded, in the typed binder and in Ctx.Param alike. Every client encodes, because there is no other way to write those characters, so no client could make such a value round-trip and the address was unusable for anything but a bare identifier. Text that is not valid encoding is passed through rather than refused: a lone percent is a malformed URI, but the address it names is still the address the router matched, and failing here would turn a lookup that finds nothing into a 500. Found by running a generated HTTP client against a real service. Co-authored-by: Hanzo Dev <[email protected]>
25 lines
739 B
Go
25 lines
739 B
Go
package zip
|
|
|
|
import "testing"
|
|
|
|
// Text that is not valid encoding is passed through rather than refused. It
|
|
// cannot be sent through this package's own test client — net/url refuses to
|
|
// parse a lone percent — so the decision is pinned here, where the function is.
|
|
func TestSegmentPassesThroughWhatItCannotDecode(t *testing.T) {
|
|
for _, c := range []struct{ in, want string }{
|
|
{"plain", "plain"},
|
|
{"a%20b", "a b"},
|
|
{"a%2Fb", "a/b"},
|
|
{"caf%C3%A9", "café"},
|
|
{"100%25", "100%"},
|
|
{"100%", "100%"}, // a lone percent: malformed, passed through
|
|
{"%zz", "%zz"}, // not hex either
|
|
{"%", "%"},
|
|
{"", ""},
|
|
} {
|
|
if got := segment(c.in); got != c.want {
|
|
t.Errorf("segment(%q) = %q, want %q", c.in, got, c.want)
|
|
}
|
|
}
|
|
}
|