line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include |
2
|
|
|
|
|
|
|
#include |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
namespace panda { namespace uri { |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
#define FROM_HEX(ch) (std::isdigit(ch) ? ch - '0' : std::tolower(ch) - 'a' + 10) |
7
|
|
|
|
|
|
|
typedef unsigned char uchar; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
char URIComponent::scheme[256]; |
10
|
|
|
|
|
|
|
char URIComponent::user_info[256]; |
11
|
|
|
|
|
|
|
char URIComponent::host[256]; |
12
|
|
|
|
|
|
|
char URIComponent::path[256]; |
13
|
|
|
|
|
|
|
char URIComponent::path_segment[256]; |
14
|
|
|
|
|
|
|
char URIComponent::query[256]; |
15
|
|
|
|
|
|
|
char URIComponent::query_param[256]; |
16
|
|
|
|
|
|
|
char URIComponent::query_param_plus[256]; |
17
|
|
|
|
|
|
|
char URIComponent::fragment[256]; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
static char _restore[256]; |
20
|
|
|
|
|
|
|
static char _forward[256][2]; |
21
|
|
|
|
|
|
|
static char _backward[256][2]; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
static const int UNSAFE_DIGIT = 1; |
24
|
|
|
|
|
|
|
static const int UNSAFE_ALPHA = 2; |
25
|
|
|
|
|
|
|
static const int UNSAFE_SUBDELIMS = 4; |
26
|
|
|
|
|
|
|
static const int UNSAFE_GENDELIMS = 8; |
27
|
|
|
|
|
|
|
static const int UNSAFE_RESERVED = 16; |
28
|
|
|
|
|
|
|
static const int UNSAFE_UNRESERVED = 32; |
29
|
|
|
|
|
|
|
static const int UNSAFE_PCHAR = 64; |
30
|
|
|
|
|
|
|
|
31
|
585
|
|
|
|
|
|
static void unsafe_generate (char* unsafe, int flags, const char* chars = nullptr) { |
32
|
585
|
100
|
|
|
|
|
if (flags & UNSAFE_DIGIT) unsafe_generate(unsafe, 0, "0123456789"); |
33
|
585
|
100
|
|
|
|
|
if (flags & UNSAFE_ALPHA) unsafe_generate(unsafe, 0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
34
|
585
|
100
|
|
|
|
|
if (flags & UNSAFE_SUBDELIMS) unsafe_generate(unsafe, 0, "!$&'()*+,;="); |
35
|
585
|
50
|
|
|
|
|
if (flags & UNSAFE_GENDELIMS) unsafe_generate(unsafe, 0, ":/?#[]@"); |
36
|
585
|
50
|
|
|
|
|
if (flags & UNSAFE_RESERVED) unsafe_generate(unsafe, UNSAFE_SUBDELIMS | UNSAFE_GENDELIMS); |
37
|
585
|
100
|
|
|
|
|
if (flags & UNSAFE_UNRESERVED) unsafe_generate(unsafe, UNSAFE_ALPHA | UNSAFE_DIGIT, "-._~"); |
38
|
585
|
100
|
|
|
|
|
if (flags & UNSAFE_PCHAR) unsafe_generate(unsafe, UNSAFE_UNRESERVED | UNSAFE_SUBDELIMS, ":@"); |
39
|
9334
|
100
|
|
|
|
|
if (chars) while (char c = *chars++) unsafe[(unsigned char) c] = c; |
|
|
100
|
|
|
|
|
|
40
|
585
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
13
|
|
|
|
|
|
static int init () { |
43
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::scheme, UNSAFE_ALPHA|UNSAFE_DIGIT, "+-."); |
44
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::user_info, UNSAFE_UNRESERVED | UNSAFE_SUBDELIMS, ":"); |
45
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::host, UNSAFE_UNRESERVED | UNSAFE_SUBDELIMS); |
46
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::path, UNSAFE_PCHAR, "/"); |
47
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::path_segment, UNSAFE_PCHAR); |
48
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::query, UNSAFE_PCHAR, "/?"); |
49
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::query_param, UNSAFE_UNRESERVED); |
50
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::fragment, UNSAFE_PCHAR, "/?"); |
51
|
|
|
|
|
|
|
|
52
|
13
|
|
|
|
|
|
unsafe_generate(URIComponent::query_param_plus, UNSAFE_UNRESERVED); |
53
|
13
|
|
|
|
|
|
URIComponent::query_param_plus[(unsigned char)' '] = '+'; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
static char hex[] = "0123456789ABCDEF"; |
56
|
13
|
|
|
|
|
|
char c = CHAR_MIN; |
57
|
3328
|
100
|
|
|
|
|
do { |
58
|
3328
|
|
|
|
|
|
uchar uc = (uchar)c; |
59
|
3328
|
|
|
|
|
|
_restore[uc] = c; |
60
|
3328
|
|
|
|
|
|
_forward[uc][0] = hex[(c >> 4) & 15]; |
61
|
3328
|
|
|
|
|
|
_forward[uc][1] = hex[(c & 15) & 15]; |
62
|
3328
|
100
|
|
|
|
|
_backward[uc][0] = FROM_HEX(c) << 4; |
63
|
3328
|
100
|
|
|
|
|
_backward[uc][1] = FROM_HEX(c); |
64
|
3328
|
|
|
|
|
|
} while (c++ != CHAR_MAX); |
65
|
|
|
|
|
|
|
|
66
|
13
|
|
|
|
|
|
_restore[(uchar)'%'] = 0; |
67
|
13
|
|
|
|
|
|
_restore[(uchar)'+'] = ' '; |
68
|
|
|
|
|
|
|
|
69
|
13
|
|
|
|
|
|
return 0; |
70
|
|
|
|
|
|
|
} |
71
|
13
|
|
|
|
|
|
static int __init = init(); |
72
|
|
|
|
|
|
|
|
73
|
301
|
|
|
|
|
|
size_t encode_uri_component (const string_view src, char* dest, const char* unsafe) { |
74
|
301
|
|
|
|
|
|
const char* str = src.data(); |
75
|
301
|
|
|
|
|
|
const char*const end = str + src.length(); |
76
|
301
|
|
|
|
|
|
char* buf = dest; |
77
|
|
|
|
|
|
|
|
78
|
1913
|
100
|
|
|
|
|
while (str != end) { |
79
|
1612
|
|
|
|
|
|
uchar uc = *str++; |
80
|
1612
|
100
|
|
|
|
|
if (unsafe[uc] != 0) *buf++ = unsafe[uc]; |
81
|
|
|
|
|
|
|
else { |
82
|
36
|
|
|
|
|
|
*buf++ = '%'; |
83
|
36
|
|
|
|
|
|
*buf++ = _forward[uc][0]; |
84
|
36
|
|
|
|
|
|
*buf++ = _forward[uc][1]; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
301
|
|
|
|
|
|
return buf - dest; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
15
|
|
|
|
|
|
size_t decode_uri_component (const string_view src, char* dest) { |
92
|
15
|
|
|
|
|
|
const char* str = src.data(); |
93
|
15
|
|
|
|
|
|
const char*const end = str + src.length(); |
94
|
15
|
|
|
|
|
|
char* buf = dest; |
95
|
|
|
|
|
|
|
|
96
|
131
|
100
|
|
|
|
|
while (str != end) { |
97
|
116
|
|
|
|
|
|
char res = _restore[(uchar)*str++]; |
98
|
116
|
100
|
|
|
|
|
if (res != 0) *buf++ = res; |
99
|
34
|
50
|
|
|
|
|
else if (str < end-1) { |
100
|
34
|
|
|
|
|
|
*buf++ = _backward[(uchar)str[0]][0] | _backward[(uchar)str[1]][1]; |
101
|
34
|
|
|
|
|
|
str += 2; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
15
|
|
|
|
|
|
return buf - dest; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
52
|
50
|
|
|
|
|
}} |
|
|
50
|
|
|
|
|
|