<commit_before>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * You may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address <EMAIL>.
 *
 */

#include <string.h>

#include <ctime>
#include <iostream>
#include <string>
#include <list>

#include "modsecurity/modsecurity.h"
#include "modsecurity/rules.h"

#include "common/modsecurity_test.h"
#include "common/colors.h"
#include "regression/regression_test.h"
#include "common/modsecurity_test_results.h"
#include "regression/custom_debug_log.h"
#include "utils/regex.h"

using modsecurity_test::CustomDebugLog;
using modsecurity_test::ModSecurityTest;
using modsecurity_test::ModSecurityTestResults;
using modsecurity_test::RegressionTest;
using modsecurity_test::RegressionTestResult;

using ModSecurity::Utils::regex_search;
using ModSecurity::Utils::SMatch;
using ModSecurity::Utils::Regex;

std::string default_test_path = "test-cases/regression";

void print_help() {
    std::cout << "Use ./regression-tests /path/to/file" << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;
}


void actions(ModSecurityTestResults<RegressionTest> *r,
    ModSecurity::Assay *a) {
    ModSecurity::ModSecurityIntervention it;
    memset(&it, '\0', sizeof(ModSecurity::ModSecurityIntervention));
    it.status = 200;
    if (a->intervention(&it) == true) {
        if (it.pause != 0) {
            // FIXME:
        }
        if (it.status != 0) {
            r->status = it.status;
        }
        if (it.url != NULL) {
            r->location = it.url;
        }
    }
}

void logCb(void *data, const char *msg) {
    std::stringstream *ss = (std::stringstream *) data;
    *ss << msg << std::endl;
}


void perform_unit_test(std::vector<RegressionTest *> *tests,
    ModSecurityTestResults<RegressionTestResult> *res, int *count) {


    for (RegressionTest *t : *tests) {
        CustomDebugLog *debug_log = new CustomDebugLog();
        ModSecurity::ModSecurity *modsec = NULL;
        ModSecurity::Rules *modsec_rules = NULL;
        ModSecurity::Assay *modsec_assay = NULL;
        ModSecurityTestResults<RegressionTest> r;
        std::stringstream serverLog;
        RegressionTestResult *testRes = new RegressionTestResult();
        testRes->test = t;
        r.status = 200;
        (*count)++;

        size_t offset = t->filename.find_last_of("/\\");
        std::string filename("");
        if (offset != std::string::npos) {
            filename = std::string(t->filename, offset + 1,
                t->filename.length() - offset - 1);
        } else {
            filename = t->filename;
        }
        std::cout << std::setw(3) << std::right <<
            std::to_string(*count) << " ";
        std::cout << std::setw(50) << std::left << filename;
        std::cout << std::setw(70) << std::left << t->name;

        modsec = new ModSecurity::ModSecurity();
        modsec->setConnectorInformation("ModSecurity-regression v0.0.1-alpha" \
            " (ModSecurity regression test utility)");
        modsec->setServerLogCb(logCb);
        modsec_rules = new ModSecurity::Rules(debug_log);

        if (modsec_rules->load(t->rules.c_str(), filename) < 0) {
            if (t->parser_error.empty() == true) {
                testRes->reason << KRED << "parse failed." << RESET \
                    << std::endl;
                testRes->reason << modsec_rules->getParserError() \
                    << std::endl;
                testRes->passed = false;
                return;
            }

            Regex re(t->parser_error);<commit_msg>Warn about parser error during the regression test<commit_after>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * You may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address <EMAIL>.
 *
 */

#include <string.h>

#include <ctime>
#include <iostream>
#include <string>
#include <list>

#include "modsecurity/modsecurity.h"
#include "modsecurity/rules.h"

#include "common/modsecurity_test.h"
#include "common/colors.h"
#include "regression/regression_test.h"
#include "common/modsecurity_test_results.h"
#include "regression/custom_debug_log.h"
#include "utils/regex.h"

using modsecurity_test::CustomDebugLog;
using modsecurity_test::ModSecurityTest;
using modsecurity_test::ModSecurityTestResults;
using modsecurity_test::RegressionTest;
using modsecurity_test::RegressionTestResult;

using ModSecurity::Utils::regex_search;
using ModSecurity::Utils::SMatch;
using ModSecurity::Utils::Regex;

std::string default_test_path = "test-cases/regression";

void print_help() {
    std::cout << "Use ./regression-tests /path/to/file" << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;
}


void actions(ModSecurityTestResults<RegressionTest> *r,
    ModSecurity::Assay *a) {
    ModSecurity::ModSecurityIntervention it;
    memset(&it, '\0', sizeof(ModSecurity::ModSecurityIntervention));
    it.status = 200;
    if (a->intervention(&it) == true) {
        if (it.pause != 0) {
            // FIXME:
        }
        if (it.status != 0) {
            r->status = it.status;
        }
        if (it.url != NULL) {
            r->location = it.url;
        }
    }
}

void logCb(void *data, const char *msg) {
    std::stringstream *ss = (std::stringstream *) data;
    *ss << msg << std::endl;
}


void perform_unit_test(std::vector<RegressionTest *> *tests,
    ModSecurityTestResults<RegressionTestResult> *res, int *count) {


    for (RegressionTest *t : *tests) {
        CustomDebugLog *debug_log = new CustomDebugLog();
        ModSecurity::ModSecurity *modsec = NULL;
        ModSecurity::Rules *modsec_rules = NULL;
        ModSecurity::Assay *modsec_assay = NULL;
        ModSecurityTestResults<RegressionTest> r;
        std::stringstream serverLog;
        RegressionTestResult *testRes = new RegressionTestResult();
        testRes->test = t;
        r.status = 200;
        (*count)++;

        size_t offset = t->filename.find_last_of("/\\");
        std::string filename("");
        if (offset != std::string::npos) {
            filename = std::string(t->filename, offset + 1,
                t->filename.length() - offset - 1);
        } else {
            filename = t->filename;
        }
        std::cout << std::setw(3) << std::right <<
            std::to_string(*count) << " ";
        std::cout << std::setw(50) << std::left << filename;
        std::cout << std::setw(70) << std::left << t->name;

        modsec = new ModSecurity::ModSecurity();
        modsec->setConnectorInformation("ModSecurity-regression v0.0.1-alpha" \
            " (ModSecurity regression test utility)");
        modsec->setServerLogCb(logCb);
        modsec_rules = new ModSecurity::Rules(debug_log);

        if (modsec_rules->load(t->rules.c_str(), filename) < 0) {
            if (t->parser_error.empty() == true) {
                testRes->reason << KRED << "parse failed." << RESET \
                    << std::endl;
                testRes->reason << modsec_rules->getParserError() \
                    << std::endl;
                testRes->passed = false;
                res->push_back(testRes);
                return;
            }

            Regex re(t->parser_error);
{'fraction_non_alphanumeric': 0.1415693245302184, 'fraction_numerical': 0.006602336211274758, 'mean_word_length': 2.8386939571150096, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4126202', 'n_tokens_mistral': 2447, 'n_tokens_neox': 2369, 'n_words': 531}