diff options
author | ZYunH <zyunhjob@163.com> | 2019-09-18 19:52:04 +0800 |
---|---|---|
committer | Erik Dubbelboer <erik@dubbelboer.com> | 2019-09-18 13:52:04 +0200 |
commit | ae421163c532f3088d2dce3bc169a04dd721e0db (patch) | |
tree | 36649cd0b06ccb472bc8c0c9bd4a7c4b7482c8b6 /bytesconv.go | |
parent | Added option to disable path normalization (#649) (diff) | |
download | fasthttp-ae421163c532f3088d2dce3bc169a04dd721e0db.tar.gz fasthttp-ae421163c532f3088d2dce3bc169a04dd721e0db.tar.bz2 fasthttp-ae421163c532f3088d2dce3bc169a04dd721e0db.zip |
Improve appendQuotedPath and AppendQuotedArg (#654)
* Update bytesconv.go
* Modify tests
* Remove unnecessary comments
* Update args_test.go
* Add test for appendQuotedPath
* Fix 11202 issue
* Fix some problems
Diffstat (limited to 'bytesconv.go')
-rw-r--r-- | bytesconv.go | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/bytesconv.go b/bytesconv.go index 7a98031..e0ca3ab 100644 --- a/bytesconv.go +++ b/bytesconv.go @@ -393,6 +393,58 @@ func s2b(s string) (b []byte) { return b } +var quotedArgShouldEscapeTable = func() [256]bool { + // According to RFC 3986 §2.3 + var a [256]bool + for i := 0; i < 256; i++ { + a[i] = true + } + + // ALPHA + for i := int('a'); i <= int('z'); i++ { + a[i] = false + } + for i := int('A'); i <= int('Z'); i++ { + a[i] = false + } + + // DIGIT + for i := int('0'); i <= int('9'); i++ { + a[i] = false + } + + // Unreserved characters + a[int('-')] = false + a[int('_')] = false + a[int('.')] = false + a[int('~')] = false + + return a +}() + +var quotedPathShouldEscapeTable = func() [256]bool { + // The implementation here equal to net/url shouldEscape(s, encodePath) + // + // The RFC allows : @ & = + $ but saves / ; , for assigning + // meaning to individual path segments. This package + // only manipulates the path as a whole, so we allow those + // last three as well. That leaves only ? to escape. + var a = quotedArgShouldEscapeTable + + // '$', '&', '+', ',', '/', ':', ';', '=', '@' + a[int('$')] = false + a[int('&')] = false + a[int('+')] = false + a[int(',')] = false + a[int('/')] = false + a[int(':')] = false + a[int(';')] = false + a[int('=')] = false + a[int('@')] = false + + return a +}() + // AppendUnquotedArg appends url-decoded src to dst and returns appended dst. // // dst may point to src. In this case src will be overwritten. @@ -403,33 +455,29 @@ func AppendUnquotedArg(dst, src []byte) []byte { // AppendQuotedArg appends url-encoded src to dst and returns appended dst. func AppendQuotedArg(dst, src []byte) []byte { for _, c := range src { - // See http://www.w3.org/TR/html5/forms.html#form-submission-algorithm - if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || - c == '*' || c == '-' || c == '.' || c == '_' { - dst = append(dst, c) - } else { + switch { + case c == ' ': + dst = append(dst, '+') + case quotedArgShouldEscapeTable[int(c)]: dst = append(dst, '%', hexCharUpper(c>>4), hexCharUpper(c&15)) + default: + dst = append(dst, c) } } return dst } func appendQuotedPath(dst, src []byte) []byte { + // Fix issue in https://github.com/golang/go/issues/11202 + if len(src) == 1 && src[0] == '*' { + return append(dst, '*') + } + for _, c := range src { - // From the spec: http://tools.ietf.org/html/rfc3986#section-3.3 - // an path can contain zero or more of pchar that is defined as follows: - // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - // pct-encoded = "%" HEXDIG HEXDIG - // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - // / "*" / "+" / "," / ";" / "=" - if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || - c == '-' || c == '.' || c == '_' || c == '~' || c == '!' || c == '$' || - c == '&' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '+' || - c == ',' || c == ';' || c == '=' || c == ':' || c == '@' || c == '/' { - dst = append(dst, c) - } else { + if quotedPathShouldEscapeTable[int(c)] { dst = append(dst, '%', hexCharUpper(c>>4), hexCharUpper(c&15)) + } else { + dst = append(dst, c) } } return dst |