diff --git a/src/actions/transformations/remove_nulls.cc b/src/actions/transformations/remove_nulls.cc index 08c15aea..5dcc8212 100644 --- a/src/actions/transformations/remove_nulls.cc +++ b/src/actions/transformations/remove_nulls.cc @@ -15,6 +15,8 @@ #include "actions/transformations/remove_nulls.h" +#include + #include #include #include @@ -30,20 +32,31 @@ namespace ModSecurity { namespace actions { namespace transformations { -RemoveNulls::RemoveNulls(std::string action) - : Transformation(action) { - this->action_kind = 1; -} std::string RemoveNulls::evaluate(std::string value, Assay *assay) { - /** - * @todo Implement the transformation RemoveNulls - */ - assay->debug(4, "Transformation RemoveNulls is not implemented yet."); - return value; + int64_t i, j; + + char *input = reinterpret_cast(malloc(value.size() + * sizeof(char))); + memcpy(input, value.c_str(), value.size()); + + i = j = 0; + while (i < value.size()) { + if (input[i] != '\0') { + input[j] = input[i]; + j++; + } + i++; + } + + std::string ret(input, 0, j); + free(input); + + return ret; } + } // namespace transformations } // namespace actions } // namespace ModSecurity diff --git a/src/actions/transformations/remove_nulls.h b/src/actions/transformations/remove_nulls.h index ba8671e2..e4ae65b5 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -30,7 +30,9 @@ namespace transformations { class RemoveNulls : public Transformation { public: - explicit RemoveNulls(std::string action); + explicit RemoveNulls(std::string action) + : Transformation(action) { } + std::string evaluate(std::string exp, Assay *assay) override; }; diff --git a/src/actions/transformations/transformation.cc b/src/actions/transformations/transformation.cc index 3506c681..00cec3c6 100644 --- a/src/actions/transformations/transformation.cc +++ b/src/actions/transformations/transformation.cc @@ -94,7 +94,7 @@ Transformation* Transformation::instantiate(std::string a) { IF_MATCH(parity_zero_7bit) { return new ParityZero7bit(a); } IF_MATCH(remove_comments_char) { return new RemoveCommentsChar(a); } IF_MATCH(remove_comments) { return new RemoveComments(a); } - IF_MATCH(remove_nulls) { return new RemoveNulls(a); } + IF_MATCH(removeNulls) { return new RemoveNulls(a); } IF_MATCH(remove_whitespace) { return new RemoveWhitespace(a); } IF_MATCH(replace_comments) { return new ReplaceComments(a); } IF_MATCH(replace_nulls) { return new ReplaceNulls(a); } diff --git a/src/utils.cc b/src/utils.cc index eb5c5981..52f255e2 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -809,5 +809,20 @@ static unsigned char x2c(unsigned char *what) { } +std::string string_to_hex(const std::string& input) { + static const char* const lut = "0123456789ABCDEF"; + size_t len = input.length(); + + std::string output; + output.reserve(2 * len); + for (size_t i = 0; i < len; ++i) { + const unsigned char c = input[i]; + output.push_back(lut[c >> 4]); + output.push_back(lut[c & 15]); + } + return output; +} + + } // namespace ModSecurity diff --git a/src/utils.h b/src/utils.h index 8684b87f..c975403f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -40,6 +40,7 @@ namespace ModSecurity { int html_entities_decode_inplace(unsigned char *input, int input_len); int normalize_path_inplace(unsigned char *input, int input_len, int win, int *changed); + std::string string_to_hex(const std::string& input); } // namespace ModSecurity #define SRC_UTILS_H_ diff --git a/test/test-cases/secrules-language-tests b/test/test-cases/secrules-language-tests index e1671340..e56e51a9 160000 --- a/test/test-cases/secrules-language-tests +++ b/test/test-cases/secrules-language-tests @@ -1 +1 @@ -Subproject commit e1671340cf078af3c904fca2be3e2266c5cef8b2 +Subproject commit e56e51a9218909431328cd083b0e163a6ad7fab1 diff --git a/test/unit/unit_test.cc b/test/unit/unit_test.cc index 7775fc1b..b9bcd294 100644 --- a/test/unit/unit_test.cc +++ b/test/unit/unit_test.cc @@ -22,8 +22,38 @@ #include "common/colors.h" + namespace modsecurity_test { + +std::string string_to_hex(const std::string& input) { + static const char* const lut = "0123456789ABCDEF"; + size_t len = input.length(); + + std::string output; + output.reserve(2 * len); + for (size_t i = 0; i < len; ++i) { + const unsigned char c = input[i]; + output.push_back(lut[c >> 4]); + output.push_back(lut[c & 15]); + } + return output; +} + + +void replaceAll(std::string *s, const std::string &search, + const char replace) { + for (size_t pos = 0; ; pos += 0) { + pos = s->find(search, pos); + if (pos == std::string::npos) { + break; + } + s->erase(pos, search.length()); + s->insert(pos, &replace); + } +} + + std::string UnitTest::print() { std::stringstream i; @@ -63,6 +93,7 @@ UnitTest *UnitTest::from_yajl_node(yajl_val &node) { u->param = YAJL_GET_STRING(val); } else if (strcmp(key, "input") == 0) { u->input = YAJL_GET_STRING(val); + replaceAll(&(u->input), "\\0", '\0'); } else if (strcmp(key, "name") == 0) { u->name = YAJL_GET_STRING(val); } else if (strcmp(key, "type") == 0) {