mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-14 15:56:44 +03:00
Validate schemes (#2078)
This commit is contained in:
@@ -289,6 +289,9 @@ func (u *URI) parse(host, uri []byte, isTLS bool) error {
|
||||
|
||||
if len(host) == 0 || bytes.Contains(uri, strColonSlashSlash) {
|
||||
scheme, newHost, newURI := splitHostURI(host, uri)
|
||||
if len(scheme) > 0 && !isValidScheme(scheme) {
|
||||
return fmt.Errorf("invalid scheme %q", scheme)
|
||||
}
|
||||
u.SetSchemeBytes(scheme)
|
||||
host = newHost
|
||||
uri = newURI
|
||||
@@ -379,6 +382,28 @@ func validUserinfo(userinfo []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isValidScheme(scheme []byte) bool {
|
||||
if len(scheme) == 0 {
|
||||
return false
|
||||
}
|
||||
first := scheme[0]
|
||||
if (first < 'a' || first > 'z') && (first < 'A' || first > 'Z') {
|
||||
return false
|
||||
}
|
||||
for i := 1; i < len(scheme); i++ {
|
||||
c := scheme[i]
|
||||
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') {
|
||||
continue
|
||||
}
|
||||
switch c {
|
||||
case '+', '-', '.':
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// parseHost parses host as an authority without user
|
||||
// information. That is, as host[:port].
|
||||
//
|
||||
|
||||
+14
@@ -131,6 +131,20 @@ func TestURIRejectInvalidIPv6(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestURIRejectInvalidScheme(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var u URI
|
||||
if err := u.Parse(nil, []byte("https>://vulndetector.com/path")); err == nil {
|
||||
t.Fatalf("expected invalid scheme error, got nil")
|
||||
}
|
||||
|
||||
var relative URI
|
||||
if err := relative.Parse(nil, []byte("/relative")); err != nil {
|
||||
t.Fatalf("unexpected error for relative path: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestURIUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user