| 2100 | } |
| 2101 | |
| 2102 | inline bool is_valid_path(const std::string &path) { |
| 2103 | size_t level = 0; |
| 2104 | size_t i = 0; |
| 2105 | |
| 2106 | // Skip slash |
| 2107 | while (i < path.size() && path[i] == '/') { |
| 2108 | i++; |
| 2109 | } |
| 2110 | |
| 2111 | while (i < path.size()) { |
| 2112 | // Read component |
| 2113 | auto beg = i; |
| 2114 | while (i < path.size() && path[i] != '/') { |
| 2115 | i++; |
| 2116 | } |
| 2117 | |
| 2118 | auto len = i - beg; |
| 2119 | assert(len > 0); |
| 2120 | |
| 2121 | if (!path.compare(beg, len, ".")) { |
| 2122 | ; |
| 2123 | } else if (!path.compare(beg, len, "..")) { |
| 2124 | if (level == 0) { return false; } |
| 2125 | level--; |
| 2126 | } else { |
| 2127 | level++; |
| 2128 | } |
| 2129 | |
| 2130 | // Skip slash |
| 2131 | while (i < path.size() && path[i] == '/') { |
| 2132 | i++; |
| 2133 | } |
| 2134 | } |
| 2135 | |
| 2136 | return true; |
| 2137 | } |
| 2138 | |
| 2139 | inline std::string encode_query_param(const std::string &value) { |
| 2140 | std::ostringstream escaped; |
no test coverage detected