diff --git a/header.go b/header.go index 8dab12acbe..9228c81604 100644 --- a/header.go +++ b/header.go @@ -2229,9 +2229,23 @@ func normalizeHeaderValue(ov, ob []byte, headerLength int) (nv, nb []byte, nhl i nv[write] = c write++ } + nv = nv[:write] copy(ob[write:], ob[write+shrunk:]) - nb = ob[write+2 : len(ob)-shrunk] + + // Check if we need to skip \r\n or just \n + skip := 0 + if ob[write] == '\r' { + if ob[write+1] == '\n' { + skip += 2 + } else { + skip++ + } + } else if ob[write] == '\n' { + skip++ + } + + nb = ob[write+skip : len(ob)-shrunk] nhl = headerLength - shrunk return } diff --git a/header_test.go b/header_test.go index cec008f5fa..7f84a6342e 100644 --- a/header_test.go +++ b/header_test.go @@ -3,6 +3,7 @@ package fasthttp import ( "bufio" "bytes" + "encoding/base64" "fmt" "io" "io/ioutil" @@ -55,6 +56,13 @@ func TestResponseHeaderMultiLineName(t *testing.T) { } } +func TestResponseHeaderMultiLinePaniced(t *testing.T) { + // Input generated by fuzz testing that caused the parser to panic. + s, _ := base64.StdEncoding.DecodeString("aAEAIDoKKDoKICA6CgkKCiA6CiA6CgkpCiA6CiA6CiA6Cig6CiAgOgoJCgogOgogOgoJKQogOgogOgogOgogOgogOgoJOg86CiA6CiA6Cig6CiAyCg==") + header := new(RequestHeader) + header.parse(s) //nolint:errcheck +} + func TestResponseHeaderEmptyValueFromHeader(t *testing.T) { t.Parallel()