File Coverage

src/panda/uri/encode.cc
Criterion Covered Total %
statement 57 57 100.0
branch 33 38 86.8
condition n/a
subroutine n/a
pod n/a
total 90 95 94.7


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