David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame] | 1 | // Copyright 2021 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package http2 |
| 6 | |
| 7 | import "strings" |
| 8 | |
| 9 | // The HTTP protocols are defined in terms of ASCII, not Unicode. This file |
| 10 | // contains helper functions which may use Unicode-aware functions which would |
| 11 | // otherwise be unsafe and could introduce vulnerabilities if used improperly. |
| 12 | |
| 13 | // asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t |
| 14 | // are equal, ASCII-case-insensitively. |
| 15 | func asciiEqualFold(s, t string) bool { |
| 16 | if len(s) != len(t) { |
| 17 | return false |
| 18 | } |
| 19 | for i := 0; i < len(s); i++ { |
| 20 | if lower(s[i]) != lower(t[i]) { |
| 21 | return false |
| 22 | } |
| 23 | } |
| 24 | return true |
| 25 | } |
| 26 | |
| 27 | // lower returns the ASCII lowercase version of b. |
| 28 | func lower(b byte) byte { |
| 29 | if 'A' <= b && b <= 'Z' { |
| 30 | return b + ('a' - 'A') |
| 31 | } |
| 32 | return b |
| 33 | } |
| 34 | |
| 35 | // isASCIIPrint returns whether s is ASCII and printable according to |
| 36 | // https://tools.ietf.org/html/rfc20#section-4.2. |
| 37 | func isASCIIPrint(s string) bool { |
| 38 | for i := 0; i < len(s); i++ { |
| 39 | if s[i] < ' ' || s[i] > '~' { |
| 40 | return false |
| 41 | } |
| 42 | } |
| 43 | return true |
| 44 | } |
| 45 | |
| 46 | // asciiToLower returns the lowercase version of s if s is ASCII and printable, |
| 47 | // and whether or not it was. |
| 48 | func asciiToLower(s string) (lower string, ok bool) { |
| 49 | if !isASCIIPrint(s) { |
| 50 | return "", false |
| 51 | } |
| 52 | return strings.ToLower(s), true |
| 53 | } |