Blame tests/msc_test.c

Packit Service 384592
/*
Packit Service 384592
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
Packit Service 384592
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
Packit Service 384592
*
Packit Service 384592
* You may not use this file except in compliance with
Packit Service 384592
* the License.  You may obtain a copy of the License at
Packit Service 384592
*
Packit Service 384592
*     http://www.apache.org/licenses/LICENSE-2.0
Packit Service 384592
*
Packit Service 384592
* If any of the files related to licensing are missing or if you have any
Packit Service 384592
* other questions related to licensing please contact Trustwave Holdings, Inc.
Packit Service 384592
* directly using the email address security@modsecurity.org.
Packit Service 384592
*/
Packit Service 384592
Packit Service 384592
#include <apr.h>
Packit Service 384592
#include <apr_getopt.h>
Packit Service 384592
Packit Service 384592
#include "modsecurity.h"
Packit Service 384592
#include "re.h"
Packit Service 384592
Packit Service 384592
#define ISHEX(X) (((X >= '0')&&(X <= '9')) || ((X >= 'a')&&(X <= 'f')) || ((X >= 'A')&&(X <= 'F')))
Packit Service 384592
Packit Service 384592
#define BUFLEN                   32768
Packit Service 384592
Packit Service 384592
#define RESULT_SUCCESS           0
Packit Service 384592
#define RESULT_ERROR            -1
Packit Service 384592
#define RESULT_MISMATCHED       -2
Packit Service 384592
#define RESULT_WRONGSIZE        -3
Packit Service 384592
#define RESULT_WRONGRET         -4
Packit Service 384592
Packit Service 384592
#define DEFAULT_ACTION           "phase:2,log,auditlog,pass"
Packit Service 384592
Packit Service 384592
#define CMDLINE_OPTS             "t:n:p:P:r:I:D:Nh"
Packit Service 384592
Packit Service 384592
/* Types */
Packit Service 384592
typedef struct tfn_data_t tfn_data_t;
Packit Service 384592
typedef struct op_data_t op_data_t;
Packit Service 384592
typedef struct action_data_t action_data_t;
Packit Service 384592
Packit Service 384592
struct tfn_data_t {
Packit Service 384592
    const char               *name;
Packit Service 384592
    const char               *param;
Packit Service 384592
    unsigned char            *input;
Packit Service 384592
    apr_size_t                input_len;
Packit Service 384592
    msre_tfn_metadata        *metadata;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
struct op_data_t {
Packit Service 384592
    const char               *name;
Packit Service 384592
    const char               *param;
Packit Service 384592
    unsigned char            *input;
Packit Service 384592
    apr_size_t                input_len;
Packit Service 384592
    msre_ruleset             *ruleset;
Packit Service 384592
    msre_rule                *rule;
Packit Service 384592
    msre_var                 *var;
Packit Service 384592
    msre_op_metadata         *metadata;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
struct action_data_t {
Packit Service 384592
    const char               *name;
Packit Service 384592
    unsigned char            *input;
Packit Service 384592
    apr_size_t                input_len;
Packit Service 384592
    msre_ruleset             *ruleset;
Packit Service 384592
    msre_rule                *rule;
Packit Service 384592
    msre_var                 *var;
Packit Service 384592
    msre_actionset           *actionset;
Packit Service 384592
    msre_action              *action;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
Packit Service 384592
/* Globals */
Packit Service 384592
static int debuglog_level = 0;
Packit Service 384592
static char *test_name = NULL;
Packit Service 384592
static apr_pool_t *g_mp = NULL;
Packit Service 384592
static modsec_rec *g_msr = NULL;
Packit Service 384592
static unsigned char buf[BUFLEN];
Packit Service 384592
msc_engine *modsecurity = NULL;
Packit Service 384592
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
Packit Service 384592
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
Packit Service 384592
char DSOLOCAL *real_server_signature = NULL;
Packit Service 384592
int DSOLOCAL remote_rules_fail_action = REMOTE_RULES_ABORT_ON_FAIL;
Packit Service 384592
char DSOLOCAL *remote_rules_fail_message = NULL;
Packit Service 384592
module AP_MODULE_DECLARE_DATA security2_module = {
Packit Service 384592
    NULL,
Packit Service 384592
    NULL,
Packit Service 384592
    NULL,
Packit Service 384592
    NULL,
Packit Service 384592
    NULL,
Packit Service 384592
    NULL,
Packit Service 384592
    NULL
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
/* Stubs */
Packit Service 384592
char *format_error_log_message(apr_pool_t *mp, error_message_t *em) {
Packit Service 384592
    return "FAKE ERROR LOG MESSAGE";
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
apr_status_t send_error_bucket(modsec_rec *msr, ap_filter_t *f, int status) {
Packit Service 384592
    return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
int apache2_exec(modsec_rec *msr, const char *command, const char **argv, char **output) {
Packit Service 384592
    return 0;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
char *get_apr_error(apr_pool_t *p, apr_status_t rc) {
Packit Service 384592
    char *text = apr_pcalloc(p, 201);
Packit Service 384592
    if (text == NULL) return NULL;
Packit Service 384592
    apr_strerror(rc, text, 200);
Packit Service 384592
    return text;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
void msr_log(modsec_rec *msr, int level, const char *text, ...) {
Packit Service 384592
    va_list ap;
Packit Service 384592
    char str1[1024] = "";
Packit Service 384592
    char str2[1256] = "";
Packit Service 384592
Packit Service 384592
    if ((msr == NULL) || (level > msr->txcfg->debuglog_level)) {
Packit Service 384592
        return;
Packit Service 384592
    }
Packit Service 384592
    if (msr->txcfg->debuglog_fd == NOT_SET_P) {
Packit Service 384592
        if (apr_file_open(&msr->txcfg->debuglog_fd, msr->txcfg->debuglog_name, APR_READ|APR_WRITE|APR_CREATE|APR_APPEND|APR_BINARY, APR_OS_DEFAULT, g_mp) != APR_SUCCESS) {
Packit Service 384592
            fprintf(stderr, "ERROR: failed to create unit test debug log \"%s\".\n", msr->txcfg->debuglog_name);
Packit Service 384592
            msr->txcfg->debuglog_fd = NULL;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    va_start(ap, text);
Packit Service 384592
    if (msr->txcfg->debuglog_fd != NULL) {
Packit Service 384592
        apr_size_t nbytes_written = 0;
Packit Service 384592
        apr_vsnprintf(str1, sizeof(str1), text, ap);
Packit Service 384592
        apr_snprintf(str2, sizeof(str2), "%lu: [%d] [%s] %s\n", (unsigned long)getpid(), level, test_name, str1);
Packit Service 384592
Packit Service 384592
        apr_file_write_full(msr->txcfg->debuglog_fd, str2, strlen(str2), &nbytes_written);
Packit Service 384592
    }
Packit Service 384592
    va_end(ap);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
void msr_log_error(modsec_rec *msr, const char *text, ...) {
Packit Service 384592
    va_list ap;
Packit Service 384592
    int level = 3;
Packit Service 384592
    char str1[1024] = "";
Packit Service 384592
    char str2[1256] = "";
Packit Service 384592
Packit Service 384592
    if ((msr == NULL) || (level > msr->txcfg->debuglog_level)) {
Packit Service 384592
        return;
Packit Service 384592
    }
Packit Service 384592
    if (msr->txcfg->debuglog_fd == NOT_SET_P) {
Packit Service 384592
        if (apr_file_open(&msr->txcfg->debuglog_fd, msr->txcfg->debuglog_name, APR_READ|APR_WRITE|APR_CREATE|APR_APPEND|APR_BINARY, APR_OS_DEFAULT, g_mp) != APR_SUCCESS) {
Packit Service 384592
            fprintf(stderr, "ERROR: failed to create unit test debug log \"%s\".\n", msr->txcfg->debuglog_name);
Packit Service 384592
            msr->txcfg->debuglog_fd = NULL;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    va_start(ap, text);
Packit Service 384592
    if (msr->txcfg->debuglog_fd != NULL) {
Packit Service 384592
        apr_size_t nbytes_written = 0;
Packit Service 384592
        apr_vsnprintf(str1, sizeof(str1), text, ap);
Packit Service 384592
        apr_snprintf(str2, sizeof(str2), "%lu: [%d] [%s] %s\n", (unsigned long)getpid(), level, test_name, str1);
Packit Service 384592
Packit Service 384592
        apr_file_write_full(msr->txcfg->debuglog_fd, str2, strlen(str2), &nbytes_written);
Packit Service 384592
    }
Packit Service 384592
    va_end(ap);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
void msr_log_warn(modsec_rec *msr, const char *text, ...) {
Packit Service 384592
    va_list ap;
Packit Service 384592
    int level = 4;
Packit Service 384592
    char str1[1024] = "";
Packit Service 384592
    char str2[1256] = "";
Packit Service 384592
Packit Service 384592
    if ((msr == NULL) || (level > msr->txcfg->debuglog_level)) {
Packit Service 384592
        return;
Packit Service 384592
    }
Packit Service 384592
    if (msr->txcfg->debuglog_fd == NOT_SET_P) {
Packit Service 384592
        if (apr_file_open(&msr->txcfg->debuglog_fd, msr->txcfg->debuglog_name, APR_READ|APR_WRITE|APR_CREATE|APR_APPEND|APR_BINARY, APR_OS_DEFAULT, g_mp) != APR_SUCCESS) {
Packit Service 384592
            fprintf(stderr, "ERROR: failed to create unit test debug log \"%s\".\n", msr->txcfg->debuglog_name);
Packit Service 384592
            msr->txcfg->debuglog_fd = NULL;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    va_start(ap, text);
Packit Service 384592
    if (msr->txcfg->debuglog_fd != NULL) {
Packit Service 384592
        apr_size_t nbytes_written = 0;
Packit Service 384592
        apr_vsnprintf(str1, sizeof(str1), text, ap);
Packit Service 384592
        apr_snprintf(str2, sizeof(str2), "%lu: [%d] [%s] %s\n", (unsigned long)getpid(), level, test_name, str1);
Packit Service 384592
Packit Service 384592
        apr_file_write_full(msr->txcfg->debuglog_fd, str2, strlen(str2), &nbytes_written);
Packit Service 384592
    }
Packit Service 384592
    va_end(ap);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
#define ap_get_remote_host(a, b, c, d) test_ap_get_remote_host(a, b, c, d)
Packit Service 384592
const char *test_ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip) {
Packit Service 384592
    return "FAKE-REMOTE-HOST";
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
char *get_env_var(request_rec *r, char *name) {
Packit Service 384592
    return "FAKE-ENV-VAR";
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
#define unixd_set_global_mutex_perms(a) my_unixd_set_global_mutex_perms(a)
Packit Service 384592
apr_status_t my_unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex) {
Packit Service 384592
    return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
#define unixd_set_proc_mutex_perms(a) my_unixd_set_proc_mutex_perms(a)
Packit Service 384592
apr_status_t my_unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex) {
Packit Service 384592
    return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
Packit Service 384592
/* Escaping functions */
Packit Service 384592
Packit Service 384592
static unsigned char hex2dec(unsigned char *what) {
Packit Service 384592
    register unsigned char digit;
Packit Service 384592
Packit Service 384592
    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
Packit Service 384592
    digit *= 16;
Packit Service 384592
    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
Packit Service 384592
Packit Service 384592
    return digit;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static unsigned char *unescape_inplace(unsigned char *str, apr_size_t *len)
Packit Service 384592
{
Packit Service 384592
    apr_size_t i, j;
Packit Service 384592
    for (i = j = 0; i < *len; j++) {
Packit Service 384592
        if ((str[i] == '\\') && (i + 3 < *len) && (str[i + 1] == 'x') && ISHEX(str[i + 2]) && ISHEX(str[i + 3]) ) {
Packit Service 384592
            str[j] = hex2dec(str + i + 2);
Packit Service 384592
            i += 4;
Packit Service 384592
        }
Packit Service 384592
        else {
Packit Service 384592
            str[j] = str[i++];
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
    *len = j;
Packit Service 384592
Packit Service 384592
    while (j < i) {
Packit Service 384592
        str[j++] = '\0';
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return str;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static char *escape(unsigned char *str, apr_size_t *len)
Packit Service 384592
{
Packit Service 384592
    char *new = apr_pcalloc(g_mp, (*len * 4) + 1);
Packit Service 384592
    apr_size_t i, j;
Packit Service 384592
    for (i = j = 0; i < *len; i++) {
Packit Service 384592
        if ((str[i] >= 0x20) && (str[i] <= 0x7e)) {
Packit Service 384592
            new[j++] = str[i];
Packit Service 384592
        }
Packit Service 384592
        else {
Packit Service 384592
            sprintf(new + j, "\\x%02x", str[i]);
Packit Service 384592
            j += 4;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
    *len = j;
Packit Service 384592
Packit Service 384592
    return new;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
Packit Service 384592
/* Testing functions */
Packit Service 384592
Packit Service 384592
static int init_tfn(tfn_data_t *data, const char *name, unsigned char *input, apr_size_t input_len, char **errmsg) {
Packit Service 384592
    *errmsg = NULL;
Packit Service 384592
Packit Service 384592
    data->name = name;
Packit Service 384592
    data->input = apr_pmemdup(g_mp, input, input_len);
Packit Service 384592
    data->input_len = input_len;
Packit Service 384592
    data->metadata = msre_engine_tfn_resolve(modsecurity->msre, name);
Packit Service 384592
    if (data->metadata == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to fetch tfn \"%s\".", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return 0;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static int test_tfn(tfn_data_t *data, unsigned char **rval, apr_size_t *rval_len, char **errmsg)
Packit Service 384592
{
Packit Service 384592
    int rc = -1;
Packit Service 384592
Packit Service 384592
    *errmsg = NULL;
Packit Service 384592
Packit Service 384592
    /* Execute the tfn */
Packit Service 384592
    rc = data->metadata->execute(g_mp, data->input, (long)(data->input_len), (char **)rval, (long *)rval_len);
Packit Service 384592
    if (rc < 0) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to execute tfn \"%s\".", data->name);
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return rc;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static int init_op(op_data_t *data, const char *name, const char *param, unsigned char *input, apr_size_t input_len, char **errmsg) {
Packit Service 384592
    const char *args = apr_psprintf(g_mp, "@%s %s", name, param);
Packit Service 384592
    char *conf_fn;
Packit Service 384592
    int rc = -1;
Packit Service 384592
Packit Service 384592
    *errmsg = NULL;
Packit Service 384592
Packit Service 384592
    data->name = name;
Packit Service 384592
    data->param = param;
Packit Service 384592
    data->input = input;
Packit Service 384592
    data->input_len = input_len;
Packit Service 384592
Packit Service 384592
    if ( apr_filepath_merge(&conf_fn, NULL, "unit-test.conf", APR_FILEPATH_TRUENAME, g_mp) != APR_SUCCESS) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to build a conf filename.");
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* Register UNIT_TEST variable */
Packit Service 384592
    msre_engine_variable_register(modsecurity->msre,
Packit Service 384592
        "UNIT_TEST",
Packit Service 384592
        VAR_SIMPLE,
Packit Service 384592
        0, 0,
Packit Service 384592
        NULL,
Packit Service 384592
        NULL,
Packit Service 384592
        VAR_DONT_CACHE,
Packit Service 384592
        PHASE_REQUEST_HEADERS
Packit Service 384592
    );
Packit Service 384592
Packit Service 384592
    /* Lookup the operator */
Packit Service 384592
    data->metadata = msre_engine_op_resolve(modsecurity->msre, name);
Packit Service 384592
    if (data->metadata == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to fetch op \"%s\".", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* Create a ruleset/rule */
Packit Service 384592
    data->ruleset = msre_ruleset_create(modsecurity->msre, g_mp);
Packit Service 384592
    if (data->ruleset == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to create ruleset for op \"%s\".", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
    data->rule = msre_rule_create(data->ruleset, RULE_TYPE_NORMAL, conf_fn, 1, "UNIT_TEST", args, DEFAULT_ACTION, errmsg);
Packit Service 384592
    if (data->rule == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to create rule for op \"%s\": %s", name, *errmsg);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* Create a fake variable */
Packit Service 384592
    data->var = (msre_var *)apr_pcalloc(g_mp, sizeof(msre_var));
Packit Service 384592
    data->var->name = "UNIT_TEST";
Packit Service 384592
    data->var->value = apr_pstrmemdup(g_mp, (char *)input, input_len);
Packit Service 384592
    data->var->value_len = input_len;
Packit Service 384592
    data->var->metadata = msre_resolve_var(modsecurity->msre, data->var->name);
Packit Service 384592
    if (data->var->metadata == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to resolve variable for op \"%s\": %s", name, data->var->name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* Initialize the operator parameter */
Packit Service 384592
    if (data->metadata->param_init != NULL) {
Packit Service 384592
        rc = data->metadata->param_init(data->rule, errmsg);
Packit Service 384592
        if (rc <= 0) {
Packit Service 384592
            *errmsg = apr_psprintf(g_mp, "Failed to init op \"%s\": %s", name, *errmsg);
Packit Service 384592
            return rc;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return 0;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static int test_op(op_data_t *data, char **errmsg)
Packit Service 384592
{
Packit Service 384592
    int rc = -1;
Packit Service 384592
Packit Service 384592
    *errmsg = NULL;
Packit Service 384592
Packit Service 384592
    /* Execute the operator */
Packit Service 384592
    if (data->metadata->execute != NULL) {
Packit Service 384592
        rc = data->metadata->execute(g_msr, data->rule, data->var, errmsg);
Packit Service 384592
        if (rc < 0) {
Packit Service 384592
            *errmsg = apr_psprintf(g_mp, "Failed to execute op \"%s\": %s", data->name, *errmsg);
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return rc;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static int init_action(action_data_t *data, const char *name, const char *param, char **errmsg)
Packit Service 384592
{
Packit Service 384592
    const char *action_string = NULL;
Packit Service 384592
    char *conf_fn;
Packit Service 384592
Packit Service 384592
    *errmsg = NULL;
Packit Service 384592
Packit Service 384592
    if ((param == NULL) || (strcmp("", param) == 0)) {
Packit Service 384592
        action_string = apr_psprintf(g_mp, "%s", name);
Packit Service 384592
    }
Packit Service 384592
    else {
Packit Service 384592
        action_string = apr_psprintf(g_mp, "%s:%s", name, param);
Packit Service 384592
    }
Packit Service 384592
    if (action_string == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to build action string for action: \"%s\".", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    if ( apr_filepath_merge(&conf_fn, NULL, "unit-test.conf", APR_FILEPATH_TRUENAME, g_mp) != APR_SUCCESS) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to build a conf filename.");
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* Register UNIT_TEST variable */
Packit Service 384592
    msre_engine_variable_register(modsecurity->msre,
Packit Service 384592
        "UNIT_TEST",
Packit Service 384592
        VAR_SIMPLE,
Packit Service 384592
        0, 0,
Packit Service 384592
        NULL,
Packit Service 384592
        NULL,
Packit Service 384592
        VAR_DONT_CACHE,
Packit Service 384592
        PHASE_REQUEST_HEADERS
Packit Service 384592
    );
Packit Service 384592
Packit Service 384592
    /* Create a ruleset/rule */
Packit Service 384592
    data->ruleset = msre_ruleset_create(modsecurity->msre, g_mp);
Packit Service 384592
    if (data->ruleset == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to create ruleset for action \"%s\".", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
    data->rule = msre_rule_create(data->ruleset, RULE_TYPE_NORMAL, conf_fn, 1, "UNIT_TEST", "@unconditionalMatch", action_string, errmsg);
Packit Service 384592
    if (data->rule == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to create rule for action \"%s\": %s", name, *errmsg);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* Get the actionset/action */
Packit Service 384592
    data->actionset = data->rule->actionset;
Packit Service 384592
    if (data->actionset == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to fetch actionset for action \"%s\"", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
    data->action = (msre_action *)apr_table_get(data->actionset->actions, name);
Packit Service 384592
    if (data->action == NULL) {
Packit Service 384592
        *errmsg = apr_psprintf(g_mp, "Failed to fetch action for action \"%s\"", name);
Packit Service 384592
        return -1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return 0;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
static int test_action(action_data_t *data, char **errmsg)
Packit Service 384592
{
Packit Service 384592
    int rc = -1;
Packit Service 384592
Packit Service 384592
    *errmsg = NULL;
Packit Service 384592
Packit Service 384592
    /* Execute the action */
Packit Service 384592
    if (data->action->metadata->execute != NULL) {
Packit Service 384592
        rc = data->action->metadata->execute(g_msr, g_mp, data->rule, data->action);
Packit Service 384592
        if (rc < 0) {
Packit Service 384592
            *errmsg = apr_psprintf(g_mp, "Failed to execute action \"%s\": %d", data->name, rc);
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return rc;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
Packit Service 384592
/* Initialization */
Packit Service 384592
static void init_msr(void)
Packit Service 384592
{
Packit Service 384592
    directory_config *dcfg = NULL;
Packit Service 384592
    request_rec *r = NULL;
Packit Service 384592
    r = (request_rec *)apr_pcalloc(g_mp, sizeof(request_rec));
Packit Service 384592
Packit Service 384592
    dcfg = (directory_config *)apr_pcalloc(g_mp, sizeof(directory_config));
Packit Service 384592
    dcfg->is_enabled = 0;
Packit Service 384592
    dcfg->reqbody_access = 0;
Packit Service 384592
    dcfg->reqbody_buffering = 0;
Packit Service 384592
    dcfg->reqbody_inmemory_limit = REQUEST_BODY_DEFAULT_INMEMORY_LIMIT;
Packit Service 384592
    dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
Packit Service 384592
    dcfg->reqbody_no_files_limit = REQUEST_BODY_NO_FILES_DEFAULT_LIMIT;
Packit Service 384592
    dcfg->resbody_access = 0;
Packit Service 384592
    dcfg->of_limit = RESPONSE_BODY_DEFAULT_LIMIT;
Packit Service 384592
    dcfg->of_limit_action = RESPONSE_BODY_LIMIT_ACTION_REJECT;
Packit Service 384592
    dcfg->debuglog_fd = NOT_SET_P;
Packit Service 384592
    dcfg->debuglog_name = "msc-test-debug.log";
Packit Service 384592
    dcfg->debuglog_level = debuglog_level;
Packit Service 384592
    dcfg->cookie_format = 0;
Packit Service 384592
    dcfg->argument_separator = '&';
Packit Service 384592
    dcfg->rule_inheritance = 0;
Packit Service 384592
    dcfg->auditlog_flag = 0;
Packit Service 384592
    dcfg->auditlog_type = AUDITLOG_SERIAL;
Packit Service 384592
    dcfg->auditlog_fd = NULL;
Packit Service 384592
    dcfg->auditlog2_fd = NULL;
Packit Service 384592
    dcfg->auditlog_name = NULL;
Packit Service 384592
    dcfg->auditlog2_name = NULL;
Packit Service 384592
    dcfg->auditlog_storage_dir = NULL;
Packit Service 384592
    dcfg->auditlog_parts = "ABCFHZ";
Packit Service 384592
    dcfg->auditlog_relevant_regex = NULL;
Packit Service 384592
    dcfg->tmp_dir = guess_tmp_dir(g_mp);
Packit Service 384592
    dcfg->upload_dir = NULL;
Packit Service 384592
    dcfg->upload_keep_files = KEEP_FILES_OFF;
Packit Service 384592
    dcfg->upload_validates_files = 0;
Packit Service 384592
    dcfg->data_dir = ".";
Packit Service 384592
    dcfg->webappid = "default";
Packit Service 384592
    dcfg->content_injection_enabled = 0;
Packit Service 384592
    dcfg->geo = NULL;
Packit Service 384592
    dcfg->cache_trans = MODSEC_CACHE_ENABLED;
Packit Service 384592
    dcfg->cache_trans_min = 15;
Packit Service 384592
    dcfg->cache_trans_max = 0;
Packit Service 384592
    dcfg->request_encoding = NULL;
Packit Service 384592
Packit Service 384592
    g_msr = (modsec_rec *)apr_pcalloc(g_mp, sizeof(modsec_rec));
Packit Service 384592
    g_msr->modsecurity = modsecurity;
Packit Service 384592
    g_msr->mp = g_mp;
Packit Service 384592
    g_msr->r = r;
Packit Service 384592
    g_msr->r_early = r;
Packit Service 384592
    g_msr->request_time = apr_time_now();
Packit Service 384592
    g_msr->dcfg1 = NULL;
Packit Service 384592
    g_msr->usercfg = NULL;
Packit Service 384592
    g_msr->txcfg = dcfg;
Packit Service 384592
    g_msr->txid = "FAKE-TXID";
Packit Service 384592
    g_msr->error_messages = NULL;
Packit Service 384592
    g_msr->alerts = NULL;
Packit Service 384592
    g_msr->server_software = "FAKE-SERVER-SOFTWARE";
Packit Service 384592
    g_msr->local_addr = "127.0.0.1";
Packit Service 384592
    g_msr->local_port = 80;
Packit Service 384592
    g_msr->remote_addr = "127.0.0.1";
Packit Service 384592
    g_msr->remote_port = 1080;
Packit Service 384592
    g_msr->request_line = "GET /unit-tests HTTP/1.1";
Packit Service 384592
    g_msr->request_uri = "http://localhost/unit-tests";
Packit Service 384592
    g_msr->request_method = "GET";
Packit Service 384592
    g_msr->query_string = "";
Packit Service 384592
    g_msr->request_protocol = "HTTP/1.1";
Packit Service 384592
    g_msr->request_headers = NULL;
Packit Service 384592
    g_msr->hostname = "localhost";
Packit Service 384592
    g_msr->msc_rule_mptmp = g_mp;
Packit Service 384592
    g_msr->tx_vars = apr_table_make(g_mp, 1);
Packit Service 384592
    g_msr->collections_original = apr_table_make(g_mp, 1);
Packit Service 384592
    g_msr->collections = apr_table_make(g_mp, 1);
Packit Service 384592
    g_msr->collections_dirty = apr_table_make(g_mp, 1);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
/**
Packit Service 384592
 * Usage text.
Packit Service 384592
 */
Packit Service 384592
static void usage(void)
Packit Service 384592
{
Packit Service 384592
    fprintf(stderr, "ModSecurity Unit Tester v%s\n", MODSEC_VERSION);
Packit Service 384592
    fprintf(stderr, "  Usage: msc_test [options]\n");
Packit Service 384592
    fprintf(stderr, "\n");
Packit Service 384592
    fprintf(stderr, "  Options:\n");
Packit Service 384592
    fprintf(stderr, "    -t        Type (required)\n");
Packit Service 384592
    fprintf(stderr, "    -n        Name (required)\n");
Packit Service 384592
    fprintf(stderr, "    -p        Parameter (required)\n");
Packit Service 384592
    fprintf(stderr, "    -P        Prerun (optional for actions)\n");
Packit Service 384592
    fprintf(stderr, "    -r        Function return code (required for some types)\n");
Packit Service 384592
    fprintf(stderr, "    -I        Iterations (default 1)\n");
Packit Service 384592
    fprintf(stderr, "    -D        Debug log level (default 0)\n");
Packit Service 384592
    fprintf(stderr, "    -N        No input on stdin.\n\n");
Packit Service 384592
    fprintf(stderr, "    -h        This help\n\n");
Packit Service 384592
    fprintf(stderr, "\n");
Packit Service 384592
    fprintf(stderr, "Input is from stdin unless -N is used.\n");
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
Packit Service 384592
Packit Service 384592
/* Main */
Packit Service 384592
Packit Service 384592
int main(int argc, const char * const argv[])
Packit Service 384592
{
Packit Service 384592
    apr_getopt_t *opt;
Packit Service 384592
    apr_file_t *fd;
Packit Service 384592
    apr_size_t nbytes = 0;
Packit Service 384592
    const char *type = NULL;
Packit Service 384592
    const char *name = NULL;
Packit Service 384592
    unsigned char *param = NULL;
Packit Service 384592
    unsigned char *prerun = NULL;
Packit Service 384592
    const char *returnval = NULL;
Packit Service 384592
    int iterations = 1;
Packit Service 384592
    char *errmsg = NULL;
Packit Service 384592
    unsigned char *out = NULL;
Packit Service 384592
    apr_size_t param_len = 0;
Packit Service 384592
    apr_size_t prerun_len = 0;
Packit Service 384592
    apr_size_t out_len = 0;
Packit Service 384592
    int noinput = 0;
Packit Service 384592
    int rc = 0;
Packit Service 384592
    int result = 0;
Packit Service 384592
    int ec = 0;
Packit Service 384592
    int i;
Packit Service 384592
    apr_time_t T0 = 0;
Packit Service 384592
    apr_time_t T1 = 0;
Packit Service 384592
    tfn_data_t tfn_data;
Packit Service 384592
    op_data_t op_data;
Packit Service 384592
    action_data_t action_data;
Packit Service 384592
    int ret = 0;
Packit Service 384592
Packit Service 384592
    memset(&tfn_data, 0, sizeof(tfn_data_t));
Packit Service 384592
    memset(&op_data, 0, sizeof(op_data_t));
Packit Service 384592
    memset(&action_data, 0, sizeof(action_data_t));
Packit Service 384592
Packit Service 384592
    apr_app_initialize(&argc, &argv, NULL);
Packit Service 384592
    atexit(apr_terminate);
Packit Service 384592
Packit Service 384592
    apr_pool_create(&g_mp, NULL);
Packit Service 384592
Packit Service 384592
    rc = apr_getopt_init(&opt, g_mp, argc, argv);
Packit Service 384592
    if (rc != APR_SUCCESS) {
Packit Service 384592
        fprintf(stderr, "Failed to initialize.\n\n");
Packit Service 384592
        usage();
Packit Service 384592
        exit(1);
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    do {
Packit Service 384592
        char  ch;
Packit Service 384592
        const char *val;
Packit Service 384592
        rc = apr_getopt(opt, CMDLINE_OPTS, &ch, &val;;
Packit Service 384592
        switch (rc) {
Packit Service 384592
        case APR_SUCCESS:
Packit Service 384592
            switch (ch) {
Packit Service 384592
                case 't':
Packit Service 384592
                    type = val;
Packit Service 384592
                    break;
Packit Service 384592
                case 'n':
Packit Service 384592
                    name = val;
Packit Service 384592
                    break;
Packit Service 384592
                case 'p':
Packit Service 384592
                    param_len = strlen(val);
Packit Service 384592
                    param = apr_pmemdup(g_mp, val, param_len + 1);
Packit Service 384592
                    unescape_inplace(param, &param_len);
Packit Service 384592
                    break;
Packit Service 384592
                case 'P':
Packit Service 384592
                    prerun_len = strlen(val);
Packit Service 384592
                    prerun = apr_pmemdup(g_mp, val, prerun_len + 1);
Packit Service 384592
                    unescape_inplace(prerun, &prerun_len);
Packit Service 384592
                    break;
Packit Service 384592
                case 'r':
Packit Service 384592
                    returnval = val;
Packit Service 384592
                    break;
Packit Service 384592
                case 'I':
Packit Service 384592
                    iterations = atoi(val);
Packit Service 384592
                    break;
Packit Service 384592
                case 'D':
Packit Service 384592
                    debuglog_level = atoi(val);
Packit Service 384592
                    break;
Packit Service 384592
                case 'N':
Packit Service 384592
                    noinput = 1;
Packit Service 384592
                    break;
Packit Service 384592
                case 'h':
Packit Service 384592
                    usage();
Packit Service 384592
                    exit(0);
Packit Service 384592
            }
Packit Service 384592
            break;
Packit Service 384592
        case APR_BADCH:
Packit Service 384592
        case APR_BADARG:
Packit Service 384592
            usage();
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
    } while (rc != APR_EOF);
Packit Service 384592
Packit Service 384592
    rc = apr_getopt_init(&opt, g_mp, argc, argv);
Packit Service 384592
    if (!type || !name || !param) {
Packit Service 384592
        usage();
Packit Service 384592
        exit(1);
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    modsecurity = modsecurity_create(g_mp, MODSEC_OFFLINE);
Packit Service 384592
    test_name = apr_psprintf(g_mp, "%s/%s", type, name);
Packit Service 384592
Packit Service 384592
    if (noinput == 0) {
Packit Service 384592
        if (apr_file_open_stdin(&fd, g_mp) != APR_SUCCESS) {
Packit Service 384592
            fprintf(stderr, "Failed to open stdin\n");
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
        /* Read in the input */
Packit Service 384592
        nbytes = BUFLEN;
Packit Service 384592
        memset(buf, 0, nbytes);
Packit Service 384592
        rc = apr_file_read(fd, buf, &nbytes);
Packit Service 384592
        if ((rc != APR_EOF) && (rc != APR_SUCCESS)) {
Packit Service 384592
            fprintf(stderr, "Failed to read data\n");
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
        if (nbytes < 0) {
Packit Service 384592
            fprintf(stderr, "Error reading data\n");
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
        apr_file_close(fd);
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    if (strcmp("tfn", type) == 0) {
Packit Service 384592
        ret = returnval ? atoi(returnval) : -8888;
Packit Service 384592
Packit Service 384592
        rc = init_tfn(&tfn_data, name, buf, nbytes, &errmsg);
Packit Service 384592
        if (rc < 0) {
Packit Service 384592
            fprintf(stderr, "ERROR: %s\n", errmsg);
Packit Service 384592
            result = RESULT_ERROR;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
    else if (strcmp("op", type) == 0) {
Packit Service 384592
        if (!returnval) {
Packit Service 384592
            fprintf(stderr, "Return value required for type \"%s\"\n", type);
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
        ret = atoi(returnval);
Packit Service 384592
Packit Service 384592
        init_msr();
Packit Service 384592
Packit Service 384592
        rc = init_op(&op_data, name, (const char *)param, buf, nbytes, &errmsg);
Packit Service 384592
        if (rc < 0) {
Packit Service 384592
            fprintf(stderr, "ERROR: %s\n", errmsg);
Packit Service 384592
            result = RESULT_ERROR;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
    else if (strcmp("action", type) == 0) {
Packit Service 384592
        if (!returnval) {
Packit Service 384592
            fprintf(stderr, "Return value required for type \"%s\"\n", type);
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
        ret = atoi(returnval);
Packit Service 384592
Packit Service 384592
        init_msr();
Packit Service 384592
Packit Service 384592
        if (prerun) {
Packit Service 384592
            action_data_t paction_data;
Packit Service 384592
            char *pname = apr_pstrdup(g_mp, (const char *)prerun);
Packit Service 384592
            char *pparam = NULL;
Packit Service 384592
Packit Service 384592
            if ((pparam = strchr((const char *)pname, ':'))) {
Packit Service 384592
                pparam[0] = '\0';
Packit Service 384592
                pparam++;
Packit Service 384592
            }
Packit Service 384592
Packit Service 384592
            rc = init_action(&paction_data, pname, (const char *)pparam, &errmsg);
Packit Service 384592
            if (rc < 0) {
Packit Service 384592
                fprintf(stderr, "ERROR: prerun - %s\n", errmsg);
Packit Service 384592
                exit(1);
Packit Service 384592
            }
Packit Service 384592
Packit Service 384592
            rc = test_action(&paction_data, &errmsg);
Packit Service 384592
            if (rc < 0) {
Packit Service 384592
                fprintf(stderr, "ERROR: prerun - %s\n", errmsg);
Packit Service 384592
                exit(1);
Packit Service 384592
            }
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
        rc = init_action(&action_data, name, (const char *)param, &errmsg);
Packit Service 384592
        if (rc < 0) {
Packit Service 384592
            fprintf(stderr, "ERROR: %s\n", errmsg);
Packit Service 384592
            result = RESULT_ERROR;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    if (iterations > 1) {
Packit Service 384592
        apr_time_clock_hires (g_mp);
Packit Service 384592
        T0 = apr_time_now();
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    for (i = 1; i <= iterations; i++) {
Packit Service 384592
        #ifdef VERBOSE
Packit Service 384592
        if (i % 100 == 0) {
Packit Service 384592
            if (i == 100) {
Packit Service 384592
                fprintf(stderr, "Iterations/100: .");
Packit Service 384592
            }
Packit Service 384592
            else {
Packit Service 384592
                fprintf(stderr, ".");
Packit Service 384592
            }
Packit Service 384592
        }
Packit Service 384592
        #endif
Packit Service 384592
Packit Service 384592
        if (strcmp("tfn", type) == 0) {
Packit Service 384592
            /* Transformations */
Packit Service 384592
            rc = test_tfn(&tfn_data, &out, &out_len, &errmsg);
Packit Service 384592
            if (rc < 0) {
Packit Service 384592
                fprintf(stderr, "ERROR: %s\n", errmsg);
Packit Service 384592
                result = RESULT_ERROR;
Packit Service 384592
            }
Packit Service 384592
            else if ((ret != -8888) && (rc != ret)) {
Packit Service 384592
                fprintf(stderr, "Returned %d (expected %d)\n", rc, ret);
Packit Service 384592
                result = RESULT_WRONGRET;
Packit Service 384592
            }
Packit Service 384592
            else if (param_len != out_len) {
Packit Service 384592
                fprintf(stderr, "Length %" APR_SIZE_T_FMT " (expected %" APR_SIZE_T_FMT ")\n", out_len, param_len);
Packit Service 384592
                result = RESULT_WRONGSIZE;
Packit Service 384592
            }
Packit Service 384592
            else {
Packit Service 384592
                result = memcmp(param, out, param_len) ? RESULT_MISMATCHED : RESULT_SUCCESS;
Packit Service 384592
            }
Packit Service 384592
Packit Service 384592
            if (result != RESULT_SUCCESS) {
Packit Service 384592
                apr_size_t s0len = nbytes;
Packit Service 384592
                const char *s0 = escape(buf, &s0len);
Packit Service 384592
                apr_size_t s1len = out_len;
Packit Service 384592
                const char *s1 = escape(out, &s1len);
Packit Service 384592
                apr_size_t s2len = param_len;
Packit Service 384592
                const char *s2 = escape(param, &s2len);
Packit Service 384592
Packit Service 384592
                fprintf(stderr, " Input: '%s' len=%" APR_SIZE_T_FMT "\n"
Packit Service 384592
                                "Output: '%s' len=%" APR_SIZE_T_FMT "\n"
Packit Service 384592
                                "Expect: '%s' len=%" APR_SIZE_T_FMT "\n",
Packit Service 384592
                                s0, nbytes, s1, out_len, s2, param_len);
Packit Service 384592
                ec = 1;
Packit Service 384592
            }
Packit Service 384592
        }
Packit Service 384592
        else if (strcmp("op", type) == 0) {
Packit Service 384592
            /* Operators */
Packit Service 384592
            rc = test_op(&op_data, &errmsg);
Packit Service 384592
            if (rc < 0) {
Packit Service 384592
                fprintf(stderr, "ERROR: %s\n", errmsg);
Packit Service 384592
                result = RESULT_ERROR;
Packit Service 384592
            }
Packit Service 384592
            else if (rc != ret) {
Packit Service 384592
                fprintf(stderr, "Returned %d (expected %d)\n", rc, ret);
Packit Service 384592
                result = RESULT_WRONGRET;
Packit Service 384592
            }
Packit Service 384592
            else {
Packit Service 384592
                result = RESULT_SUCCESS;
Packit Service 384592
            }
Packit Service 384592
Packit Service 384592
            if (result != RESULT_SUCCESS) {
Packit Service 384592
                apr_size_t s0len = nbytes;
Packit Service 384592
                const char *s0 = escape(buf, &s0len);
Packit Service 384592
Packit Service 384592
                fprintf(stderr, " Test: '@%s %s'\n"
Packit Service 384592
                                "Input: '%s' len=%" APR_SIZE_T_FMT "\n",
Packit Service 384592
                                name, param, s0, nbytes);
Packit Service 384592
                ec = 1;
Packit Service 384592
            }
Packit Service 384592
        }
Packit Service 384592
        else if (strcmp("action", type) == 0) {
Packit Service 384592
            /* Actions */
Packit Service 384592
            int n;
Packit Service 384592
            const apr_array_header_t *arr;
Packit Service 384592
            apr_table_entry_t *te;
Packit Service 384592
Packit Service 384592
            rc = test_action(&action_data, &errmsg);
Packit Service 384592
            if (rc < 0) {
Packit Service 384592
                fprintf(stderr, "ERROR: %s\n", errmsg);
Packit Service 384592
                result = RESULT_ERROR;
Packit Service 384592
            }
Packit Service 384592
            else if (rc != ret) {
Packit Service 384592
                fprintf(stderr, "Returned %d (expected %d)\n", rc, ret);
Packit Service 384592
                result = RESULT_WRONGRET;
Packit Service 384592
            }
Packit Service 384592
            else {
Packit Service 384592
                result = RESULT_SUCCESS;
Packit Service 384592
            }
Packit Service 384592
Packit Service 384592
            if (result != RESULT_SUCCESS) {
Packit Service 384592
                fprintf(stderr, "  Test: '%s:%s'\n"
Packit Service 384592
                                "Prerun: '%s'\n",
Packit Service 384592
                                name, param, (prerun ? (const char *)prerun : ""));
Packit Service 384592
                ec = 1;
Packit Service 384592
            }
Packit Service 384592
Packit Service 384592
            /* Store any collections that were initialized and changed */
Packit Service 384592
            arr = apr_table_elts(g_msr->collections);
Packit Service 384592
            te = (apr_table_entry_t *)arr->elts;
Packit Service 384592
            for (n = 0; n < arr->nelts; n++) {
Packit Service 384592
                apr_table_t *col = (apr_table_t *)te[n].val;
Packit Service 384592
//                apr_table_t *orig_col = NULL;
Packit Service 384592
Packit Service 384592
                if (g_msr->txcfg->debuglog_level >= 9) {
Packit Service 384592
                    msr_log(g_msr, 9, "Found loaded collection: %s", te[n].key);
Packit Service 384592
                }
Packit Service 384592
                /* Only store those collections that changed. */
Packit Service 384592
                if (apr_table_get(g_msr->collections_dirty, te[n].key)) {
Packit Service 384592
                    int x = collection_store(g_msr, col);
Packit Service 384592
Packit Service 384592
                    if (g_msr->txcfg->debuglog_level >= 9) {
Packit Service 384592
                        msr_log(g_msr, 9, "Stored collection: %s (%d)", te[n].key, x);
Packit Service 384592
                    }
Packit Service 384592
                }
Packit Service 384592
#if 0
Packit Service 384592
                /* Re-populate the original values with the new ones. */
Packit Service 384592
                if ((orig_col = (apr_table_t *)apr_table_get(g_msr->collections_original, te[n].key)) != NULL) {
Packit Service 384592
                    const apr_array_header_t *orig_arr = apr_table_elts(orig_col);
Packit Service 384592
                    apr_table_entry_t *orig_te = (apr_table_entry_t *)orig_arr->elts;
Packit Service 384592
                    int m;
Packit Service 384592
Packit Service 384592
                    for (m = 0; m < orig_arr->nelts; m++) {
Packit Service 384592
                        msc_string *mstr = (msc_string *)apr_table_get(col, orig_te[m].key);
Packit Service 384592
Packit Service 384592
                        if (g_msr->txcfg->debuglog_level >= 9) {
Packit Service 384592
                            msr_log(g_msr, 9, "Updating original collection: %s.%s=%s", te[n].key, mstr->name, mstr->value);
Packit Service 384592
                        }
Packit Service 384592
                        //apr_table_setn(orig_col, orig_te[m].key, (void *)mstr );
Packit Service 384592
                        collection_original_setvar(g_msr, te[n].key, mstr);
Packit Service 384592
Packit Service 384592
                        
Packit Service 384592
                    }
Packit Service 384592
                }
Packit Service 384592
#endif
Packit Service 384592
            }
Packit Service 384592
            apr_table_clear(g_msr->collections_dirty);
Packit Service 384592
            apr_table_clear(g_msr->collections_original);
Packit Service 384592
        }
Packit Service 384592
        else {
Packit Service 384592
            fprintf(stderr, "Unknown type: \"%s\"\n", type);
Packit Service 384592
            exit(1);
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
        if (ec != 0) {
Packit Service 384592
            fprintf(stdout, "%s\n", errmsg ? errmsg : "");
Packit Service 384592
            return ec;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    if (iterations > 1) {
Packit Service 384592
        double dT;
Packit Service 384592
        T1 = apr_time_now();
Packit Service 384592
Packit Service 384592
        dT = apr_time_as_msec(T1 - T0);
Packit Service 384592
Packit Service 384592
        #ifdef VERBOSE
Packit Service 384592
        if (i >= 100) {
Packit Service 384592
            fprintf(stderr, "\n");
Packit Service 384592
        }
Packit Service 384592
        #endif
Packit Service 384592
Packit Service 384592
        fprintf(stdout, "%d @ %.4f msec per iteration.\n", iterations, dT / iterations);
Packit Service 384592
    }
Packit Service 384592
    fprintf(stdout, "%s\n", errmsg ? errmsg : "");
Packit Service 384592
Packit Service 384592
    return ec;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592