#include <optional>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "condition/base.hpp"
#include "configuration/common/parser_exception.hpp"
#include "configuration/common/raw_configuration.hpp"
#include "configuration/common/transformer_parser.hpp"
#include "transformer/base.hpp"
namespace ddwaf {
std::optional<transformer_id> transformer_from_string(std::string_view str)
{
static const std::unordered_map<std::string_view, transformer_id> transformer_mapping{
{"lowercase", transformer_id::lowercase},
{"remove_nulls", transformer_id::remove_nulls},
{"compress_whitespace", transformer_id::compress_whitespace},
{"normalize_path", transformer_id::normalize_path},
{"normalize_path_win", transformer_id::normalize_path_win},
{"url_decode", transformer_id::url_decode},
{"url_decode_iis", transformer_id::url_decode_iis},
{"css_decode", transformer_id::css_decode},
{"js_decode", transformer_id::js_decode},
{"html_entity_decode", transformer_id::html_entity_decode},
{"base64_decode", transformer_id::base64_decode},
{"base64url_decode", transformer_id::base64url_decode},
{"base64_encode", transformer_id::base64_encode},
{"shell_unescape", transformer_id::shell_unescape},
{"url_basename", transformer_id::url_basename},
{"url_path", transformer_id::url_path},
{"url_querystring", transformer_id::url_querystring},
{"remove_comments", transformer_id::remove_comments},
{"unicode_normalize", transformer_id::unicode_normalize},
{"removeNulls", transformer_id::remove_nulls},
{"compressWhiteSpace", transformer_id::compress_whitespace},
{"normalizePath", transformer_id::normalize_path},
{"normalizePathWin", transformer_id::normalize_path_win},
{"urlDecode", transformer_id::url_decode},
{"urlDecodeUni", transformer_id::url_decode_iis},
{"cssDecode", transformer_id::css_decode},
{"jsDecode", transformer_id::js_decode},
{"htmlEntityDecode", transformer_id::html_entity_decode},
{"base64Decode", transformer_id::base64_decode},
{"base64Encode", transformer_id::base64_encode},
{"cmdLine", transformer_id::shell_unescape},
{"_sqr_basename", transformer_id::url_basename},
{"_sqr_filename", transformer_id::url_path},
{"_sqr_querystring", transformer_id::url_querystring},
{"removeComments", transformer_id::remove_comments},
};
auto it = transformer_mapping.find(str);
if (it != transformer_mapping.end()) {
return {it->second};
}
return std::nullopt;
}
std::vector<transformer_id> parse_transformers(
const raw_configuration::vector &root, data_source &source)
{
if (root.empty()) {
return {};
}
std::vector<transformer_id> transformers;
transformers.reserve(root.size());
for (const auto &transformer_param : root) {
auto transformer = static_cast<std::string_view>(transformer_param);
auto id = transformer_from_string(transformer);
if (id.has_value()) {
transformers.emplace_back(id.value());
} else if (transformer == "keys_only") {
source = ddwaf::data_source::keys;
} else if (transformer == "values_only") {
source = ddwaf::data_source::values;
} else {
throw unknown_transformer(transformer);
}
}
return transformers;
}
}