diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/net/url/url.go | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/src/net/url/url.go b/src/net/url/url.go index 71fd8f59b3..6d1d505343 100644 --- a/src/net/url/url.go +++ b/src/net/url/url.go @@ -56,17 +56,9 @@ func ishex(c byte) bool { return table[c]&hexChar != 0 } +// Precondition: ishex(c) is true. func unhex(c byte) byte { - switch { - case '0' <= c && c <= '9': - return c - '0' - case 'a' <= c && c <= 'f': - return c - 'a' + 10 - case 'A' <= c && c <= 'F': - return c - 'A' + 10 - default: - panic("invalid hex character") - } + return 9*(c>>6) + (c & 15) } type EscapeError string @@ -161,19 +153,24 @@ func unescape(s string, mode encoding) (string, error) { return s, nil } + var unescapedPlusSign byte + switch mode { + case encodeQueryComponent: + unescapedPlusSign = ' ' + default: + unescapedPlusSign = '+' + } var t strings.Builder t.Grow(len(s) - 2*n) for i := 0; i < len(s); i++ { switch s[i] { case '%': + // In the loop above, we established that unhex's precondition is + // fulfilled for both s[i+1] and s[i+2]. t.WriteByte(unhex(s[i+1])<<4 | unhex(s[i+2])) i += 2 case '+': - if mode == encodeQueryComponent { - t.WriteByte(' ') - } else { - t.WriteByte('+') - } + t.WriteByte(unescapedPlusSign) default: t.WriteByte(s[i]) } @@ -195,8 +192,7 @@ func PathEscape(s string) string { func escape(s string, mode encoding) string { spaceCount, hexCount := 0, 0 - for i := 0; i < len(s); i++ { - c := s[i] + for _, c := range []byte(s) { if shouldEscape(c, mode) { if c == ' ' && mode == encodeQueryComponent { spaceCount++ @@ -231,8 +227,8 @@ func escape(s string, mode encoding) string { } j := 0 - for i := 0; i < len(s); i++ { - switch c := s[i]; { + for _, c := range []byte(s) { + switch { case c == ' ' && mode == encodeQueryComponent: t[j] = '+' j++ @@ -242,7 +238,7 @@ func escape(s string, mode encoding) string { t[j+2] = upperhex[c&15] j += 3 default: - t[j] = s[i] + t[j] = c j++ } } |
