diff --git a/src/operators/ip_match_f.h b/src/operators/ip_match_f.h index a250a93c..a3816ab3 100644 --- a/src/operators/ip_match_f.h +++ b/src/operators/ip_match_f.h @@ -29,7 +29,7 @@ class IpMatchF : public IpMatchFromFile { IpMatchF(std::string op, std::string param, bool negation) : IpMatchFromFile(op, param, negation) { } explicit IpMatchF(std::string param) - : IpMatchFromFile("IpMatchFromFile", param) { } + : IpMatchFromFile("IpMatchFromF", param) { } }; } // namespace operators diff --git a/src/operators/ip_match_from_file.h b/src/operators/ip_match_from_file.h index 59b9694e..98da7de0 100644 --- a/src/operators/ip_match_from_file.h +++ b/src/operators/ip_match_from_file.h @@ -29,6 +29,8 @@ class IpMatchFromFile : public IpMatch { : IpMatch(op, param, negation) { } IpMatchFromFile(std::string op, std::string param) : IpMatch(op, param) { } + IpMatchFromFile(std::string param) + : IpMatch("IpMatchFromFile", param) { } bool init(const std::string& file, std::string *error) override; }; diff --git a/src/operators/no_match.h b/src/operators/no_match.h index 6a6b5249..462e5bbf 100644 --- a/src/operators/no_match.h +++ b/src/operators/no_match.h @@ -31,6 +31,8 @@ class NoMatch : public Operator { /** @ingroup ModSecurity_Operator */ NoMatch(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } + NoMatch() + : Operator("NoMatch") { } bool evaluate(Transaction *transaction, const std::string &str) override; }; diff --git a/src/operators/operator.cc b/src/operators/operator.cc index 75cb973e..5d952067 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -21,6 +21,7 @@ #include "modsecurity/transaction.h" +#include "src/utils/string.h" #include "src/operators/begins_with.h" #include "src/operators/contains.h" #include "src/operators/contains_word.h" @@ -113,105 +114,67 @@ bool Operator::evaluate(Transaction *transaction, const std::string& a) { if (transaction) { transaction->debug(2, "Operator: " + this->m_op + \ " is not implemented or malfunctioning."); - } else { - std::cerr << "Operator: " + this->m_op + \ - " is not implemented or malfunctioning."; } #endif return true; } -Operator *Operator::instantiate(std::string op_string) { - // Sanity check. - if (op_string.size() <= 2) { - return NULL; - } +Operator *Operator::instantiate(std::string op, std::string param) { + std::string op_ = utils::string::tolower(op); - std::string op = op_string; - op = op.substr(1, op_string.size() - 2); - - // We assume no negation by default - bool negation = false; - // If there is a '!' in front substring and assign negation - if (op.at(0) == '!') { - op = op.substr(1, op.size() - 1); - negation = true; - } - - // Check to see if there is a parameter, if not param is an empty string - std::string param = ""; - if (op.find(" ") != std::string::npos) { - param = op; - param.erase(0, param.find(" ") + 1); - op.erase(op.find(" "), - op.length() - op.find(" ")); - } - - for (std::basic_string::iterator p = op.begin(); - p != op.end(); ++p) { - *p = tolower(*p); - } - std::string op_ = op; - if (op_.length() > 2) { - op_.erase(0, 1); - if (op_.back() == ' ') { - op_.pop_back(); - } - } - - IF_MATCH(beginswith) { return new BeginsWith(op, param, negation); } - IF_MATCH(contains) { return new Contains(op, param, negation); } - IF_MATCH(containsword) { return new ContainsWord(op, param, negation); } - IF_MATCH(detectsqli) { return new DetectSQLi(op, param, negation); } - IF_MATCH(detectxss) { return new DetectXSS(op, param, negation); } - IF_MATCH(endswith) { return new EndsWith(op, param, negation); } - IF_MATCH(eq) { return new Eq(op, param, negation); } - IF_MATCH(fuzzyhash) { return new FuzzyHash(op, param, negation); } - IF_MATCH(geolookup) { return new GeoLookup(op, param, negation); } - IF_MATCH(ge) { return new Ge(op, param, negation); } - IF_MATCH(gsblookup) { return new GsbLookup(op, param, negation); } - IF_MATCH(gt) { return new Gt(op, param, negation); } - IF_MATCH(inspectfile) { return new InspectFile(op, param, negation); } - IF_MATCH(ipmatchf) { return new IpMatchF(op, param, negation); } + IF_MATCH(beginswith) { return new BeginsWith(param); } + IF_MATCH(contains) { return new Contains(param); } + IF_MATCH(containsword) { return new ContainsWord(param); } + IF_MATCH(detectsqli) { return new DetectSQLi(); } + IF_MATCH(detectxss) { return new DetectXSS(); } + IF_MATCH(endswith) { return new EndsWith(param); } + IF_MATCH(eq) { return new Eq(param); } + IF_MATCH(fuzzyhash) { return new FuzzyHash(param); } + IF_MATCH(geolookup) { return new GeoLookup(param); } + IF_MATCH(ge) { return new Ge(param); } + IF_MATCH(gsblookup) { return new GsbLookup(param); } + IF_MATCH(gt) { return new Gt(param); } + IF_MATCH(inspectfile) { return new InspectFile(param); } + IF_MATCH(ipmatchf) { return new IpMatchF(param); } IF_MATCH(ipmatchfromfile) { - return new IpMatchFromFile(op, param, negation); + return new IpMatchFromFile(param); } - IF_MATCH(ipmatch) { return new IpMatch(op, param, negation); } - IF_MATCH(le) { return new Le(op, param, negation); } - IF_MATCH(lt) { return new Lt(op, param, negation); } - IF_MATCH(nomatch) { return new NoMatch(op, param, negation); } - IF_MATCH(pmf) { return new PmF(op, param, negation); } - IF_MATCH(pmfromfile) { return new PmFromFile(op, param, negation); } - IF_MATCH(pm) { return new Pm(op, param, negation); } - IF_MATCH(rbl) { return new Rbl(op, param, negation); } - IF_MATCH(rsub) { return new Rsub(op, param, negation); } - IF_MATCH(rx) { return new Rx(op, param, negation); } - IF_MATCH(streq) { return new StrEq(op, param, negation); } - IF_MATCH(strmatch) { return new StrMatch(op, param, negation); } + IF_MATCH(ipmatch) { return new IpMatch(param); } + IF_MATCH(le) { return new Le(param); } + IF_MATCH(lt) { return new Lt(param); } + IF_MATCH(nomatch) { return new NoMatch(); } + IF_MATCH(pmfromfile) { return new PmFromFile(param); } + IF_MATCH(pmf) { return new PmF(param); } + IF_MATCH(pm) { return new Pm(param); } + IF_MATCH(rbl) { return new Rbl(param); } + IF_MATCH(rsub) { return new Rsub(param); } + IF_MATCH(rx) { return new Rx(param); } + IF_MATCH(streq) { return new StrEq(param); } + IF_MATCH(strmatch) { return new StrMatch(param); } IF_MATCH(validatebyterange) { - return new ValidateByteRange(op, param, negation); + return new ValidateByteRange(param); } - IF_MATCH(validatedtd) { return new ValidateDTD(op, param, negation); } - IF_MATCH(validatehash) { return new ValidateHash(op, param, negation); } - IF_MATCH(validateschema) { return new ValidateSchema(op, param, negation); } + IF_MATCH(validatedtd) { return new ValidateDTD(param); } + IF_MATCH(validatehash) { return new ValidateHash(param); } + IF_MATCH(validateschema) { return new ValidateSchema(param); } IF_MATCH(validateurlencoding) { - return new ValidateUrlEncoding(op, param, negation); + return new ValidateUrlEncoding(); } IF_MATCH(validateutf8encoding) { - return new ValidateUtf8Encoding(op, param, negation); + return new ValidateUtf8Encoding(); } - IF_MATCH(verifycc) { return new VerifyCC(op, param, negation); } - IF_MATCH(verifycpf) { return new VerifyCPF(op, param, negation); } - IF_MATCH(verifyssn) { return new VerifySSN(op, param, negation); } - IF_MATCH(within) { return new Within(op, param, negation); } + IF_MATCH(verifycc) { return new VerifyCC(param); } + IF_MATCH(verifycpf) { return new VerifyCPF(param); } + IF_MATCH(verifyssn) { return new VerifySSN(param); } + IF_MATCH(within) { return new Within(param); } IF_MATCH(unconditionalmatch) { - return new UnconditionalMatch(op, param, negation); + return new UnconditionalMatch(); } - return new Operator(op, param, negation); + return new Operator(param); } } // namespace operators diff --git a/src/operators/operator.h b/src/operators/operator.h index 4507f4a2..b81fd0eb 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -53,7 +53,7 @@ class Operator { m_param() { } virtual ~Operator() { } - static Operator *instantiate(std::string opName); + static Operator *instantiate(std::string opName, std::string param); virtual bool init(const std::string &arg, std::string *error) { return true; diff --git a/src/operators/pm_f.h b/src/operators/pm_f.h index 17dc5c23..95f9213e 100644 --- a/src/operators/pm_f.h +++ b/src/operators/pm_f.h @@ -30,6 +30,8 @@ class PmF : public PmFromFile { /** @ingroup ModSecurity_Operator */ PmF(std::string op, std::string param, bool negation) : PmFromFile(op, param, negation) { } + explicit PmF(std::string param) + : PmFromFile("PmFromF", param) { } }; diff --git a/src/operators/pm_from_file.h b/src/operators/pm_from_file.h index 89643172..67e11869 100644 --- a/src/operators/pm_from_file.h +++ b/src/operators/pm_from_file.h @@ -30,6 +30,8 @@ class PmFromFile : public Pm { /** @ingroup ModSecurity_Operator */ PmFromFile(std::string op, std::string param, bool negation) : Pm(op, param, negation) { } + PmFromFile(std::string op, std::string param) + : Pm(op, param) { } explicit PmFromFile(std::string param) : Pm("PmFromFile", param) { } bool init(const std::string &file, std::string *error) override; diff --git a/test/common/modsecurity_test.cc b/test/common/modsecurity_test.cc index f8b56b27..28a48500 100644 --- a/test/common/modsecurity_test.cc +++ b/test/common/modsecurity_test.cc @@ -141,7 +141,10 @@ void ModSecurityTest::cmd_options(int argc, char **argv) { i++; m_automake_output = true; } - + if (argc > i && strcmp(argv[i], "countall") == 0) { + i++; + m_count_all = true; + } if (const char* env_p = std::getenv("AUTOMAKE_TESTS")) { m_automake_output = true; } diff --git a/test/common/modsecurity_test.h b/test/common/modsecurity_test.h index 258442ce..dffbb9a3 100644 --- a/test/common/modsecurity_test.h +++ b/test/common/modsecurity_test.h @@ -33,7 +33,8 @@ template class ModSecurityTest : public: ModSecurityTest() : m_test_number(0), - m_automake_output(false) { } + m_automake_output(false), + m_count_all(false) { } std::string header(); void cmd_options(int, char **); @@ -45,6 +46,7 @@ template class ModSecurityTest : bool verbose = false; bool color = false; int m_test_number; + bool m_count_all; bool m_automake_output; }; diff --git a/test/regression/regression.cc b/test/regression/regression.cc index 5771a0f0..fb91f839 100644 --- a/test/regression/regression.cc +++ b/test/regression/regression.cc @@ -397,13 +397,13 @@ int main(int argc, char **argv) { << std::endl; #else test.cmd_options(argc, argv); - if (!test.m_automake_output) { + if (!test.m_automake_output && !test.m_count_all) { std::cout << test.header(); } test.load_tests(); - if (!test.m_automake_output) { + if (!test.m_automake_output && !test.m_count_all) { std::cout << std::setw(4) << std::right << "# "; std::cout << std::setw(50) << std::left << "File Name"; std::cout << std::setw(70) << std::left << "Test Name"; @@ -423,6 +423,11 @@ int main(int argc, char **argv) { } keyList.sort(); + if (test.m_count_all) { + std::cout << std::to_string(keyList.size()) << std::endl; + exit(0); + } + ModSecurityTestResults res; for (std::string &a : keyList) { test_number++; diff --git a/test/test-suite.sh b/test/test-suite.sh index c80ba006..2b87daba 100755 --- a/test/test-suite.sh +++ b/test/test-suite.sh @@ -10,8 +10,14 @@ FILE=${@: -1} if [[ $FILE == *"test-cases/regression/"* ]] then - $VALGRIND $PARAM ./regression_tests ../$FILE - echo $VALGRIND $PARAM ./regression_tests ../$FILE + AMOUNT=$(./regression_tests countall ../$FILE) + for i in `seq 1 $AMOUNT`; do + $VALGRIND $PARAM ./regression_tests ../$FILE:$i + if [ $? -eq 139 ]; then + echo ":test-result: FAIL segfault: ../$FILE:$i" + fi + echo $VALGRIND $PARAM ./regression_tests ../$FILE:$i + done; else $VALGRIND $PARAM ./unit_tests ../$FILE fi diff --git a/test/unit/unit.cc b/test/unit/unit.cc index 9ae70cd1..70cbea2a 100644 --- a/test/unit/unit.cc +++ b/test/unit/unit.cc @@ -144,10 +144,9 @@ void perform_unit_test(ModSecurityTest *test, UnitTest *t, } if (t->type == "op") { - Operator *op = Operator::instantiate("\"@" + t->name + \ - " " + t->param + "\""); + Operator *op = Operator::instantiate(t->name, t->param); op->init(t->filename, &error); - int ret = op->evaluate(NULL, t->input); + int ret = op->evaluate(NULL, NULL, t->input, NULL); t->obtained = ret; if (ret != t->ret) { res->push_back(t);