| 18 | #define URL_RESERVED URL_GEN_RESERVED URL_SUB_RESERVED /* only allowed delims */ |
| 19 | |
| 20 | static int append_normalized_escapes(struct strbuf *buf, |
| 21 | const char *from, |
| 22 | size_t from_len, |
| 23 | const char *esc_extra, |
| 24 | const char *esc_ok) |
| 25 | { |
| 26 | /* |
| 27 | * Append to strbuf 'buf' characters from string 'from' with length |
| 28 | * 'from_len' while unescaping characters that do not need to be escaped |
| 29 | * and escaping characters that do. The set of characters to escape |
| 30 | * (the complement of which is unescaped) starts out as the RFC 3986 |
| 31 | * unsafe characters (0x00-0x1F,0x7F-0xFF," <>\"#%{}|\\^`"). If |
| 32 | * 'esc_extra' is not NULL, those additional characters will also always |
| 33 | * be escaped. If 'esc_ok' is not NULL, those characters will be left |
| 34 | * escaped if found that way, but will not be unescaped otherwise (used |
| 35 | * for delimiters). If a %-escape sequence is encountered that is not |
| 36 | * followed by 2 hexadecimal digits, the sequence is invalid and |
| 37 | * false (0) will be returned. Otherwise true (1) will be returned for |
| 38 | * success. |
| 39 | * |
| 40 | * Note that all %-escape sequences will be normalized to UPPERCASE |
| 41 | * as indicated in RFC 3986. Unless included in esc_extra or esc_ok |
| 42 | * alphanumerics and "-._~" will always be unescaped as per RFC 3986. |
| 43 | */ |
| 44 | |
| 45 | while (from_len) { |
| 46 | int ch = *from++; |
| 47 | int was_esc = 0; |
| 48 | |
| 49 | from_len--; |
| 50 | if (ch == '%') { |
| 51 | if (from_len < 2) |
| 52 | return 0; |
| 53 | ch = hex2chr(from); |
| 54 | if (ch < 0) |
| 55 | return 0; |
| 56 | from += 2; |
| 57 | from_len -= 2; |
| 58 | was_esc = 1; |
| 59 | } |
| 60 | if ((unsigned char)ch <= 0x1F || (unsigned char)ch >= 0x7F || |
| 61 | strchr(URL_UNSAFE_CHARS, ch) || |
| 62 | (esc_extra && strchr(esc_extra, ch)) || |
| 63 | (was_esc && strchr(esc_ok, ch))) |
| 64 | strbuf_addf(buf, "%%%02X", (unsigned char)ch); |
| 65 | else |
| 66 | strbuf_addch(buf, ch); |
| 67 | } |
| 68 | |
| 69 | return 1; |
| 70 | } |
| 71 | |
| 72 | static const char *end_of_token(const char *s, int c, size_t n) |
| 73 | { |
no test coverage detected