| 133 | } |
| 134 | |
| 135 | static SC::Result scHttpDecodeComponent(SC::StringSpan input, SC::Span<char> storage, SC::StringSpan& output, |
| 136 | bool plusAsSpace) |
| 137 | { |
| 138 | output = {}; |
| 139 | const char* data = input.bytesWithoutTerminator(); |
| 140 | const size_t size = input.sizeInBytes(); |
| 141 | size_t write = 0; |
| 142 | for (size_t read = 0; read < size; ++read) |
| 143 | { |
| 144 | char decoded = data[read]; |
| 145 | if (decoded == '%') |
| 146 | { |
| 147 | SC_TRY_MSG(read + 2 < size, "Malformed percent escape"); |
| 148 | const int high = scHttpHexValue(data[read + 1]); |
| 149 | const int low = scHttpHexValue(data[read + 2]); |
| 150 | SC_TRY_MSG(high >= 0 and low >= 0, "Malformed percent escape"); |
| 151 | decoded = static_cast<char>((high << 4) | low); |
| 152 | read += 2; |
| 153 | } |
| 154 | else if (plusAsSpace and decoded == '+') |
| 155 | { |
| 156 | decoded = ' '; |
| 157 | } |
| 158 | SC_TRY_MSG(write < storage.sizeInBytes(), "Decoded output buffer is too small"); |
| 159 | storage.data()[write++] = decoded; |
| 160 | } |
| 161 | output = {{storage.data(), write}, false, input.getEncoding()}; |
| 162 | return SC::Result(true); |
| 163 | } |
| 164 | |
| 165 | static bool scHttpUrlContainsInvalidWhitespace(SC::StringSpan value) |
| 166 | { |
no test coverage detected