* Decode a %u-encoded character, using best-fit mapping as necessary. Path version. * * @param[in] cfg * @param[in] tx * @param[in] data * @return decoded byte */
| 1175 | * @return decoded byte |
| 1176 | */ |
| 1177 | static uint8_t decode_u_encoding_path(htp_cfg_t *cfg, htp_tx_t *tx, unsigned char *data) { |
| 1178 | uint8_t c1 = x2c(data); |
| 1179 | uint8_t c2 = x2c(data + 2); |
| 1180 | uint8_t r = cfg->decoder_cfgs[HTP_DECODER_URL_PATH].bestfit_replacement_byte; |
| 1181 | |
| 1182 | if (c1 == 0x00) { |
| 1183 | r = c2; |
| 1184 | tx->flags |= HTP_PATH_OVERLONG_U; |
| 1185 | } else { |
| 1186 | // Check for fullwidth form evasion |
| 1187 | if (c1 == 0xff) { |
| 1188 | tx->flags |= HTP_PATH_HALF_FULL_RANGE; |
| 1189 | } |
| 1190 | |
| 1191 | if (cfg->decoder_cfgs[HTP_DECODER_URL_PATH].u_encoding_unwanted != HTP_UNWANTED_IGNORE) { |
| 1192 | tx->response_status_expected_number = cfg->decoder_cfgs[HTP_DECODER_URL_PATH].u_encoding_unwanted; |
| 1193 | } |
| 1194 | |
| 1195 | // Use best-fit mapping |
| 1196 | unsigned char *p = cfg->decoder_cfgs[HTP_DECODER_URL_PATH].bestfit_map; |
| 1197 | |
| 1198 | // TODO Optimize lookup. |
| 1199 | |
| 1200 | for (;;) { |
| 1201 | // Have we reached the end of the map? |
| 1202 | if ((p[0] == 0) && (p[1] == 0)) { |
| 1203 | break; |
| 1204 | } |
| 1205 | |
| 1206 | // Have we found the mapping we're looking for? |
| 1207 | if ((p[0] == c1) && (p[1] == c2)) { |
| 1208 | r = p[2]; |
| 1209 | break; |
| 1210 | } |
| 1211 | |
| 1212 | // Move to the next triplet |
| 1213 | p += 3; |
| 1214 | } |
| 1215 | } |
| 1216 | |
| 1217 | // Check for encoded path separators |
| 1218 | if ((r == '/') || ((cfg->decoder_cfgs[HTP_DECODER_URL_PATH].backslash_convert_slashes) && (r == '\\'))) { |
| 1219 | tx->flags |= HTP_PATH_ENCODED_SEPARATOR; |
| 1220 | } |
| 1221 | |
| 1222 | return r; |
| 1223 | } |
| 1224 | |
| 1225 | /** |
| 1226 | * Decode a %u-encoded character, using best-fit mapping as necessary. Params version. |
no test coverage detected