コード例 #1
0
ファイル: logger.c プロジェクト: nickleroy/ironbee
ib_status_t DLL_PUBLIC ib_logevent_field_add(ib_logevent_t *le,
                                             const char *name)
{
    IB_FTRACE_INIT();
    char *name_copy;
    ib_status_t rc;

    assert(le != NULL);

    if (le->fields == NULL) {
        rc = ib_list_create(&le->fields, le->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    name_copy = ib_mpool_memdup(le->mp, name, strlen(name) + 1);
    rc = ib_list_push(le->fields, name_copy);

    IB_FTRACE_RET_STATUS(rc);
}
コード例 #2
0
ファイル: logger.c プロジェクト: nickleroy/ironbee
ib_status_t DLL_PUBLIC ib_logevent_tag_add(ib_logevent_t *le,
                                           const char *tag)
{
    IB_FTRACE_INIT();
    char *tag_copy;
    ib_status_t rc;

    assert(le != NULL);

    if (le->tags == NULL) {
        rc = ib_list_create(&le->tags, le->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    tag_copy = ib_mpool_memdup(le->mp, tag, strlen(tag) + 1);
    rc = ib_list_push(le->tags, tag_copy);

    IB_FTRACE_RET_STATUS(rc);
}
コード例 #3
0
ファイル: config.c プロジェクト: nrupaks/ironbee
ib_status_t ib_site_create(ib_site_t **psite,
                           ib_engine_t *ib,
                           const char *name)
{
    IB_FTRACE_INIT(ib_site_create);
    ib_mpool_t *pool = ib->config_mp;
    ib_status_t rc;

    /* Create the main structure in the config memory pool */
    *psite = (ib_site_t *)ib_mpool_calloc(pool, 1, sizeof(**psite));
    if (*psite == NULL) {
        rc = IB_EALLOC;
        IB_FTRACE_RET_STATUS(rc);
    }
    (*psite)->ib = ib;
    (*psite)->mp = pool;
    (*psite)->name = (const char *)ib_mpool_memdup(pool, name, strlen(name)+1);


    /* Remaining fields are NULL via calloc. */

    IB_FTRACE_RET_STATUS(IB_OK);
}
コード例 #4
0
ファイル: config.c プロジェクト: nrupaks/ironbee
ib_status_t ib_site_loc_create(ib_site_t *site,
                               ib_loc_t **ploc,
                               const char *path)
{
    IB_FTRACE_INIT(ib_site_loc_create);
    ib_loc_t *loc;
    ib_status_t rc;

    if (ploc != NULL) {
        *ploc = NULL;
    }

    /* Create a list if this is the first item. */
    if (site->locations == NULL) {
        rc = ib_list_create(&site->locations, site->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    /* Create the location structure in the site memory pool */
    loc = (ib_loc_t *)ib_mpool_calloc(site->mp, 1, sizeof(*loc));
    if (loc == NULL) {
        rc = IB_EALLOC;
        IB_FTRACE_RET_STATUS(rc);
    }
    loc->site = site;
    loc->path = path;
    loc->path = (const char *)ib_mpool_memdup(site->mp, path, strlen(path)+1);

    if (ploc != NULL) {
        *ploc = loc;
    }

    rc = ib_list_push(site->locations, (void *)loc);
    IB_FTRACE_RET_STATUS(rc);
}
コード例 #5
0
ファイル: pcre.c プロジェクト: BillTheBest/ironbee
/**
 * Internal compilation of the modpcre pattern.
 *
 * @param[in] ib IronBee engine for logging.
 * @param[in] pool The memory pool to allocate memory out of.
 * @param[out] pcre_cpatt Struct containing the compilation.
 * @param[in] patt The uncompiled pattern to match.
 * @param[out] errptr Pointer to an error message describing the failure.
 * @param[out] errorffset The location of the failure, if this fails.
 * @returns IronBee status. IB_EINVAL if the pattern is invalid,
 *          IB_EALLOC if memory allocation fails or IB_OK.
 */
static ib_status_t pcre_compile_internal(ib_engine_t *ib,
                                         ib_mpool_t *pool,
                                         modpcre_cpatt_t **pcre_cpatt,
                                         const char *patt,
                                         const char **errptr,
                                         int *erroffset)
{
    IB_FTRACE_INIT();

    /* Compiled pattern. */
    pcre *cpatt = NULL;

    /* Compiled pattern size. Used to copy cpatt. */
    size_t cpatt_sz;

    /* Extra data structure. This contains the study_data pointer. */
    pcre_extra *edata = NULL;

    /* Size of edata->study_data. */
    size_t study_data_sz;

    /* Is the compiled regex jit-compiled? This impacts how it is executed. */
    int is_jit;

    /* How cpatt is produced. */
    const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
#ifdef PCRE_HAVE_JIT
    /* Determine the success of a call. */
    int rc;

    /* Determines if the pcre compilation was successful with pcre_jit. */
    int pcre_jit_ret;

    /* How edata is produced if we are using JIT. */
    const int study_flags = PCRE_STUDY_JIT_COMPILE;
#else

    /* How edata is produced if we are not using JIT. */
    const int study_flags = 0;
#endif /* PCRE_HAVE_JIT */

    cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL);

    if (*errptr != NULL) {
        ib_util_log_error("PCRE compile error for \"%s\": %s at offset %d",
                          patt, *errptr, *erroffset);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    edata = pcre_study(cpatt, study_flags, errptr);

#ifdef PCRE_HAVE_JIT
    if(*errptr != NULL)  {
        pcre_free(cpatt);
        ib_util_log_error("PCRE-JIT study failed: %s", *errptr);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* The check to see if JIT compilation was a success changed in 8.20RC1
       now uses pcre_fullinfo see doc/pcrejit.3 */
    rc = pcre_fullinfo(cpatt, edata, PCRE_INFO_JIT, &pcre_jit_ret);
    if (rc != 0) {
        ib_log_error(ib, "PCRE-JIT failed to get pcre_fullinfo");
        is_jit = 0;
    }
    else if (pcre_jit_ret != 1) {
        ib_log_info(ib, "PCRE-JIT compiler does not support: %s", patt);
        ib_log_info(ib, "It will fallback to the normal PCRE");
        is_jit = 0;
    }
    else { /* Assume pcre_jit_ret == 1. */
        is_jit = 1;
    }
#else
    if(*errptr != NULL)  {
        pcre_free(cpatt);
        ib_log_info(ib, "PCRE study failed: %s", *errptr);
    }
    is_jit = 0;
#endif /*PCRE_HAVE_JIT*/

    /* Compute the size of the populated values of cpatt. */
    pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz);

    if (edata != NULL) {
        pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz);
    }
    else {
        study_data_sz = 0;
    }

    /**
     * Below is only allocation and copy operations to pass the PCRE results
     * back to the output variable pcre_cpatt.
     */

    *pcre_cpatt = (modpcre_cpatt_t *)ib_mpool_alloc(pool, sizeof(**pcre_cpatt));
    if (*pcre_cpatt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        ib_log_error(ib,
                     "Failed to allocate pcre_cpatt of size: %zd",
                     sizeof(**pcre_cpatt));
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    (*pcre_cpatt)->is_jit = is_jit;
    (*pcre_cpatt)->cpatt_sz = cpatt_sz;
    (*pcre_cpatt)->study_data_sz = study_data_sz;

    /* Copy pattern. */
    (*pcre_cpatt)->patt  = ib_mpool_strdup(pool, patt);
    if ((*pcre_cpatt)->patt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        ib_log_error(ib, "Failed to duplicate pattern string: %s", patt);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy compiled pattern. */
    (*pcre_cpatt)->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz);
    pcre_free(cpatt);
    if ((*pcre_cpatt)->cpatt == NULL) {
        pcre_free(edata);
        ib_log_error(ib, "Failed to duplicate pattern of size: %zd", cpatt_sz);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy extra data (study data). */
    if (edata != NULL) {

        /* Copy edata. */
        (*pcre_cpatt)->edata = ib_mpool_memdup(pool, edata, sizeof(*edata));

        if ((*pcre_cpatt)->edata == NULL) {
            pcre_free(edata);
            ib_log_error(ib, "Failed to duplicate edata.");
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }

        /* Copy edata->study_data. */
        (*pcre_cpatt)->edata->study_data = ib_mpool_memdup(pool,
                                                           edata->study_data,
                                                           study_data_sz);
        pcre_free(edata);
        if ((*pcre_cpatt)->edata->study_data == NULL) {
            ib_log_error(ib, "Failed to study data of size: %zd", study_data_sz);
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }
    }
    else {
        (*pcre_cpatt)->edata = NULL;
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
コード例 #6
0
ファイル: pcre.c プロジェクト: BillTheBest/ironbee
/**
 * Internal compilation of the dfa pattern.
 *
 * The major difference in this compilation from that of a normal pcre pattern
 * is that it does not use PCRE_JIT because it is intended for use
 * on streaming data. Streaming data is delivered in chunks
 * and partial matches are found. Doing partial matches and resumes
 * disable JIT optimizations and some a few other normal optimizations.
 *
 * @param[in] pool The memory pool to allocate memory out of.
 * @param[out] pcre_cpatt Struct containing the compilation.
 * @param[in] patt The uncompiled pattern to match.
 * @param[out] errptr Pointer to an error message describing the failure.
 * @param[out] errorffset The location of the failure, if this fails.
 * @returns IronBee status. IB_EINVAL if the pattern is invalid,
 *          IB_EALLOC if memory allocation fails or IB_OK.
 */
static ib_status_t dfa_compile_internal(ib_mpool_t *pool,
                                        dfa_rule_data_t **dfa_cpatt,
                                        const char *patt,
                                        const char **errptr,
                                        int *erroffset)
{
    IB_FTRACE_INIT();

    /* Compiled pattern. */
    pcre *cpatt = NULL;

    /* Compiled pattern size. Used to copy cpatt. */
    size_t cpatt_sz;

    /* Extra data structure. This contains the study_data pointer. */
    pcre_extra *edata = NULL;

    /* Size of edata->study_data. */
    size_t study_data_sz;

    /* How cpatt is produced. */
    const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;

    /* How edata is produced if we are not using JIT. */
    const int study_flags = 0;

    cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL);

    if (*errptr != NULL) {
        ib_util_log_error("PCRE compile error for \"%s\": %s at offset %d",
                          patt, *errptr, *erroffset);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    edata = pcre_study(cpatt, study_flags, errptr);

    if(*errptr != NULL)  {
        pcre_free(cpatt);
        ib_util_log_error("PCRE study failed: %s", *errptr);
    }

    /* Compute the size of the populated values of cpatt. */
    pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz);

    if (edata != NULL) {
        pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz);
    }
    else {
        study_data_sz = 0;
    }

    /**
     * Below is only allocation and copy operations to pass the PCRE results
     * back to the output variable dfa_cpatt.
     */

    *dfa_cpatt = (dfa_rule_data_t *)ib_mpool_alloc(pool, sizeof(**dfa_cpatt));
    if (*dfa_cpatt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    (*dfa_cpatt)->cpatt_sz = cpatt_sz;
    (*dfa_cpatt)->study_data_sz = study_data_sz;

    /* Copy pattern. */
    (*dfa_cpatt)->patt  = ib_mpool_strdup(pool, patt);
    if ((*dfa_cpatt)->patt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy compiled pattern. */
    (*dfa_cpatt)->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz);
    pcre_free(cpatt);
    if ((*dfa_cpatt)->cpatt == NULL) {
        pcre_free(edata);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy extra data (study data). */
    if (edata != NULL) {

        /* Copy edata. */
        (*dfa_cpatt)->edata = ib_mpool_memdup(pool, edata, sizeof(*edata));

        if ((*dfa_cpatt)->edata == NULL) {
            pcre_free(edata);
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }

        /* Copy edata->study_data. */
        (*dfa_cpatt)->edata->study_data = ib_mpool_memdup(pool,
                                                           edata->study_data,
                                                           study_data_sz);
        pcre_free(edata);
        if ((*dfa_cpatt)->edata->study_data == NULL) {
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }
    }
    else {
        (*dfa_cpatt)->edata = NULL;
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
コード例 #7
0
ファイル: pcre.c プロジェクト: niubl/ironbee
/**
 * Internal compilation of the modpcre pattern.
 *
 * @param[in] ib IronBee engine for logging.
 * @param[in] pool The memory pool to allocate memory out of.
 * @param[in] config Module configuration
 * @param[in] is_dfa Set to true for DFA
 * @param[out] pcpdata Pointer to new struct containing the compilation.
 * @param[in] patt The uncompiled pattern to match.
 * @param[out] errptr Pointer to an error message describing the failure.
 * @param[out] erroffset The location of the failure, if this fails.
 *
 * @returns IronBee status. IB_EINVAL if the pattern is invalid,
 *          IB_EALLOC if memory allocation fails or IB_OK.
 */
static ib_status_t pcre_compile_internal(ib_engine_t *ib,
                                         ib_mpool_t *pool,
                                         const modpcre_cfg_t *config,
                                         bool is_dfa,
                                         modpcre_cpat_data_t **pcpdata,
                                         const char *patt,
                                         const char **errptr,
                                         int *erroffset)
{
    assert(ib != NULL);
    assert(pool != NULL);
    assert(config != NULL);
    assert(pcpdata != NULL);
    assert(patt != NULL);

    /* Pattern data structure we'll create */
    modpcre_cpat_data_t *cpdata;

    /* Compiled pattern. */
    pcre *cpatt = NULL;

    /* Compiled pattern size. Used to copy cpatt. */
    size_t cpatt_sz;

    /* Extra data structure. This contains the study_data pointer. */
    pcre_extra *edata = NULL;

    /* Size of edata->study_data. */
    size_t study_data_sz;

    /* How cpatt is produced. */
    const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;

    /* Are we using JIT? */
    bool use_jit = !is_dfa;

#ifdef PCRE_HAVE_JIT
    if (config->use_jit == 0) {
        use_jit = false;
    }

    /* Do we want to be using JIT? */
    const bool want_jit = use_jit;
#else
    use_jit = false;
#endif /* PCRE_HAVE_JIT */

    cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL);

    if (*errptr != NULL) {
        ib_log_error(ib, "PCRE compile error for \"%s\": %s at offset %d",
                     patt, *errptr, *erroffset);
        return IB_EINVAL;
    }

    if (config->study) {
        if (use_jit) {
#ifdef PCRE_HAVE_JIT
            edata = pcre_study(cpatt, PCRE_STUDY_JIT_COMPILE, errptr);
            if (*errptr != NULL)  {
                pcre_free(cpatt);
                use_jit = false;
                ib_log_warning(ib, "PCRE-JIT study failed: %s", *errptr);
            }
#endif
        }
        else {
            edata = pcre_study(cpatt, 0, errptr);
            if (*errptr != NULL)  {
                pcre_free(cpatt);
                ib_log_error(ib, "PCRE study failed: %s", *errptr);
            }
        }
    }
    else if (use_jit) {
        ib_log_warning(ib, "PCRE: Disabling JIT because study disabled");
        use_jit = false;
    }

#ifdef PCRE_HAVE_JIT
    /* The check to see if JIT compilation was a success changed in 8.20RC1
       now uses pcre_fullinfo see doc/pcrejit.3 */
    if (use_jit) {
        int rc;
        int pcre_jit_ret;

        rc = pcre_fullinfo(cpatt, edata, PCRE_INFO_JIT, &pcre_jit_ret);
        if (rc != 0) {
            ib_log_error(ib, "PCRE-JIT failed to get pcre_fullinfo");
            use_jit = false;
        }
        else if (pcre_jit_ret != 1) {
            ib_log_info(ib, "PCRE-JIT compiler does not support: %s", patt);
            use_jit = false;
        }
        else { /* Assume pcre_jit_ret == 1. */
            /* Do nothing */
        }
    }
    if (want_jit && !use_jit) {
        ib_log_info(ib, "Falling back to normal PCRE");
    }
#endif /*PCRE_HAVE_JIT*/

    /* Compute the size of the populated values of cpatt. */
    pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz);
    if (edata != NULL) {
        pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz);
    }
    else {
        study_data_sz = 0;
    }

    /**
     * Below is only allocation and copy operations to pass the PCRE results
     * back to the output variable cpdata.
     */

    cpdata = (modpcre_cpat_data_t *)ib_mpool_calloc(pool, sizeof(*cpdata), 1);
    if (cpdata == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        ib_log_error(ib,
                     "Failed to allocate cpdata of size: %zd",
                     sizeof(*cpdata));
        return IB_EALLOC;
    }

    cpdata->is_dfa = is_dfa;
    cpdata->is_jit = use_jit;
    cpdata->cpatt_sz = cpatt_sz;
    cpdata->study_data_sz = study_data_sz;

    /* Copy pattern. */
    cpdata->patt = ib_mpool_strdup(pool, patt);
    if (cpdata->patt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        ib_log_error(ib, "Failed to duplicate pattern string: %s", patt);
        return IB_EALLOC;
    }

    /* Copy compiled pattern. */
    cpdata->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz);
    pcre_free(cpatt);
    if (cpdata->cpatt == NULL) {
        pcre_free(edata);
        ib_log_error(ib, "Failed to duplicate pattern of size: %zd", cpatt_sz);
        return IB_EALLOC;
    }
    ib_log_debug(ib, "PCRE copied cpatt @ %p -> %p (%zd bytes)",
                 (void *)cpatt, (void *)cpdata->cpatt, cpatt_sz);

    /* Copy extra data (study data). */
    if (edata != NULL) {

        /* Copy edata. */
        cpdata->edata = ib_mpool_memdup(pool, edata, sizeof(*edata));
        if (cpdata->edata == NULL) {
            pcre_free(edata);
            ib_log_error(ib, "Failed to duplicate edata.");
            return IB_EALLOC;
        }

        /* Copy edata->study_data. */
        if (edata->study_data != NULL) {
            cpdata->edata->study_data =
                ib_mpool_memdup(pool, edata->study_data, study_data_sz);

            if (cpdata->edata->study_data == NULL) {
                ib_log_error(ib, "Failed to study data of size: %zd",
                             study_data_sz);
                pcre_free(edata);
                return IB_EALLOC;
            }
        }
        pcre_free(edata);
    }
    else {
        cpdata->edata = ib_mpool_calloc(pool, 1, sizeof(*edata));
        if (cpdata->edata == NULL) {
            pcre_free(edata);
            ib_log_error(ib, "Failed to allocate edata.");
            return IB_EALLOC;
        }
    }

    /* Set the PCRE limits for non-DFA patterns */
    if (! is_dfa) {
        cpdata->edata->flags |=
            (PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION);
        cpdata->edata->match_limit =
            (unsigned long)config->match_limit;
        cpdata->edata->match_limit_recursion =
            (unsigned long)config->match_limit_recursion;
        cpdata->dfa_ws_size = 0;
    }
    else {
        cpdata->edata->match_limit = 0U;
        cpdata->edata->match_limit_recursion = 0U;
        cpdata->dfa_ws_size = (int)config->dfa_workspace_size;
    }

    /* Set stack limits for JIT */
    if (cpdata->is_jit) {
#ifdef PCRE_HAVE_JIT
        if (config->jit_stack_start == 0U) {
            cpdata->jit_stack_start =
                PCRE_JIT_STACK_START_MULT * config->match_limit_recursion;
        }
        else {
            cpdata->jit_stack_start = (int)config->jit_stack_start;
        }
        if (config->jit_stack_max == 0U) {
            cpdata->jit_stack_max =
                PCRE_JIT_STACK_MAX_MULT * config->match_limit_recursion;
        }
        else {
            cpdata->jit_stack_max = (int)config->jit_stack_max;
        }
#endif
    }
    else {
        cpdata->jit_stack_start = 0;
        cpdata->jit_stack_max = 0;
    }

    ib_log_trace(ib,
                 "Compiled pcre pattern \"%s\": "
                 "cpatt=%p edata=%p limit=%ld rlimit=%ld study=%p "
                 "dfa=%s dfa-ws-sz=%d "
                 "jit=%s jit-stack: start=%d max=%d",
                 patt,
                 (void *)cpdata->cpatt,
                 (void *)cpdata->edata,
                 cpdata->edata->match_limit,
                 cpdata->edata->match_limit_recursion,
                 cpdata->edata->study_data,
                 cpdata->is_dfa ? "yes" : "no",
                 cpdata->dfa_ws_size,
                 cpdata->is_jit ? "yes" : "no",
                 cpdata->jit_stack_start,
                 cpdata->jit_stack_max);
    *pcpdata = cpdata;

    return IB_OK;
}
コード例 #8
0
ファイル: libinjection.c プロジェクト: niubl/ironbee
/*********************************
 * Helper Functions
 *********************************/
static
ib_status_t sqli_create_pattern_set_from_file(
    sqli_pattern_set_t **out_ps,
    const char         *path,
    ib_mpool_t         *mp
)
{
    assert(out_ps != NULL);
    assert(path   != NULL);
    assert(mp     != NULL);

    ib_status_t  rc;
    FILE               *fp          = NULL;
    char               *buffer      = NULL;
    size_t              buffer_size = 0;
    ib_list_t          *items       = NULL;
    ib_list_node_t     *n           = NULL;
    ib_mpool_t         *tmp         = NULL;
    sqli_pattern_set_t *ps          = NULL;
    size_t              i           = 0;

    /* Temporary memory pool for this function only. */
    rc = ib_mpool_create(&tmp, "sqli tmp", NULL);
    assert(rc == IB_OK);
    assert(tmp != NULL);

    fp = fopen(path, "r");
    if (fp == NULL) {
        goto fail;
    }

    rc = ib_list_create(&items, tmp);
    assert(rc    == IB_OK);
    assert(items != NULL);

    for (;;) {
        char *buffer_copy;
        int   read = getline(&buffer, &buffer_size, fp);

        if (read == -1) {
            if (! feof(fp)) {
                fclose(fp);
                goto fail;
            }
            else {
                break;
            }
        }

        buffer_copy = ib_mpool_memdup(mp, buffer, read);
        assert(buffer_copy != NULL);
        while (buffer_copy[read-1] == '\n' || buffer_copy[read-1] == '\r') {
            buffer_copy[read-1] = '\0';
            --read;
        }

        rc = ib_list_push(items, (void *)buffer_copy);
        assert(rc == IB_OK);
    }

    fclose(fp);

    ps = ib_mpool_alloc(mp, sizeof(*ps));
    assert(ps != NULL);

    ps->num_patterns = ib_list_elements(items);
    ps->patterns =
        ib_mpool_alloc(mp, ps->num_patterns * sizeof(*ps->patterns));
    assert(ps->patterns != NULL);

    i = 0;
    IB_LIST_LOOP(items, n) {
        ps->patterns[i] = ib_list_node_data(n);
        ++i;
    }
コード例 #9
0
ファイル: expand.c プロジェクト: moon2l/ironbee
/*
 * Expand a string from the given hash-like object, ex version.  See expand.h.
 */
ib_status_t ib_expand_str_gen_ex(ib_mpool_t *mp,
                                 const char *str,
                                 size_t str_len,
                                 const char *prefix,
                                 const char *suffix,
                                 bool nul,
                                 bool recurse,
                                 ib_expand_lookup_fn_t lookup_fn,
                                 const void *lookup_data,
                                 char **result,
                                 size_t *result_len)
{
    IB_FTRACE_INIT();
    ib_status_t rc;
    size_t pre_len;             /* Prefix string length */
    size_t suf_len = SIZE_MAX;  /* Suffix string length */
    const char *buf = str;      /* Current buffer */
    size_t buflen = str_len;    /* Length of the buffer */

    /* Sanity checks */
    assert(mp != NULL);
    assert(str != NULL);
    assert(prefix != NULL);
    assert(suffix != NULL);
    assert(lookup_fn != NULL);
    assert(result != NULL);
    assert(result_len != NULL);

    /* Initialize the result to NULL */
    *result = NULL;
    *result_len = 0;

    /* Validate prefix and suffix */
    if ( (*prefix == '\0') || (*suffix == '\0') ) {
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Compute prefix length */
    pre_len = strlen(prefix);
    assert(pre_len != 0);

    /* Check for minimum string length */
    if (str_len < (pre_len+1) ) {
        *result = (char *)ib_mpool_memdup(mp, str, str_len);
        *result_len = str_len;
        IB_FTRACE_RET_STATUS(IB_OK);
    }

    /* Loop until there is nothing more to find. */
    while (1) {
        const char *pre = NULL; /* Pointer to found prefix string */
        size_t      pre_off = 0;/* Offset of prefix in the string */
        const char *suf = NULL; /* Pointer to found suffix string */
        const char *name;       /* Pointer to name between pre and suffix */
        size_t      namelen;    /* Length of the name */
        char       *new;        /* New buffer */
        size_t      newlen;     /* Length of new buffer */
        const char *iptr;       /* Initial block (up to the prefix) */
        size_t      ilen;       /* Length of the initial block */
        const char *fptr;       /* Final block (after the suffix) */
        size_t      flen;       /* Length of the final block */
        ib_field_t *f;          /* Field */
        size_t      slen;       /* Length of the buffer to search */

        /* Look for the last prefix in the string with a matching suffix */
        slen = buflen;
        while ( (pre == NULL) && (slen >= pre_len) ) {
            if (recurse) {
                pre = ib_strrstr_ex(buf, slen, prefix, pre_len);
            }
            else {
                pre = ib_strstr_ex(buf, slen, prefix, pre_len);
            }
            if (pre == NULL) {
                break;
            }

            /* Lazy compute suffix length */
            if (suf_len == SIZE_MAX) {
                suf_len = strlen(suffix);
                assert (suf_len != 0);
            }

            /* And the next matching suffix */
            pre_off = pre - buf;
            suf = ib_strstr_ex(pre+pre_len,
                               buflen - (pre_off + pre_len),
                               suffix,
                               suf_len);
            if ( recurse && (suf == NULL) ) {
                slen = (pre - buf);
                pre = NULL;
            }
        }

        /* Did we find a matching pair? */
        if ( (pre == NULL) || (suf == NULL) ) {
            break;
        }

        /* The name is the block between the two */
        name = (pre + pre_len);
        namelen = (suf - pre) - pre_len;

        /* Length of the initial block */
        iptr = buf;
        ilen = (pre - buf);

        /* The final block */
        fptr = (suf + suf_len);
        flen = (buf + buflen ) - fptr;

        /* Zero length name? Expand it to "" */
        if (namelen == 0) {
            rc = join2(mp,
                       iptr, ilen,
                       fptr, flen,
                       true,
                       &new, &newlen);
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
            buf = new;
            buflen = newlen;
            continue;
        }

        /* Search the hash */
        rc = lookup_fn(lookup_data, name, namelen, &f);
        if (rc == IB_ENOENT) {
            /* Not in the hash; replace with "" */
            rc = join2(mp,
                       iptr, ilen,
                       fptr, flen,
                       true,
                       &new, &newlen);
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
            buf = new;
            buflen = newlen;
            continue;
        }
コード例 #10
0
ib_status_t ib_tfn_data_get_ex(
    ib_engine_t *ib,
    ib_data_t   *data,
    const char  *name,
    size_t       nlen,
    const ib_field_t **pf,
    const char  *tfn
)
{
    assert(data != NULL);

    char *fullname;
    size_t fnlen;
    size_t tlen;
    ib_status_t rc;

    /* No tfn just means a normal get. */
    if (tfn == NULL) {
        rc = ib_data_get_ex(data, name, nlen, (void *)pf);
        return rc;
    }

    /* Build the full name with tfn: "name.t(tfn)" */
    tlen = strlen(tfn);
    fnlen = nlen + tlen + 4; /* Additional ".t()" bytes */
    fullname = (char *)ib_mpool_alloc(ib_data_pool(data), fnlen);
    memcpy(fullname, name, nlen);
    memcpy(fullname + nlen, ".t(", fnlen - nlen);
    memcpy(fullname + nlen + 3, tfn, fnlen - nlen - 3);
    fullname[fnlen - 1] = ')';

    /* See if there is already a transformed version, otherwise
     * one needs to be created.
     */
    rc = ib_data_get_ex(data, fullname, fnlen, (void *)pf);
    if (rc == IB_ENOENT) {
        const char *tname;
        size_t i;
        ib_field_t *new_pf;

        /* Get the non-tfn field. */
        rc = ib_data_get_ex(data, name, nlen, &new_pf);
        if (rc != IB_OK) {
            return rc;
        }

        /* Currently this only works for string type fields. */
        if (   (new_pf->type != IB_FTYPE_NULSTR)
            && (new_pf->type != IB_FTYPE_BYTESTR))
        {
            return IB_EINVAL;
        }


        /* Copy the field, noting the tfn. */
        rc = ib_field_copy(&new_pf, ib_data_pool(data), fullname, fnlen, new_pf);
        if (rc != IB_OK) {
            return rc;
        }
        new_pf->tfn = (char *)ib_mpool_memdup(ib_data_pool(data), tfn, tlen + 1);


        /* Transform. */
        tname = tfn;
        for (i = 0; i <= tlen; ++i) {
            ib_tfn_t *t;
            ib_flags_t flags;

            if ((tfn[i] == ',') || (i == tlen)) {
                size_t len = (tfn + i) - tname;

                rc = ib_tfn_lookup_ex(ib, tname, len, &t);
                if (rc == IB_OK) {
                    rc = ib_tfn_transform(ib, ib_data_pool(data), t, new_pf, (const ib_field_t**) &new_pf, &flags);
                    if (rc != IB_OK) {
                        /// @todo What to do here?  Fail or ignore?
                    }
                }
                else {
                    /// @todo What to do here?  Fail or ignore?
                }
                tname = tfn + i + 1;

            }
        }

        /* Store the transformed field. */
        rc = ib_data_set(data, new_pf, name, nlen);
        if (rc != IB_OK) {
            return rc;
        }
        *pf = new_pf;
    }

    return rc;
}