Skip to content

Commit 9bdb482

Browse files
authored
Merge pull request #146 from flrdv/master
v0.17.3.1
2 parents f6db4a5 + 7e7056c commit 9bdb482

File tree

4 files changed

+30
-47
lines changed

4 files changed

+30
-47
lines changed

internal/protocol/http1/parser.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,6 @@ path:
152152
if len(data[i+1:]) >= 2 {
153153
// fast path
154154
c := (hexconv.Halfbyte[data[i+1]] << 4) | hexconv.Halfbyte[data[i+2]]
155-
if strutil.IsASCIINonprintable(c) {
156-
return true, nil, status.ErrBadRequest
157-
}
158155
if strutil.IsURLUnsafeChar(c) {
159156
data[i+1] |= 0x20
160157
data[i+2] |= 0x20
@@ -234,9 +231,6 @@ pathDecode2Char:
234231
}
235232

236233
char := (hexconv.Halfbyte[p.urlEncodedChar] << 4) | hexconv.Halfbyte[data[0]]
237-
if strutil.IsASCIINonprintable(char) {
238-
return true, nil, status.ErrBadRequest
239-
}
240234
if strutil.IsURLUnsafeChar(char) {
241235
if !requestLine.AppendBytes('%', p.urlEncodedChar|0x20, data[0]|0x20) {
242236
return true, nil, status.ErrURITooLong
@@ -350,9 +344,6 @@ paramsValue:
350344
if len(data[i+1:]) >= 2 {
351345
// fast path
352346
c := (hexconv.Halfbyte[data[i+1]] << 4) | hexconv.Halfbyte[data[i+2]]
353-
if strutil.IsASCIINonprintable(c) {
354-
return true, nil, status.ErrBadParams
355-
}
356347

357348
if !requestLine.AppendByte(c) {
358349
return true, nil, status.ErrTooLongRequestLine
@@ -412,9 +403,6 @@ paramsValueDecode2Char:
412403
}
413404

414405
char := (hexconv.Halfbyte[p.urlEncodedChar] << 4) | hexconv.Halfbyte[data[0]]
415-
if strutil.IsASCIINonprintable(char) {
416-
return true, nil, status.ErrBadParams
417-
}
418406

419407
if !requestLine.AppendByte(char) {
420408
return true, nil, status.ErrTooLongRequestLine

internal/protocol/http1/parser_test.go

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,19 @@ func TestParser(t *testing.T) {
334334
require.Equal(t, "/AAA", path)
335335
})
336336

337-
t.Run("path nonprintable", func(t *testing.T) {
338-
_, err := parsePath("/%41%07")
339-
require.EqualError(t, err, status.ErrBadRequest.Error())
337+
t.Run("path urlencoded unicode", func(t *testing.T) {
338+
t.Run("fastpath", func(t *testing.T) {
339+
parser, request := getParser(config.Default())
340+
_, _, err := parser.Parse([]byte("GET /%D0%9F%D0%B0%D0%B2%D0%BB%D0%BE "))
341+
require.NoError(t, err)
342+
require.Equal(t, "/%d0%9f%d0%b0%d0%b2%d0%bb%d0%be", request.Path)
343+
})
344+
345+
t.Run("slowpath", func(t *testing.T) {
346+
request, err := parseRequestLine("/%D0%9F%D0%B0%D0%B2%D0%BB%D0%BE")
347+
require.NoError(t, err)
348+
require.Equal(t, "/%d0%9f%d0%b0%d0%b2%d0%bb%d0%be", request.Path)
349+
})
340350
})
341351

342352
t.Run("unsafe", func(t *testing.T) {
@@ -395,14 +405,6 @@ func TestParser(t *testing.T) {
395405
require.Equal(t, "Slava Ukraini", params.Value("hello world"))
396406
})
397407

398-
t.Run("fastpath nonprintable", func(t *testing.T) {
399-
_, err := parseParams("hello%07=world")
400-
require.EqualError(t, err, status.ErrBadParams.Error())
401-
402-
_, err = parseParams("hello=wor%07ld")
403-
require.EqualError(t, err, status.ErrBadParams.Error())
404-
})
405-
406408
splitchars := func(str string) []string {
407409
byChars := make([]string, len(str))
408410
for i := range str {
@@ -420,12 +422,19 @@ func TestParser(t *testing.T) {
420422
require.Equal(t, "Heroyam Slava", params.Value("Slava Ukraini"))
421423
})
422424

423-
t.Run("slowpath nonprintable", func(t *testing.T) {
424-
_, err := parseParams(splitchars("h%07ey=hello")...)
425-
require.EqualError(t, err, status.ErrBadParams.Error())
425+
t.Run("allow unicode values", func(t *testing.T) {
426+
t.Run("fastpath", func(t *testing.T) {
427+
parser, request := getParser(config.Default())
428+
_, _, err := parser.Parse([]byte("GET /?n=Слава+Україні "))
429+
require.NoError(t, err)
430+
require.Equal(t, "Слава Україні", request.Params.Value("n"))
431+
})
426432

427-
_, err = parseParams(splitchars("hey=he%07llo")...)
428-
require.EqualError(t, err, status.ErrBadParams.Error())
433+
t.Run("slowpath", func(t *testing.T) {
434+
request, err := parseRequestLine("/?n=Слава+Україні")
435+
require.NoError(t, err)
436+
require.Equal(t, "Слава Україні", request.Params.Value("n"))
437+
})
429438
})
430439
})
431440
})
@@ -534,18 +543,13 @@ func TestParser(t *testing.T) {
534543
{
535544
Name: "encoded nonprintable",
536545
Sample: "/%ff",
537-
WantError: status.ErrBadRequest,
546+
WantError: nil,
538547
},
539548
{
540549
Name: "param key nonprintable",
541550
Sample: "/?he%07llo=world",
542551
WantError: status.ErrBadParams,
543552
},
544-
{
545-
Name: "param value nonprintable",
546-
Sample: "/?hello=wor%07ld",
547-
WantError: status.ErrBadParams,
548-
},
549553
{
550554
Name: "fragment",
551555
Sample: "/hello#Section1",

internal/strutil/url.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
// IsURLUnsafeChar tells whether it's safe to decode an urlencoded character.
1010
func IsURLUnsafeChar(c byte) bool {
11-
return c == '/'
11+
return c == '/' || IsASCIINonprintable(c)
1212
}
1313

1414
// URLDecode decodes an urlencoded string and tells whether the string was properly formed.
@@ -37,9 +37,6 @@ func URLDecode(str string) (string, bool) {
3737
}
3838

3939
char := (x << 4) | y
40-
if IsASCIINonprintable(char) {
41-
return "", false
42-
}
4340
if IsURLUnsafeChar(char) {
4441
b.Write([]byte{'%', c1 | 0x20, c2 | 0x20})
4542
continue

internal/strutil/url_test.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,9 @@ func TestURLDecode(t *testing.T) {
1919
}
2020
})
2121

22-
t.Run("unsafe char", func(t *testing.T) {
23-
res, ok := URLDecode("%61%2f")
22+
t.Run("unsafe char normalization", func(t *testing.T) {
23+
res, ok := URLDecode("%61%2f%D0")
2424
require.True(t, ok)
25-
require.Equal(t, "a%2f", res)
26-
})
27-
28-
t.Run("unsafe normalization", func(t *testing.T) {
29-
res, ok := URLDecode("%61%2F")
30-
require.True(t, ok)
31-
require.Equal(t, "a%2f", res)
25+
require.Equal(t, "a%2f%d0", res)
3226
})
3327
}

0 commit comments

Comments
 (0)