Skip to content

Commit

Permalink
Fix RequestHeader parser (valyala#1808)
Browse files Browse the repository at this point in the history
When FastHTTP receives a header value suffixed or prefixed with tabs, they should be stripped.
  • Loading branch information
ksw2000 authored and newacorn committed Jul 26, 2024
1 parent f61cdc3 commit 1872b07
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
21 changes: 17 additions & 4 deletions header.go
Original file line number Diff line number Diff line change
Expand Up @@ -3298,7 +3298,7 @@ func (s *headerScanner) next() bool {
s.key = s.b[:n]
normalizeHeaderKey(s.key, s.disableNormalizing)
n++
for len(s.b) > n && s.b[n] == ' ' {
for len(s.b) > n && (s.b[n] == ' ' || s.b[n] == '\t') {
n++
// the newline index is a relative index, and lines below trimmed `s.b` by `n`,
// so the relative newline index also shifted forward. it's safe to decrease
Expand Down Expand Up @@ -3352,13 +3352,18 @@ func (s *headerScanner) next() bool {
if n > 0 && s.value[n-1] == rChar {
n--
}
for n > 0 && s.value[n-1] == ' ' {
for n > 0 && (s.value[n-1] == ' ' || s.value[n-1] == '\t') {
n--
}
s.value = s.value[:n]
if isMultiLineValue {
s.value, s.b, s.hLen = normalizeHeaderValue(s.value, oldB, s.hLen)
}

for len(s.b) > 0 && (s.b[0] == ' ' || s.b[0] == '\t') {
s.b = s.b[1:]
}

return true
}

Expand Down Expand Up @@ -3437,6 +3442,7 @@ func normalizeHeaderValue(ov, ob []byte, headerLength int) (nv, nb []byte, nhl i
}
write := 0
shrunk := 0
once := false
lineStart := false
for read := 0; read < length; read++ {
c := ov[read]
Expand All @@ -3445,10 +3451,17 @@ func normalizeHeaderValue(ov, ob []byte, headerLength int) (nv, nb []byte, nhl i
shrunk++
if c == nChar {
lineStart = true
once = false
}
continue
case lineStart && c == '\t':
c = ' '
case lineStart && (c == '\t' || c == ' '):
if !once {
c = ' '
once = true
} else {
shrunk++
continue
}
default:
lineStart = false
}
Expand Down
5 changes: 5 additions & 0 deletions header_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ func TestResponseHeaderMultiLineValue(t *testing.T) {
"Foo: Bar\r\n" +
"Multi-Line: one;\r\n two\r\n" +
"Values: v1;\r\n v2; v3;\r\n v4;\tv5\r\n" +
// issue #1808
"WithTabs: \t v1 \t\r\n" +
"WithTabs-Start: \t \t v1 \r\n" +
"WithTabs-End: v1 \t \t\t\t\r\n" +
"WithTabs-Multi-Line: \t v1 \t;\r\n \t v2 \t;\r\n\t v3\r\n" +
"\r\n"
header := new(ResponseHeader)
if _, err := header.parse([]byte(s)); err != nil {
Expand Down

0 comments on commit 1872b07

Please sign in to comment.