示例#1
0
/// @test Test util field library - ib_field_from_string()
TEST_F(TestIBUtilField, test_field_from_string)
{
    ib_field_t *f;
    ib_status_t rc;
    ib_num_t fnum;
    ib_float_t ffloat;
    const char *fnulstr;

    rc = ib_field_from_string(MM(), IB_S2SL("test_num"),
                              "11", &f);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(IB_FTYPE_NUM, f->type);
    ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_num_out(&fnum)));
    ASSERT_EQ(11, fnum);

    rc = ib_field_from_string(MM(), IB_S2SL("test_num"),
                              "-11", &f);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(IB_FTYPE_NUM, f->type);
    ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_num_out(&fnum)));
    ASSERT_EQ(-11, fnum);

    rc = ib_field_from_string(MM(), IB_S2SL("test_float"),
                              "1.0", &f);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(IB_FTYPE_FLOAT, f->type);
    ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_float_out(&ffloat)));
    ASSERT_EQ(1.0, ffloat);

    rc = ib_field_from_string(MM(), IB_S2SL("test_num"),
                              "-1.0", &f);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(IB_FTYPE_FLOAT, f->type);
    ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_float_out(&ffloat)));
    ASSERT_EQ(-1.0, ffloat);

    rc = ib_field_from_string(MM(), IB_S2SL("test_str"),
                              "x", &f);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(IB_FTYPE_NULSTR, f->type);
    ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_nulstr_out(&fnulstr)));
    ASSERT_STREQ("x", fnulstr);

    rc = ib_field_from_string(MM(), IB_S2SL("test_str"),
                              "-1.1x", &f);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(IB_FTYPE_NULSTR, f->type);
    ASSERT_EQ(IB_OK, ib_field_value(f, ib_ftype_nulstr_out(&fnulstr)));
    ASSERT_STREQ("-1.1x", fnulstr);
}
示例#2
0
ib_status_t test_execute_fn(const ib_rule_exec_t *rule_exec,
                            void *data,
                            ib_flags_t flags,
                            ib_field_t *field,
                            ib_num_t *result)
{
    char *searchstr = (char *)data;
    const char* s;
    ib_status_t rc;

    if (field->type != IB_FTYPE_NULSTR) {
        return IB_EINVAL;
    }

    rc = ib_field_value(field, ib_ftype_nulstr_out(&s));
    if (rc != IB_OK) {
        return rc;
    }

    if (strstr(s, searchstr) == NULL) {
        *result = 0;
    }
    else {
        *result = 1;
    }

    return IB_OK;
}
示例#3
0
ib_status_t test_execute_fn(
    ib_tx_t    *tx,
    void       *instance_data,
    const ib_field_t *field,
    ib_field_t *capture,
    ib_num_t   *result,
    void       *cbdata
)
{
    char *searchstr = (char *)instance_data;
    const char* s;
    ib_status_t rc;

    if (field->type != IB_FTYPE_NULSTR) {
        return IB_EINVAL;
    }

    rc = ib_field_value(field, ib_ftype_nulstr_out(&s));
    if (rc != IB_OK) {
        return rc;
    }

    if (strstr(s, searchstr) == NULL) {
        *result = 0;
    }
    else {
        *result = 1;
    }

    return IB_OK;
}
示例#4
0
/// @test Test util field library - ib_field_create() ib_field_create()
TEST_F(TestIBUtilField, test_field_create)
{
    ib_field_t *f;
    ib_status_t rc;
    const char *nulstrval = "TestValue";
    ib_num_t numval = 5;
    ib_bytestr_t *bytestrval;
    const char *nulout;
    const char *nulcopy;

    nulcopy = ib_mm_strdup(MM(), nulstrval);
    ASSERT_STRNE(NULL, nulcopy);
    rc = ib_field_create(&f, MM(), IB_S2SL("test_nulstr"),
                         IB_FTYPE_NULSTR, ib_ftype_nulstr_in(nulcopy));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(11UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_nulstr", f->name, 11));

    rc = ib_field_value(f, ib_ftype_nulstr_out(&nulout));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_STREQ(nulstrval, nulout);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_num"),
                         IB_FTYPE_NUM, ib_ftype_num_in(&numval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(8UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_num", f->name, 8));

    rc = ib_bytestr_dup_mem(&bytestrval, MM(),
                            (uint8_t *)nulstrval, strlen(nulstrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bytestrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(12UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_bytestr", f->name, 12));

    rc = ib_field_create(&f, MM(), IB_S2SL("test_nulstr_ex"),
                         IB_FTYPE_NULSTR, ib_ftype_nulstr_in(nulstrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_num_ex"),
                         IB_FTYPE_NUM, ib_ftype_num_in(&numval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_bytestr_ex"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bytestrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
}
示例#5
0
const char* ConstField::value_as_null_string() const
{
    Internal::check_type(NULL_STRING, type());
    const char* v;
    throw_if_error(ib_field_value(
        ib(), ib_ftype_nulstr_out(&v)
    ));
    return v;
}
示例#6
0
const char* ConstField::value_as_null_string(
    const char* arg,
    size_t      arg_length
) const
{
    Internal::check_type(NULL_STRING, type());
    const char* v;
    throw_if_error(ib_field_value_ex(
        ib(), ib_ftype_nulstr_out(&v),
        arg, arg_length
    ));
    return v;
}
示例#7
0
文件: field.c 项目: aburan28/ironbee
void ib_field_util_log_debug(
    const char       *prefix,
    const ib_field_t *f
)
{
    assert(prefix != NULL);
    assert(f != NULL);

    ib_status_t rc;

    if (ib_util_get_log_level() < IB_LOG_DEBUG) {
        return;
    }

    if (ib_field_is_dynamic(f)) {
        ib_util_log_debug(
            "%s is dynamic: fn_get=%p cbdata_get=%p fn_set=%p cbdata_set=%p",

          prefix,
            f->val->fn_get, f->val->cbdata_get,
            f->val->fn_set, f->val->cbdata_set
        );
    }

    ib_util_log_debug("%s name=%.*s type=%d",
                      prefix, (int)f->nlen, f->name, f->type
    );

    if (ib_field_is_dynamic(f)) {
        return;
    }

    assert(f->val->pval);

    if (*(void **)(f->val->pval) == NULL) {
        ib_util_log_debug(
            "%s has no value.",
            prefix
        );
    }
    else {
        switch (f->type) {
        case IB_FTYPE_GENERIC:
        {
            void *v;
            rc = ib_field_value(f, ib_ftype_generic_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s value=%p", prefix, v);
            }
            break;
        }
        case IB_FTYPE_NUM:
        {
            ib_num_t v;
            rc = ib_field_value(f, ib_ftype_num_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s value=%"PRId64, prefix, v);
            }
            break;
        }
        case IB_FTYPE_FLOAT:
        {
            ib_float_t v;
            rc = ib_field_value(f, ib_ftype_float_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s value=%Lf", prefix, v);
            }
            break;
        }
        case IB_FTYPE_NULSTR:
        {
            const char *v;
            rc = ib_field_value(f, ib_ftype_nulstr_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s value=%s", prefix, v);
            }
            break;
        }
        case IB_FTYPE_BYTESTR:
        {
            const ib_bytestr_t *v;
            rc = ib_field_value(f, ib_ftype_bytestr_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s value=%" IB_BYTESTR_FMT,
                                  prefix, IB_BYTESTR_FMT_PARAM(v));
            }
            break;
        }
        case IB_FTYPE_LIST:
        {
            const ib_list_t* v;
            rc = ib_field_value(f, ib_ftype_list_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s &value=%p", prefix, v);
            }
            break;
        }
        case IB_FTYPE_SBUFFER:
        {
            const ib_stream_t* v;
            rc = ib_field_value(f, ib_ftype_sbuffer_out(&v));
            if (rc == IB_OK) {
                ib_util_log_debug("%s &value=%p", prefix, v);
            }
            break;
        }
        default:
            ib_util_log_debug("%s Unknown field type: %u",
                              prefix, f->type
            );
        }
    }
}
示例#8
0
文件: field.c 项目: aburan28/ironbee
/**
 * Attempt to convert a single field.
 *
 * If the desired type matches the in_field type, out_field is set to NULL
 * and IB_OK is returned.
 *
 * @param[in,out] mp Memory pool to use.
 * @param[in] desired_type The type to try to convert this to.
 * @param[in] in_field The input field.
 * @param[out] out_field The output field to write to.
 *
 * @returns
 *   - IB_OK On success.
 *   - IB_EINVAL If a string cannot be converted to a number type
 *               or some other invalid type conversion is requested.
 *   - IB_EALLOC Memory allocation error.
 */
ib_status_t ib_field_convert(
    ib_mpool_t *mp,
    const ib_ftype_t desired_type,
    const ib_field_t *in_field,
    ib_field_t **out_field)
{
    assert(mp);
    assert(in_field);

    ib_status_t rc;

    /* Holder values for in_field values before being set in out_field. */
    size_t sz;
    const char *str;
    const ib_bytestr_t *bstr;
    ib_num_t num;
    ib_float_t flt;
    void *new_field_value;


    if (in_field->type == desired_type) {
        *out_field = NULL;
        return IB_OK;
    }

    switch (in_field->type) {
        case IB_FTYPE_NULSTR:

            /* Extract string. */
            rc = ib_field_value(in_field, ib_ftype_nulstr_out(&str));
            if (rc!=IB_OK){
                return rc;
            }

            switch(desired_type) {
                case IB_FTYPE_BYTESTR:
                    rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
                    if (rc!=IB_OK){
                        return rc;
                    }
                    new_field_value = ib_ftype_bytestr_in(bstr);
                    break;
                case IB_FTYPE_NUM:
                    rc = ib_string_to_num(str, 0, &num);
                    new_field_value = ib_ftype_num_in(&num);
                    break;
                case IB_FTYPE_FLOAT:
                    rc = ib_string_to_float(str, &flt);
                    new_field_value = ib_ftype_float_in(&flt);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        case IB_FTYPE_BYTESTR:

            /* Extract bytestr. */
            rc = ib_field_value(in_field, ib_ftype_bytestr_out(&bstr));
            if (rc!=IB_OK){
                return rc;
            }
            sz = ib_bytestr_length(bstr);

            /* Convert byte str. */
            switch(desired_type) {
                case IB_FTYPE_NULSTR:
                    str = ib_mpool_memdup_to_str(mp, bstr, sz);
                    if (!str) {
                        return rc;
                    }
                    new_field_value = ib_ftype_nulstr_in(str);
                    break;
                case IB_FTYPE_NUM:
                    rc = ib_string_to_num_ex((char *)bstr, sz, 0, &num);
                    new_field_value = ib_ftype_num_in(&num);
                    break;
                case IB_FTYPE_FLOAT:
                    rc = ib_string_to_float_ex((char *)bstr, sz, &flt);
                    new_field_value = ib_ftype_float_in(&flt);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        case IB_FTYPE_NUM:

            /* Extract unum. */
            rc = ib_field_value(in_field, ib_ftype_num_out(&num));
            if (rc!=IB_OK){
                return rc;
            }

            switch(desired_type) {
                case IB_FTYPE_NULSTR:
                    str = ib_num_to_string(mp, num);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    new_field_value = ib_ftype_nulstr_in(str);
                    break;
                case IB_FTYPE_BYTESTR:
                    str = ib_num_to_string(mp, num);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
                    if (rc!=IB_OK){
                        return rc;
                    }
                    new_field_value = ib_ftype_bytestr_in(bstr);
                    break;
                case IB_FTYPE_FLOAT:
                    flt = (ib_float_t)num;
                    new_field_value = ib_ftype_float_in(&flt);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        case IB_FTYPE_FLOAT:

            /* Extract unum. */
            rc = ib_field_value(in_field, ib_ftype_float_out(&flt));
            if (rc!=IB_OK){
                return rc;
            }

            switch(desired_type) {
                case IB_FTYPE_NULSTR:
                    str = ib_float_to_string(mp, flt);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    new_field_value = ib_ftype_nulstr_in(str);
                    break;
                case IB_FTYPE_BYTESTR:
                    str = ib_float_to_string(mp, flt);
                    if (!str) {
                        return IB_EINVAL;
                    }
                    rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
                    if (rc!=IB_OK){
                        return rc;
                    }
                    new_field_value = ib_ftype_bytestr_in(bstr);
                    break;
                case IB_FTYPE_NUM:
                    num = (ib_float_t)flt;
                    new_field_value = ib_ftype_num_in(&num);
                    break;
                default:
                    return IB_EINVAL;
            }
            break;
        default:
            return IB_EINVAL;
    }

    rc = ib_field_create(
        out_field,
        mp,
        in_field->name,
        in_field->nlen,
        desired_type,
        new_field_value);
    return rc;
}
示例#9
0
///@test Test util field library - ib_field_dyn_register_get()
TEST_F(TestIBUtilField, test_dyn_field)
{
    ib_field_t *dynf;
    ib_field_t *cdynf;
    ib_status_t rc;
    const char *fval;

    /* Create a field with no initial value. */
    rc = ib_field_create_dynamic(
        &dynf, MM(),
        IB_S2SL("test_dynf"), IB_FTYPE_NULSTR,
        dyn_get, (void *)"dynf_get",
        dyn_set, (void *)"dynf_set"
    );
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(dynf);
    ASSERT_EQ(9UL, dynf->nlen);
    ASSERT_EQ(0, memcmp("test_dynf", dynf->name, 9));

    /* Get the value from the dynamic field. */
    rc = ib_field_value_ex(dynf,
        ib_ftype_nulstr_out(&fval),
        (void *)"fetch1", 6
    );
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(fval);
    ASSERT_EQ(
        std::string("testval_dynf_get_fetch1_call01"),
        fval
    );

    /* Get the value from the dynamic field again. */
    rc = ib_field_value_ex(dynf,
        ib_ftype_nulstr_out(&fval),
        (void *)"fetch2", 6
    );
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(fval);
    ASSERT_EQ(
        std::string("testval_dynf_get_fetch2_call02"),
        fval
    );

    /* Set */
    rc = ib_field_setv_ex(dynf, (void *)"val1", (void *)"set1", 4);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(std::string("testval_dynf_set_set1_val1_call03"), g_dyn_call_val);

    /* Reset call counter. */
    g_dyn_call_count = 0;

    /* Create another field with no initial value. */
    rc = ib_field_create_dynamic(
        &cdynf, MM(),
        IB_S2SL("test_cdynf"), IB_FTYPE_NULSTR,
        dyn_get_cached, (void *)("cdynf_get"),
        dyn_set, NULL
    );
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(cdynf);
    ASSERT_EQ(10UL, cdynf->nlen);
    ASSERT_EQ(0, memcmp("test_cdynf", cdynf->name, 10));

    /* Get the value from the dynamic field. */
    rc = ib_field_value_ex(cdynf,
        ib_ftype_nulstr_out(&fval),
        (void *)"fetch1", 6
    );
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(fval);
    ASSERT_EQ(
        std::string("testval_cdynf_get_fetch1_call01"),
        fval
    );

    /* Get the value from the dynamic field again. */
    rc = ib_field_value_ex(cdynf,
        ib_ftype_nulstr_out(&fval),
        NULL, 0
    );
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(fval);
    ASSERT_EQ(
        std::string("testval_cdynf_get_fetch1_call01"),
        fval
    );
}
示例#10
0
文件: field.c 项目: niubl/ironbee
ib_status_t ib_field_convert(
    ib_mpool_t        *mp,
    const ib_ftype_t   desired_type,
    const ib_field_t  *in_field,
    ib_field_t       **out_field
)
{
    assert(mp);
    assert(in_field);

    ib_status_t rc;

    /* Holder values for in_field values before being set in out_field. */
    size_t sz;
    const char *str;
    const ib_bytestr_t *bstr;
    ib_num_t num;
    ib_time_t tme;
    ib_float_t flt;
    void *new_field_value;

    if (in_field->type == desired_type) {
        *out_field = NULL;
        return IB_OK;
    }

    switch (in_field->type) {
    case IB_FTYPE_NULSTR:

        /* Extract string.  Note that a zero-length nulstr field can
         * have a NULL value in the union. */
        if ( (in_field->val->u.nulstr == NULL) &&
             (in_field->val->pval == NULL) )
        {
            str = "";
        }
        else {
            rc = ib_field_value(in_field, ib_ftype_nulstr_out(&str));
            if (rc != IB_OK){
                return rc;
            }
        }

        switch (desired_type) {
        case IB_FTYPE_BYTESTR:
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_TIME:
            rc = ib_string_to_time(str, &tme);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_NUM:
            rc = ib_string_to_num(str, 0, &num);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_num_in(&num);
            break;
        case IB_FTYPE_FLOAT:
            rc = ib_string_to_float(str, &flt);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_BYTESTR:

        /* Extract bytestr. */
        rc = ib_field_value(in_field, ib_ftype_bytestr_out(&bstr));
        if (rc != IB_OK){
            return rc;
        }
        str = (const char *)ib_bytestr_const_ptr(bstr);
        sz = ib_bytestr_length(bstr);

        /* Convert byte str. */
        switch(desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_mpool_memdup_to_str(mp, str, sz);
            if (!str) {
                return rc;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_TIME:
            rc = ib_string_to_time_ex(str, sz, &tme);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_NUM:
            rc = ib_string_to_num_ex(str, sz, 0, &num);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_num_in(&num);
            break;
        case IB_FTYPE_FLOAT:
            rc = ib_string_to_float_ex(str, sz, &flt);
            if (rc != IB_OK) {
                return rc;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_TIME:

        /* Extract time. */
        rc = ib_field_value(in_field, ib_ftype_time_out(&tme));
        if (rc != IB_OK){
            return rc;
        }

        switch (desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_time_to_string(mp, tme);
            if (! str) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_BYTESTR:
            str = ib_time_to_string(mp, tme);
            if (! str) {
                return IB_EINVAL;
            }
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK){
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_FLOAT:
            flt = (ib_float_t)tme;
            /* Check that our assignment is within error=1, or fail. */
            if (llabs(tme - flt) > 1) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_NUM:

        /* Extract unum. */
        rc = ib_field_value(in_field, ib_ftype_num_out(&num));
        if (rc != IB_OK){
            return rc;
        }

        switch (desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_num_to_string(mp, num);
            if (! str) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_BYTESTR:
            str = ib_num_to_string(mp, num);
            if (! str) {
                return IB_EINVAL;
            }
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK){
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_TIME:
            if (num < 0) {
                return IB_EINVAL;
            }
            tme = (ib_time_t)num;
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_FLOAT:
            flt = (ib_float_t)num;
            if (llabs(flt - num) > 1) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_float_in(&flt);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    case IB_FTYPE_FLOAT:

        /* Extract unum. */
        rc = ib_field_value(in_field, ib_ftype_float_out(&flt));
        if (rc != IB_OK){
            return rc;
        }

        switch (desired_type) {
        case IB_FTYPE_NULSTR:
            str = ib_float_to_string(mp, flt);
            if (!str) {
                return IB_EINVAL;
            }
            new_field_value = ib_ftype_nulstr_in(str);
            break;
        case IB_FTYPE_BYTESTR:
            str = ib_float_to_string(mp, flt);
            if (!str) {
                return IB_EINVAL;
            }
            rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str);
            if (rc != IB_OK){
                return rc;
            }
            new_field_value = ib_ftype_bytestr_in(bstr);
            break;
        case IB_FTYPE_TIME:
            if (flt < 0) {
                return IB_EINVAL;
            }
            tme = (ib_float_t)flt;
            new_field_value = ib_ftype_time_in(&tme);
            break;
        case IB_FTYPE_NUM:
            num = (ib_float_t)flt;
            new_field_value = ib_ftype_num_in(&num);
            break;
        default:
            return IB_EINVAL;
        }
        break;

    default:
        return IB_EINVAL;
    }

    rc = ib_field_create(
        out_field,
        mp,
        in_field->name,
        in_field->nlen,
        desired_type,
        new_field_value
    );
    return rc;
}
示例#11
0
static ib_status_t foo2bar(ib_engine_t *ib,
                           ib_mpool_t *mp,
                           void *fndata,
                           const ib_field_t *fin,
                           const ib_field_t **fout,
                           ib_flags_t *pflags)
{
    ib_status_t rc = IB_OK;
    ib_field_t *fnew;

    if (fin->type == IB_FTYPE_BYTESTR) {
        const ib_bytestr_t *ibs;
        rc = ib_field_value(fin, ib_ftype_bytestr_out(&ibs));
        if (rc != IB_OK) {
            return rc;
        }

        const uint8_t *data_in;
        size_t dlen_in;
        uint8_t *data_out;

        assert (ibs != NULL);

        data_in = ib_bytestr_const_ptr(ibs);
        dlen_in = ib_bytestr_length(ibs);

        if ( (data_in != NULL) &&
             (dlen_in == 3) &&
             (strncmp("foo", (char *)data_in, 3) == 0) )
        {
            data_out = (uint8_t *)ib_mpool_alloc(mp, dlen_in);
            if (data_out == NULL) {
                return IB_EINVAL;
            }
            *pflags = (IB_TFN_FMODIFIED);
            *(data_out+0) = 'b';
            *(data_out+1) = 'a';
            *(data_out+2) = 'r';
        }
        else {
            data_out = (uint8_t *)data_in;
        }
        rc = ib_field_create_bytestr_alias(&fnew, mp,
                                           fin->name, fin->nlen,
                                           data_out, dlen_in);
        if (rc == IB_OK) {
            *fout = fnew;
        }
    }
    else if (fin->type == IB_FTYPE_NULSTR) {
        const char *in;
        char *out;

        rc = ib_field_value(fin, ib_ftype_nulstr_out(&in));
        if (rc != IB_OK) {
            return rc;
        }
        if ( (in != NULL) && (strncmp(in, "foo", 3) == 0) ) {
            out = (char *)ib_mpool_alloc(mp, strlen(in) + 1);
            if (out == NULL) {
                return IB_EINVAL;
            }

            *pflags = (IB_TFN_FMODIFIED);
            *(out+0) = 'b';
            *(out+1) = 'a';
            *(out+2) = 'r';
            *(out+3) = '\0';
        }
        else {
            out = (char *)in;
        }
        rc = ib_field_create(&fnew, mp, fin->name, fin->nlen,
                             IB_FTYPE_NULSTR, ib_ftype_nulstr_in(out));
        if (rc == IB_OK) {
            *fout = fnew;
        }
    }
    else {
        return IB_EINVAL;
    }

    return rc;
}
示例#12
0
/**
 * Length transformation
 *
 * @param[in] ib IronBee engine
 * @param[in] mp Memory pool to use for allocations.
 * @param[in] fndata Function specific data.
 * @param[in] fin Input field.
 * @param[out] fout Output field.
 * @param[out] pflags Transformation flags.
 *
 * @returns IB_OK if successful.
 */
static ib_status_t tfn_length(ib_engine_t *ib,
                              ib_mpool_t *mp,
                              void *fndata,
                              const ib_field_t *fin,
                              ib_field_t **fout,
                              ib_flags_t *pflags)
{
    IB_FTRACE_INIT();
    ib_status_t rc = IB_OK;

    assert(mp != NULL);
    assert(fin != NULL);
    assert(fout != NULL);
    assert(pflags != NULL);

    /**
     * This works on C-style (NUL terminated) and byte strings.  Note
     * that data is assumed to be a NUL terminated string (because our
     * configuration parser can't produce anything else).
     **/
    if (fin->type == IB_FTYPE_NULSTR) {
        const char *fval;
        rc = ib_field_value(fin, ib_ftype_nulstr_out(&fval));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        const ib_unum_t len = strlen(fval);
        rc = ib_field_create(
            fout, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_UNUM,
            ib_ftype_unum_in(&len)
        );
    }
    else if (fin->type == IB_FTYPE_BYTESTR) {
        const ib_bytestr_t *value;
        rc = ib_field_value(fin, ib_ftype_bytestr_out(&value));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        const ib_unum_t len = ib_bytestr_length(value);
        rc = ib_field_create(
            fout, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_UNUM,
            ib_ftype_unum_in(&len)
        );
    }
    else if (fin->type == IB_FTYPE_LIST) {
        const ib_list_node_t  *node = NULL;
        const ib_list_t       *ilist;        /** Incoming list */

        /* Get the incoming list */
        // @todo Remove mutable once list is const correct.
        rc = ib_field_value(fin, ib_ftype_list_out(&ilist));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        if (ilist == NULL) {
            IB_FTRACE_RET_STATUS(IB_EUNKNOWN);
        }

        /* Create the outgoing list field */
        rc = ib_field_create(
            fout, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_LIST, NULL
        );
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        /* Walk through the incoming fields */
        IB_LIST_LOOP_CONST(ilist, node) {
            const ib_field_t *ifield = (ib_field_t *)node->data;
            ib_field_t *ofield = NULL;
            ib_flags_t flags = 0;

            rc = tfn_length(ib, mp, NULL, ifield, &ofield, &flags);
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
            rc = ib_field_list_add(*fout, ofield);
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else {
示例#13
0
/**
 * @brief Execute the rule.
 *
 * @param[in] ib Ironbee engine
 * @param[in] tx The transaction.
 * @param[in,out] User data. A @c pcre_rule_data_t.
 * @param[in] flags Operator instance flags
 * @param[in] field The field content.
 * @param[out] result The result.
 * @returns IB_OK most times. IB_EALLOC when a memory allocation error handles.
 */
static ib_status_t dfa_operator_execute(ib_engine_t *ib,
                                        ib_tx_t *tx,
                                        const ib_rule_t *rule,
                                        void *data,
                                        ib_flags_t flags,
                                        ib_field_t *field,
                                        ib_num_t *result)
{
    IB_FTRACE_INIT();
    assert(tx);
    assert(data);


    int matches;
    ib_status_t ib_rc;
    const int ovecsize = 3 * MATCH_MAX;
    dfa_rule_data_t *rule_data;
    int *ovector;
    const char* subject;
    size_t subject_len;
    const ib_bytestr_t* bytestr;
    dfa_workspace_t *dfa_workspace;
    int options; /* dfa exec options. */

    ovector = (int *)malloc(ovecsize*sizeof(*ovector));
    if (ovector==NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Pull out the rule data. */
    rule_data = (dfa_rule_data_t *)data;


    if (field->type == IB_FTYPE_NULSTR) {
        ib_rc = ib_field_value(field, ib_ftype_nulstr_out(&subject));
        if (ib_rc != IB_OK) {
            free(ovector);
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        subject_len = strlen(subject);
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        ib_rc = ib_field_value(field, ib_ftype_bytestr_out(&bytestr));
        if (ib_rc != IB_OK) {
            free(ovector);
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        subject_len = ib_bytestr_length(bytestr);
        subject = (const char *) ib_bytestr_const_ptr(bytestr);
    }
    else {
        free(ovector);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Debug block. Escapes a string and prints it to the log.
     * Memory is freed. */
    if (ib_log_get_level(ib) >= 9) {

        /* Worst case, we can have a string that is 4x larger.
         * Consider if a string of 0xF7 is passed.  That single character
         * will expand to a string of 4 printed characters +1 for the \0
         * character. */
        char *debug_str = ib_util_hex_escape(subject, subject_len);

        if ( debug_str != NULL ) {
            ib_log_debug3_tx(tx, "Matching against: %s", debug_str);
            free( debug_str );
        }
    }

    /* Get the per-tx workspace data for this rule data id. */
    ib_rc = get_dfa_tx_data(tx, rule_data->id, &dfa_workspace);
    if (ib_rc == IB_ENOENT) {
        options = PCRE_PARTIAL_SOFT;

        ib_rc = alloc_dfa_tx_data(tx, rule_data->id, &dfa_workspace);
        if (ib_rc != IB_OK) {
            free(ovector);
            ib_log_error_tx(tx, "Unexpected error creating tx storage "
                                "for dfa operator %s",
                                rule_data->id);
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        ib_log_debug_tx(tx,
                       "Created DFA workspace at %p for id %s.",
                        dfa_workspace,
                        rule_data->id);
    }
    else if (ib_rc == IB_OK) {
        options = PCRE_PARTIAL_SOFT | PCRE_DFA_RESTART;
        ib_log_debug_tx(tx,
                        "Reusing existing DFA workspace %p for id %s.",
                        dfa_workspace,
                        rule_data->id);
    }
    else {
        free(ovector);
        ib_log_error_tx(tx,
                        "Unexpected error fetching dfa data "
                        "for dfa operator %s",
                        rule_data->id);
        IB_FTRACE_RET_STATUS(ib_rc);
    }

    /* Actually do the DFA match. */
    matches = pcre_dfa_exec(rule_data->cpatt,
                            rule_data->edata,
                            subject,
                            subject_len,
                            0, /* Starting offset. */
                            options,
                            ovector,
                            ovecsize,
                            dfa_workspace->workspace,
                            dfa_workspace->wscount);

    if (matches >= 0) {
        ib_rc = IB_OK;
        *result = 1;
    }
    else if (matches == PCRE_ERROR_PARTIAL) {
        ib_log_debug2_tx(tx, "Partial match found, but not a full match.");
        ib_rc = IB_OK;
        *result = 0;
    }
    else if (matches == PCRE_ERROR_NOMATCH) {

        if (ib_log_get_level(ib) >= 7) {
            char* tmp_c = malloc(subject_len+1);
            memcpy(tmp_c, subject, subject_len);
            tmp_c[subject_len] = '\0';
            /* No match. Return false to the caller (*result = 0). */
            ib_log_debug2_tx(tx, "No match for [%s] using pattern [%s].",
                        tmp_c,
                        rule_data->patt);
            free(tmp_c);
        }

        ib_rc = IB_OK;
        *result = 0;
    }
    else {
        /* Some other error occurred. Set the status to false and
        report the error. */
        ib_rc = IB_EUNKNOWN;
        *result = 0;
    }

    free(ovector);
    IB_FTRACE_RET_STATUS(ib_rc);
}
示例#14
0
文件: core_tfns.c 项目: niubl/ironbee
/**
 * Length transformation
 *
 * @param[in] mp Memory pool to use for allocations.
 * @param[in] fin Input field.
 * @param[out] fout Output field. This is NULL on error.
 * @param[in] fndata Callback data
 *
 * @returns IB_OK if successful.
 */
static ib_status_t tfn_length(ib_mpool_t *mp,
                              const ib_field_t *fin,
                              const ib_field_t **fout,
                              void *fndata)
{
    assert(mp != NULL);
    assert(fin != NULL);
    assert(fout != NULL);

    ib_status_t rc = IB_OK;
    ib_field_t *fnew;

    /* Initialize the output field pointer */
    *fout = NULL;

    /**
     * This works on C-style (NUL terminated) and byte strings.  Note
     * that data is assumed to be a NUL terminated string (because our
     * configuration parser can't produce anything else).
     **/
    if (fin->type == IB_FTYPE_NULSTR) {
        const char *fval;
        rc = ib_field_value(fin, ib_ftype_nulstr_out(&fval));
        if (rc != IB_OK) {
            return rc;
        }

        const ib_num_t len = strlen(fval);
        rc = ib_field_create(
            &fnew, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_NUM,
            ib_ftype_num_in(&len)
        );
    }
    else if (fin->type == IB_FTYPE_BYTESTR) {
        const ib_bytestr_t *value;
        rc = ib_field_value(fin, ib_ftype_bytestr_out(&value));
        if (rc != IB_OK) {
            return rc;
        }

        const ib_num_t len = ib_bytestr_length(value);
        rc = ib_field_create(
            &fnew, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_NUM,
            ib_ftype_num_in(&len)
        );
    }
    else if (fin->type == IB_FTYPE_LIST) {
        const ib_list_node_t  *node = NULL;
        const ib_list_t       *ilist;        /** Incoming list */

        /* Get the incoming list */
        // @todo Remove mutable once list is const correct.
        rc = ib_field_value(fin, ib_ftype_list_out(&ilist));
        if (rc != IB_OK) {
            return rc;
        }

        if (ilist == NULL) {
            return IB_EUNKNOWN;
        }

        /* Create the outgoing list field */
        rc = ib_field_create(
            &fnew, mp,
            IB_FIELD_NAME("Length"),
            IB_FTYPE_LIST, NULL
        );
        if (rc != IB_OK) {
            return rc;
        }

        /* Walk through the incoming fields */
        IB_LIST_LOOP_CONST(ilist, node) {
            const ib_field_t *ifield = (ib_field_t *)node->data;
            const ib_field_t *ofield = NULL;

            rc = tfn_length(mp, ifield, &ofield, NULL);
            if (rc != IB_OK) {
                return rc;
            }
            rc = ib_field_list_add_const(fnew, ofield);
            if (rc != IB_OK) {
                return rc;
            }
        }
    }
    else {
示例#15
0
文件: ee_oper.c 项目: B0SB05/ironbee
/**
 * Helper function for stream and non-stream execution.
 *
 *
 *
 * @param[in] tx Transaction
 * @param[in] operator_data Operator data.
 * @param[in] data Per-transaction data for this operator instance.
 * @param[in] field Input field.
 * @param[in] full_match If true, the full input text must be matched.
 * @param[out] result Result of execution.
 */
static
ib_status_t ee_operator_execute_common(
    ib_tx_t *tx,
    ee_operator_data_t *operator_data,
    ee_tx_data_t *data,
    const ib_field_t *field,
    bool full_match,
    ib_num_t *result
)
{
    ib_status_t rc;
    ia_eudoxus_result_t ia_rc;
    ia_eudoxus_state_t* state = NULL;
    const char *input;
    size_t input_len;

    assert(tx != NULL);
    assert(operator_data != NULL);
    assert(data != NULL);

    *result = 0;

    if (field->type == IB_FTYPE_NULSTR) {
        rc = ib_field_value(field, ib_ftype_nulstr_out(&input));
        if (rc != IB_OK) {
            return rc;
        }
        input_len = strlen(input);
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        const ib_bytestr_t *bs;
        rc = ib_field_value(field, ib_ftype_bytestr_out(&bs));
        if (rc != IB_OK) {
            return rc;
        }
        input = (const char *)ib_bytestr_const_ptr(bs);
        input_len = ib_bytestr_length(bs);
    }
    else if (field->type == IB_FTYPE_LIST) {
        return IB_ENOTIMPL;
    }
    else {
        return IB_EINVAL;
    }

    if (data->end_of_automata) {
        /* Nothing to do. */
        return IB_OK;
    }

    /* Run eudoxus */
    state = data->eudoxus_state;
    rc = IB_OK;

    ia_rc = ia_eudoxus_execute(state, (const uint8_t *)input, input_len);
    if (ia_rc == IA_EUDOXUS_STOP) {
        if (full_match) {
            if (data->ee_cbdata->match_len == input_len) {
                *result = 1;
            }
        }
        else {
            *result = 1;
        }
        rc = IB_OK;
    }
    else if (ia_rc == IA_EUDOXUS_END) {
        data->end_of_automata = true;
        rc = IB_OK;
    }
    else if (ia_rc != IA_EUDOXUS_OK) {
        rc = IB_EUNKNOWN;
    }

    return rc;
}
示例#16
0
文件: expand.c 项目: moon2l/ironbee
/**
 * Join a field with strings before and after it
 *
 * @param[in] mp Memory pool
 * @param[in] f Field to join
 * @param[in] iptr Pointer to initial string
 * @param[in] ilen Length of @a iptr
 * @param[in] fptr Pointer to final string
 * @param[in] flen Length of @a fptr
 * @param[in] nul true if NUL byte should be tacked on, false if not
 * @param[out] out Pointer to output block
 * @param[out] olen Length of the output block
 *
 * @returns status code
 */
static ib_status_t join_parts(ib_mpool_t *mp,
                              const ib_field_t *f,
                              const char *iptr,
                              size_t ilen,
                              const char *fptr,
                              size_t flen,
                              bool nul,
                              char **out,
                              size_t *olen)
{
    IB_FTRACE_INIT();
    ib_status_t rc;
    char numbuf[NUM_BUF_LEN+1]; /* Buffer used to convert number to str */
    assert(NUM_BUF_LEN <= 256);

    switch(f->type) {
    case IB_FTYPE_NULSTR:
    {
        /* Field is a NUL-terminated string */
        const char *s;
        rc = ib_field_value(f, ib_ftype_nulstr_out(&s));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        size_t slen = strlen(s);
        rc = join3(mp,
                   iptr, ilen,
                   s, slen,
                   fptr, flen,
                   nul,
                   out, olen);
        break;
    }

    case IB_FTYPE_BYTESTR:
    {
        /* Field is a byte string */
        const ib_bytestr_t *bs;
        rc = ib_field_value(f, ib_ftype_bytestr_out(&bs));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        rc = join3(mp,
                   iptr, ilen,
                   (const char *)ib_bytestr_const_ptr(bs),
                   ib_bytestr_length(bs),
                   fptr, flen,
                   nul,
                   out, olen);
        break;
    }

    case IB_FTYPE_NUM:
    {
        /* Field is a number; convert it to a string */
        ib_num_t n;
        rc = ib_field_value(f, ib_ftype_num_out(&n));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        snprintf(numbuf, NUM_BUF_LEN, "%"PRId64, n);
        rc = join3(mp,
                   iptr, ilen,
                   numbuf, strlen(numbuf),
                   fptr, flen,
                   nul,
                   out, olen);
        break;
    }

    case IB_FTYPE_UNUM:
    {
        /* Field is an unsigned number; convert it to a string */
        ib_unum_t n;
        rc = ib_field_value(f, ib_ftype_unum_out(&n));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        snprintf(numbuf, NUM_BUF_LEN, "%"PRIu64, n);
        rc = join3(mp,
                   iptr, ilen,
                   numbuf, strlen(numbuf),
                   fptr, flen,
                   nul,
                   out, olen);
        break;
    }

    case IB_FTYPE_LIST:
    {
        /* Field is a list: use the first element in the list */
        const ib_list_t *list;
        const ib_list_node_t *node;
        const ib_field_t *element;

        rc = ib_field_value(f, ib_ftype_list_out(&list));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        node = ib_list_first_const(list);
        if (node == NULL) {
            rc = join2(mp, iptr, ilen, fptr, flen, nul, out, olen);
            break;
        }

        element = (const ib_field_t *)ib_list_node_data_const(node);
        rc = join_parts(mp, element, iptr, ilen, fptr, flen, nul, out, olen);
        break;
    }

    default:
        /* Something else: replace with "" */
        rc = join2(mp, iptr, ilen, fptr, flen, nul, out, olen);
        break;
    }

    IB_FTRACE_RET_STATUS(rc);
}
示例#17
0
/**
 * String modification transformation core
 *
 * @param[in] ib IronBee engine
 * @param[in] mp Memory pool to use for allocations.
 * @param[in] fndata Function specific data.
 * @param[in] fin Input field.
 * @param[out] fout Output field.
 * @param[out] pflags Transformation flags.
 *
 * @returns IB_OK if successful.
 */
static ib_status_t tfn_strmod(ib_engine_t *ib,
                              ib_mpool_t *mp,
                              ib_strmod_fn_t str_fn,
                              ib_strmod_ex_fn_t ex_fn,
                              const ib_field_t *fin,
                              ib_field_t **fout,
                              ib_flags_t *pflags)
{
    IB_FTRACE_INIT();
    ib_status_t rc;
    ib_flags_t result;

    assert(ib != NULL);
    assert(mp != NULL);
    assert(str_fn != NULL);
    assert(ex_fn != NULL);
    assert(fin != NULL);
    assert(fout != NULL);
    assert(pflags != NULL);

    /* Initialize the output field pointer */
    *fout = NULL;

    switch(fin->type) {
    case IB_FTYPE_NULSTR :
    {
        const char *in;
        char *out;
        rc = ib_field_value(fin, ib_ftype_nulstr_out(&in));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        if (in == NULL) {
            IB_FTRACE_RET_STATUS(IB_EINVAL);
        }
        rc = str_fn(IB_STROP_COW, mp, (char *)in, &out, &result);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        rc = ib_field_create(fout, mp,
                             fin->name, fin->nlen,
                             IB_FTYPE_NULSTR,
                             ib_ftype_nulstr_in(out));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        break;
    }

    case IB_FTYPE_BYTESTR:
    {
        const ib_bytestr_t *bs;
        const uint8_t *din;
        uint8_t *dout;
        size_t dlen;
        rc = ib_field_value(fin, ib_ftype_bytestr_out(&bs));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        if (bs == NULL) {
            IB_FTRACE_RET_STATUS(IB_EINVAL);
        }
        din = ib_bytestr_const_ptr(bs);
        if (din == NULL) {
            IB_FTRACE_RET_STATUS(IB_EINVAL);
        }
        dlen = ib_bytestr_length(bs);
        rc = ex_fn(IB_STROP_COW, mp,
                   (uint8_t *)din, dlen,
                   &dout, &dlen,
                   &result);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        rc = ib_field_create_bytestr_alias(fout, mp,
                                           fin->name, fin->nlen,
                                           dout, dlen);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
        break;
    }
    default:
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    } /* switch(fin->type) */

    /* Check the flags */
    if (ib_flags_all(result, IB_STRFLAG_MODIFIED) == true) {
        *pflags = IB_TFN_FMODIFIED;
    }
    else {
        *pflags = IB_TFN_NONE;
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
示例#18
0
文件: field.c 项目: aburan28/ironbee
const char *ib_field_format(
    const ib_field_t  *field,
    bool               quote,
    bool               escape,
    const char       **type_name,
    char              *buf,
    size_t             bufsize
)
{
    ib_status_t rc;
    const char *tname = NULL;

    assert(buf != NULL);
    assert(bufsize > 0);

    *buf = '\0';
    if (field == NULL) {
        tname = "NULL";
        if (quote) {
            strncpy(buf, "\"\"", bufsize-1);
            *(buf+bufsize) = '\0';
        }
        else {
            *buf = '\0';
        }
    }
    else {
        switch (field->type) {

        case IB_FTYPE_NULSTR :
        {
            const char *s;
            tname = "NULSTR";
            rc = ib_field_value(field, ib_ftype_nulstr_out(&s));
            if (rc != IB_OK) {
                break;
            }
            if (escape) {
                ib_string_escape_json_buf(s, quote, buf, bufsize, NULL, NULL);
            }
            else if (quote) {
                snprintf(buf, bufsize, "\"%s\"", (s?s:""));
            }
            else {
                strncpy(buf, s, bufsize-1);
                *(buf+bufsize-1) = '\0';
            }
            break;
        }

        case IB_FTYPE_BYTESTR:
        {
            const ib_bytestr_t *bs;

            tname = "BYTESTR";
            rc = ib_field_value(field, ib_ftype_bytestr_out(&bs));
            if (rc != IB_OK) {
                break;
            }

            if (escape) {
                ib_string_escape_json_buf_ex(ib_bytestr_const_ptr(bs),
                                             ib_bytestr_length(bs),
                                             true,
                                             quote,
                                             buf, bufsize, NULL,
                                             NULL);
            }
            else if (quote) {
                snprintf(buf, bufsize, "\"%.*s\"",
                         (int)ib_bytestr_length(bs),
                         (const char *)ib_bytestr_const_ptr(bs));
            }
            else {
                size_t len = ib_bytestr_length(bs);
                if (len > (bufsize - 1) ) {
                    len = bufsize - 1;
                }
                strncpy(buf, (const char *)ib_bytestr_const_ptr(bs), len);
                *(buf+len) = '\0';
            }
            break;
        }

        case IB_FTYPE_NUM :          /**< Numeric value */
        {
            ib_num_t n;
            tname = "NUM";
            rc = ib_field_value(field, ib_ftype_num_out(&n));
            if (rc != IB_OK) {
                break;
            }
            snprintf(buf, bufsize, "%"PRId64, n);
            break;
        }

        case IB_FTYPE_FLOAT :        /**< Float numeric value */
        {
            ib_float_t f;
            tname = "FLOAT";
            rc = ib_field_value(field, ib_ftype_float_out(&f));
            if (rc != IB_OK) {
                break;
            }
            snprintf(buf, bufsize, "%Lf", f);
            break;
        }

        case IB_FTYPE_LIST :         /**< List */
        {
            const ib_list_t *lst;
            size_t len;

            tname = "LIST";
            rc = ib_field_value(field, ib_ftype_list_out(&lst));
            if (rc != IB_OK) {
                break;
            }
            len = IB_LIST_ELEMENTS(lst);
            if (len == 0) {
                snprintf(buf, bufsize, "list[%zd]", len);
            }
            else {
                const ib_list_node_t *node;
                node = ib_list_last_const(lst);
                if (node == NULL) {
                    snprintf(buf, bufsize, "list[%zd]", len);
                }
                else {
                    ib_field_format((const ib_field_t *)node->data,
                                    quote, escape,
                                    &tname, buf, bufsize);
                }
            }
            break;
        }

        default:
            tname = buf;
            snprintf(buf, bufsize, "type = %d", field->type);
            break;
        }
    }

    /* Store the type name */
    if (type_name != NULL) {
        *type_name = tname;
    }

    /* Return the buffer */
    return buf;
}
示例#19
0
文件: ee_oper.c 项目: niubl/ironbee
/**
 * Execute the @c ee_match_any operator.
 *
 * At first match the operator will stop searching and return true.
 *
 * The capture option is supported; the matched pattern will be placed in the
 * capture variable if a match occurs.
 *
 * @param[in] tx Current transaction.
 * @param[in] instance_data Instance data needed for execution.
 * @param[in] field The field to operate on.
 * @param[in] capture If non-NULL, the collection to capture to.
 * @param[out] result The result of the operator 1=true 0=false.
 * @param[in] cbdata Callback data.
 */
static
ib_status_t ee_match_any_operator_execute(
    ib_tx_t *tx,
    void *instance_data,
    const ib_field_t *field,
    ib_field_t *capture,
    ib_num_t *result,
    void *cbdata
)
{
    ib_status_t rc;
    ia_eudoxus_result_t ia_rc;
    ee_operator_data_t *operator_data = instance_data;
    ia_eudoxus_t* eudoxus = operator_data->eudoxus;
    ia_eudoxus_state_t* state = NULL;
    const char *input;
    size_t input_len;
    ee_callback_data_t *ee_cbdata;
    const ib_module_t *m = (const ib_module_t *)cbdata;

    assert(m != NULL);
    assert(tx != NULL);
    assert(instance_data != NULL);

    *result = 0;

    if (field->type == IB_FTYPE_NULSTR) {
        rc = ib_field_value(field, ib_ftype_nulstr_out(&input));
        if (rc != IB_OK) {
            return rc;
        }
        input_len = strlen(input);
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        const ib_bytestr_t *bs;
        rc = ib_field_value(field, ib_ftype_bytestr_out(&bs));
        if (rc != IB_OK) {
            return rc;
        }
        input = (const char *)ib_bytestr_const_ptr(bs);
        input_len = ib_bytestr_length(bs);
    }
    else if (field->type == IB_FTYPE_LIST) {
        return IB_ENOTIMPL;
    }
    else {
        return IB_EINVAL;
    }

    rc = get_ee_tx_data(m, tx, operator_data, &state);
    if (rc == IB_ENOENT) {
        /* State not found create it */
        ee_cbdata = ib_mpool_alloc(tx->mp, sizeof(*ee_cbdata));
        if (ee_cbdata == NULL) {
            return IB_EALLOC;
        }
        ee_cbdata->tx = tx;
        ee_cbdata->capture = capture;
        ia_rc = ia_eudoxus_create_state(&state,
                                        eudoxus,
                                        ee_first_match_callback,
                                        (void *)ee_cbdata);
        if (ia_rc != IA_EUDOXUS_OK) {
            if (state != NULL) {
                ia_eudoxus_destroy_state(state);
                state = NULL;
            }
            return IB_EINVAL;
        }
        set_ee_tx_data(m, tx, operator_data, state);
    }
    else if (rc != IB_OK) {
        /* Error getting the state -- abort */
        return rc;
    }

    rc = IB_OK;

    ia_rc = ia_eudoxus_execute(state, (const uint8_t *)input, input_len);
    if (ia_rc == IA_EUDOXUS_STOP) {
        *result = 1;
        rc = IB_OK;
    }
    else if (ia_rc == IA_EUDOXUS_ERROR) {
        rc = IB_EUNKNOWN;
    }

    return rc;
}
示例#20
0
文件: pcre.c 项目: niubl/ironbee
/**
 * @brief Execute the dfa operator
 *
 * @param[in] tx Current transaction.
 * @param[in] instance_data Instance data needed for execution.
 * @param[in] field The field to operate on.
 * @param[in] capture If non-NULL, the collection to capture to.
 * @param[out] result The result of the operator 1=true 0=false.
 * @param[in] cbdata Callback data.
 *
 * @returns IB_OK most times. IB_EALLOC when a memory allocation error handles.
 */
static
ib_status_t dfa_operator_execute(
    ib_tx_t *tx,
    void *instance_data,
    const ib_field_t *field,
    ib_field_t *capture,
    ib_num_t *result,
    void *cbdata
)
{
    assert(instance_data != NULL);
    assert(tx            != NULL);

    int matches;
    ib_status_t ib_rc;
    const int ovecsize = 3 * MATCH_MAX;
    modpcre_operator_data_t *operator_data =
        (modpcre_operator_data_t *)instance_data;
    int *ovector;
    const char *subject;
    size_t subject_len;
    const ib_bytestr_t *bytestr;
    dfa_workspace_t *dfa_workspace;
    const char *id = operator_data->id;
    int options; /* dfa exec options. */
    int start_offset;
    int match_count;
    const ib_module_t *m = (const ib_module_t *)cbdata;

    assert(m != NULL);
    assert(operator_data->cpdata->is_dfa == true);

    ovector = (int *)malloc(ovecsize*sizeof(*ovector));
    if (ovector==NULL) {
        return IB_EALLOC;
    }

    if (field->type == IB_FTYPE_NULSTR) {
        ib_rc = ib_field_value(field, ib_ftype_nulstr_out(&subject));
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }

        subject_len = strlen(subject);
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        ib_rc = ib_field_value(field, ib_ftype_bytestr_out(&bytestr));
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }

        subject_len = ib_bytestr_length(bytestr);
        subject = (const char *) ib_bytestr_const_ptr(bytestr);
    }
    else {
        free(ovector);
        return IB_EINVAL;
    }

    /* Get the per-tx workspace data for this rule data id. */
    ib_rc = get_dfa_tx_data(m, tx, id, &dfa_workspace);
    if (ib_rc == IB_ENOENT) {
        /* First time we are called, clear the captures. */
        if (capture) {
            ib_rc = ib_capture_clear(capture);
            if (ib_rc != IB_OK) {
                ib_log_error_tx(tx, "Error clearing captures: %s",
                                ib_status_to_string(ib_rc));
            }
        }

        options = PCRE_PARTIAL_SOFT;

        ib_rc = alloc_dfa_tx_data(m, tx, operator_data->cpdata, id, &dfa_workspace);
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }
    }
    else if (ib_rc == IB_OK) {
        options = PCRE_PARTIAL_SOFT | PCRE_DFA_RESTART;
    }
    else {
        free(ovector);
        return ib_rc;
    }

    /* Perform the match.
     * If capturing is specified, then find all matches.
     */
    start_offset = 0;
    match_count = 0;
    do {
        matches = pcre_dfa_exec(operator_data->cpdata->cpatt,
                                operator_data->cpdata->edata,
                                subject,
                                subject_len,
                                start_offset, /* Starting offset. */
                                options,
                                ovector,
                                ovecsize,
                                dfa_workspace->workspace,
                                dfa_workspace->wscount);

        if (matches > 0) {
            ++match_count;

            /* Use the longest match - the first in ovector -
             * to set the offset in the subject for the next
             * match.
             */
            start_offset = ovector[1] + 1;
            if (capture) {
                pcre_dfa_set_match(tx, capture, ovector, 1, subject);
            }
        }
    } while (capture && (matches > 0));

    if (match_count > 0) {
        ib_rc = IB_OK;
        *result = 1;
    }
    else if ((matches == 0) || (matches == PCRE_ERROR_NOMATCH)) {
        ib_rc = IB_OK;
        *result = 0;
    }
    else if (matches == PCRE_ERROR_PARTIAL) {
        ib_rc = IB_OK;
        *result = 0;
    }
    else {
        /* Some other error occurred. Set the status to false and
         * return the error. */
        ib_rc = IB_EUNKNOWN;
        *result = 0;
    }

    free(ovector);
    return ib_rc;
}
示例#21
0
/**
 * JSON YAJL encode: Encode a list
 *
 * @param[in,out] handle YAJL generator handle
 * @param[in] name Name of @a list (or NULL)
 * @param[in] nlen Length of @a name
 * @param[in] list IronBee list to encode
 *
 * @returns IronBee status code
 */
static ib_status_t encode_list(
    yajl_gen         handle,
    const char      *name,
    size_t           nlen,
    const ib_list_t *list)
{
    ib_status_t           rc = IB_OK;
    const ib_list_node_t *node;
    yajl_gen_status       status;
    int                   errors = 0;

    /* Encode the name */
    if ( (name != NULL) && (nlen != 0) ) {
        status = yajl_gen_string(handle, (const unsigned char *)name, nlen);
        if (status != yajl_gen_status_ok) {
            return IB_EUNKNOWN;
        }
    }

    /* Encode the map start */
    status = yajl_gen_map_open(handle);
    if (status != yajl_gen_status_ok) {
        return IB_EUNKNOWN;
    }

    IB_LIST_LOOP_CONST(list, node) {
        const ib_field_t *field = (const ib_field_t *)node->data;
        ib_status_t       tmprc;

        status = yajl_gen_string(handle,
                                 (const unsigned char *)field->name,
                                 field->nlen);
        if (status != yajl_gen_status_ok) {
            rc = IB_EUNKNOWN;
            ++errors;
            continue;
        }

        switch(field->type) {
        case IB_FTYPE_LIST:
        {
            const ib_list_t *list2;
            tmprc = ib_field_value(field, ib_ftype_list_out(&list2));
            if ( (tmprc != IB_OK) && (rc == IB_OK) ) {
                rc = tmprc;
                ++errors;
            }
            else {
                tmprc = encode_list(handle, NULL, 0, list2);
                if ( (tmprc != IB_OK) && (rc == IB_OK) ) {
                    rc = tmprc;
                    ++errors;
                }
            }
            break;
        }

        case IB_FTYPE_NUM:
        {
            ib_num_t num;
            tmprc = ib_field_value(field, ib_ftype_num_out(&num));
            if ( (tmprc != IB_OK) && (rc == IB_OK) ) {
                rc = tmprc;
                ++errors;
            }
            else {
                status = yajl_gen_integer(handle, num);
                if (status != yajl_gen_status_ok) {
                    if (rc != IB_OK) {
                        rc = IB_EUNKNOWN;
                    }
                    ++errors;
                }
            }
            break;
        }

        case IB_FTYPE_FLOAT:
        {
            ib_float_t fnum;
            tmprc = ib_field_value(field, ib_ftype_float_out(&fnum));
            if ( (tmprc != IB_OK) && (rc == IB_OK) ) {
                rc = tmprc;
                ++errors;
            }
            else {
                char buf[float_buf_size+1];
                snprintf(buf, float_buf_size, "%#.8Lg", fnum);
                status = yajl_gen_number(handle, buf, strlen(buf));
                if (status != yajl_gen_status_ok) {
                    if (rc != IB_OK) {
                        rc = IB_EUNKNOWN;
                    }
                    ++errors;
                }
            }
            break;
        }

        case IB_FTYPE_NULSTR:
        {
            const char *str;
            tmprc = ib_field_value(field, ib_ftype_nulstr_out(&str));
            if ( (tmprc != IB_OK) && (rc == IB_OK) ) {
                rc = tmprc;
                ++errors;
            }
            else {
                status = yajl_gen_string(handle,
                                         (unsigned char *)str,
                                         strlen(str));
                if (status != yajl_gen_status_ok) {
                    if (rc != IB_OK) {
                        rc = IB_EUNKNOWN;
                    }
                    ++errors;
                }
            }
            break;
        }

        case IB_FTYPE_BYTESTR:
        {
            const ib_bytestr_t *bs;
            tmprc = ib_field_value(field, ib_ftype_bytestr_out(&bs));
            if ( (tmprc != IB_OK) && (rc == IB_OK) ) {
                rc = tmprc;
                ++errors;
            }
            else {
                status = yajl_gen_string(handle,
                                         ib_bytestr_const_ptr(bs),
                                         ib_bytestr_length(bs));
                if (status != yajl_gen_status_ok) {
                    if (rc != IB_OK) {
                        rc = IB_EUNKNOWN;
                    }
                    ++errors;
                }
            }
            break;
        }

        default: /* Just ignore it */
            break;

        } /* switch(f->type) */
    }

    /* Encode the map end */
    status = yajl_gen_map_close(handle);
    if (status != yajl_gen_status_ok) {
        return IB_EUNKNOWN;
    }

    return IB_OK;
}
示例#22
0
文件: core_tfns.c 项目: niubl/ironbee
/**
 * String modification transformation core
 *
 * @param[in] mp Memory pool to use for allocations.
 * @param[in] str_fn NUL-terminated string transformation function
 * @param[in] ex_fn EX (string/length) transformation function
 * @param[in] fin Input field.
 * @param[out] fout Output field. This is NULL on error.
 *
 * @returns IB_OK if successful.
 */
static ib_status_t tfn_strmod(ib_mpool_t *mp,
                              ib_strmod_fn_t str_fn,
                              ib_strmod_ex_fn_t ex_fn,
                              const ib_field_t *fin,
                              const ib_field_t **fout)
{
    ib_status_t rc;
    ib_flags_t result;
    ib_field_t *fnew;

    assert(mp != NULL);
    assert(str_fn != NULL);
    assert(ex_fn != NULL);
    assert(fin != NULL);
    assert(fout != NULL);

    /* Initialize the output field pointer */
    *fout = NULL;

    switch(fin->type) {
    case IB_FTYPE_NULSTR :
    {
        const char *in;
        char *out;
        rc = ib_field_value(fin, ib_ftype_nulstr_out(&in));
        if (rc != IB_OK) {
            return rc;
        }
        if (in == NULL) {
            return IB_EINVAL;
        }
        rc = str_fn(IB_STROP_COW, mp, (char *)in, &out, &result);
        if (rc != IB_OK) {
            return rc;
        }
        rc = ib_field_create(&fnew, mp,
                             fin->name, fin->nlen,
                             IB_FTYPE_NULSTR,
                             ib_ftype_nulstr_in(out));
        if (rc != IB_OK) {
            return rc;
        }
        *fout = fnew;
        break;
    }

    case IB_FTYPE_BYTESTR:
    {
        const ib_bytestr_t *bs;
        const uint8_t *din;
        uint8_t *dout;
        size_t dlen;
        rc = ib_field_value(fin, ib_ftype_bytestr_out(&bs));
        if (rc != IB_OK) {
            return rc;
        }
        if (bs == NULL) {
            return IB_EINVAL;
        }
        din = ib_bytestr_const_ptr(bs);
        if (din == NULL) {
            return IB_EINVAL;
        }
        dlen = ib_bytestr_length(bs);
        rc = ex_fn(IB_STROP_COW, mp,
                   (uint8_t *)din, dlen,
                   &dout, &dlen,
                   &result);
        if (rc != IB_OK) {
            return rc;
        }
        rc = ib_field_create_bytestr_alias(&fnew, mp,
                                           fin->name, fin->nlen,
                                           dout, dlen);
        if (rc != IB_OK) {
            return rc;
        }
        *fout = fnew;
        break;
    }

    default:
        return IB_EINVAL;
    } /* switch(fin->type) */

    return IB_OK;
}
示例#23
0
文件: pcre.c 项目: niubl/ironbee
/**
 * @brief Execute the PCRE operator
 *
 * @param[in] tx Current transaction.
 * @param[in] instance_data Instance data needed for execution.
 * @param[in] field The field to operate on.
 * @param[in] capture If non-NULL, the collection to capture to.
 * @param[out] result The result of the operator 1=true 0=false.
 * @param[in] cbdata Callback data.
 *
 * @returns IB_OK most times. IB_EALLOC when a memory allocation error handles.
 */
static
ib_status_t pcre_operator_execute(
    ib_tx_t *tx,
    void *instance_data,
    const ib_field_t *field,
    ib_field_t *capture,
    ib_num_t *result,
    void *cbdata
)
{
    assert(instance_data != NULL);
    assert(tx            != NULL);

    int matches;
    ib_status_t ib_rc;
    const int ovecsize = 3 * MATCH_MAX;
    int *ovector = (int *)malloc(ovecsize*sizeof(*ovector));
    const char *subject = NULL;
    size_t subject_len = 0;
    const ib_bytestr_t *bytestr;
    modpcre_operator_data_t *operator_data =
        (modpcre_operator_data_t *)instance_data;
    pcre_extra *edata = NULL;
#ifdef PCRE_JIT_STACK
    pcre_jit_stack *jit_stack = NULL;
#endif

    assert(operator_data->cpdata->is_dfa == false);

    if (ovector==NULL) {
        return IB_EALLOC;
    }

    if (field->type == IB_FTYPE_NULSTR) {
        ib_rc = ib_field_value(field, ib_ftype_nulstr_out(&subject));
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }

        if (subject != NULL) {
            subject_len = strlen(subject);
        }
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        ib_rc = ib_field_value(field, ib_ftype_bytestr_out(&bytestr));
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }

        if (bytestr != NULL) {
            subject_len = ib_bytestr_length(bytestr);
            subject = (const char *) ib_bytestr_const_ptr(bytestr);
        }
    }
    else {
        free(ovector);
        return IB_EINVAL;
    }

    if (subject == NULL) {
        subject     = "";
    }

    if (operator_data->cpdata->is_jit) {
#ifdef PCRE_JIT_STACK
        jit_stack = pcre_jit_stack_alloc(operator_data->cpdata->jit_stack_start,
                                         operator_data->cpdata->jit_stack_max);
        if (jit_stack == NULL) {
            ib_log_warn(ib,
                "Failed to allocate a jit stack for a jit-compiled rule.  "
                "Not using jit for this call."
            );
        }
        /* If the study data is NULL or size zero, don't use it. */
        else if (operator_data->cpdata->study_data_sz > 0) {
            edata = operator_data->cpdata->edata;
        }
        if (edata != NULL) {
            pcre_assign_jit_stack(edata, NULL, jit_stack);
        }
#else
        edata = NULL;
#endif
    }
    else if (operator_data->cpdata->study_data_sz > 0) {
        edata = operator_data->cpdata->edata;
    }
    else {
        edata = NULL;
    }

    matches = pcre_exec(operator_data->cpdata->cpatt,
                        edata,
                        subject,
                        subject_len,
                        0, /* Starting offset. */
                        0, /* Options. */
                        ovector,
                        ovecsize);

#ifdef PCRE_JIT_STACK
    if (jit_stack != NULL) {
        pcre_jit_stack_free(jit_stack);
    }
#endif

    if (matches > 0) {
        if (capture != NULL) {
            pcre_set_matches(tx, capture, ovector, matches, subject);
        }
        ib_rc = IB_OK;
        *result = 1;
    }
    else if (matches == PCRE_ERROR_NOMATCH) {
        ib_rc = IB_OK;
        *result = 0;
    }
    else {
        /* Some other error occurred. Set the status to false return the
         * error. */
        ib_rc = IB_EUNKNOWN;
        *result = 0;
    }

    free(ovector);
    return ib_rc;
}
示例#24
0
/**
 * @brief Execute the rule.
 *
 * @param[in] ib Ironbee engine
 * @param[in] tx The transaction.
 * @param[in,out] User data. A @c pcre_rule_data_t.
 * @param[in] flags Operator instance flags
 * @param[in] field The field content.
 * @param[out] result The result.
 * @returns IB_OK most times. IB_EALLOC when a memory allocation error handles.
 */
static ib_status_t pcre_operator_execute(ib_engine_t *ib,
                                         ib_tx_t *tx,
                                         const ib_rule_t *rule,
                                         void *data,
                                         ib_flags_t flags,
                                         ib_field_t *field,
                                         ib_num_t *result)
{
    IB_FTRACE_INIT();

    assert(ib!=NULL);
    assert(tx!=NULL);
    assert(tx->dpi!=NULL);
    assert(data!=NULL);

    int matches;
    ib_status_t ib_rc;
    const int ovecsize = 3 * MATCH_MAX;
    int *ovector = (int *)malloc(ovecsize*sizeof(*ovector));
    const char* subject = NULL;
    size_t subject_len = 0;
    const ib_bytestr_t* bytestr;
    pcre_rule_data_t *rule_data = (pcre_rule_data_t *)data;
    pcre_extra *edata = NULL;
#ifdef PCRE_JIT_STACK
    pcre_jit_stack *jit_stack = pcre_jit_stack_alloc(PCRE_JIT_MIN_STACK_SZ,
                                                     PCRE_JIT_MAX_STACK_SZ);
#endif

    if (ovector==NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    if (field->type == IB_FTYPE_NULSTR) {
        ib_rc = ib_field_value(field, ib_ftype_nulstr_out(&subject));
        if (ib_rc != IB_OK) {
            free(ovector);
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        if (subject != NULL) {
            subject_len = strlen(subject);
        }
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        ib_rc = ib_field_value(field, ib_ftype_bytestr_out(&bytestr));
        if (ib_rc != IB_OK) {
            free(ovector);
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        if (bytestr != NULL) {
            subject_len = ib_bytestr_length(bytestr);
            subject = (const char *) ib_bytestr_const_ptr(bytestr);
        }
    }
    else {
        free(ovector);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    if (subject == NULL) {
        subject     = "";
    }

    /* Debug block. Escapes a string and prints it to the log.
     * Memory is freed. */
    if (ib_log_get_level(ib) >= 9) {

        /* Worst case, we can have a string that is 4x larger.
         * Consider if a string of 0xF7 is passed.  That single character
         * will expand to a string of 4 printed characters +1 for the \0
         * character. */
        char *debug_str = ib_util_hex_escape(subject, subject_len);

        if ( debug_str != NULL ) {
            ib_log_debug3_tx(tx, "Matching against: %s", debug_str);
            free( debug_str );
        }
    }

#ifdef PCRE_JIT_STACK
    /* Log if we expected jit, but did not get it. */
    if (rule_data->is_jit && jit_stack == NULL) {
        ib_log_debug(ib,
                     "Failed to allocate a jit stack for a jit-compiled rule. "
                     "Not using jit for this call.");
        edata = NULL;
    }

    /* If the study data is NULL or size zero, don't use it. */
    else if (rule_data->edata == NULL || rule_data->study_data_sz <= 0) {
        edata = NULL;
    }

    /* Only if we get here do we use the study data (edata) in the rule_data. */
    else {
        edata = rule_data->edata;
        pcre_assign_jit_stack(rule_data->edata, NULL, jit_stack);
    }

#endif

    matches = pcre_exec(rule_data->cpatt,
                        edata,
                        subject,
                        subject_len,
                        0, /* Starting offset. */
                        0, /* Options. */
                        ovector,
                        ovecsize);

#ifdef PCRE_JIT_STACK
    if (jit_stack != NULL) {
        pcre_jit_stack_free(jit_stack);
    }
#endif

    if (matches > 0) {
        if (ib_flags_all(rule->flags, IB_RULE_FLAG_CAPTURE) == true) {
            pcre_set_matches(ib, tx, ovector, matches, subject);
        }
        ib_rc = IB_OK;
        *result = 1;
    }
    else if (matches == PCRE_ERROR_NOMATCH) {

        if (ib_log_get_level(ib) >= 7) {
            char* tmp_c = malloc(subject_len+1);
            memcpy(tmp_c, subject, subject_len);
            tmp_c[subject_len] = '\0';
            /* No match. Return false to the caller (*result = 0). */
            ib_log_debug2_tx(tx, "No match for [%s] using pattern [%s].",
                        tmp_c,
                        rule_data->patt);
            free(tmp_c);
        }


        ib_rc = IB_OK;
        *result = 0;
    }
    else {
        /* Some other error occurred. Set the status to false and
        report the error. */
        ib_rc = IB_EUNKNOWN;
        *result = 0;
    }

    free(ovector);
    IB_FTRACE_RET_STATUS(ib_rc);
}
示例#25
0
文件: pcre.c 项目: nickleroy/ironbee
/**
 * @brief Execute the rule.
 *
 * @param[in] ib Ironbee engine
 * @param[in] tx The transaction.
 * @param[in,out] User data. A @c pcre_rule_data_t.
 * @param[in] flags Operator instance flags
 * @param[in] field The field content.
 * @param[in] result The result.
 * @returns IB_OK most times. IB_EALLOC when a memory allocation error handles.
 */
static ib_status_t pcre_operator_execute(ib_engine_t *ib,
                                         ib_tx_t *tx,
                                         void *data,
                                         ib_flags_t flags,
                                         ib_field_t *field,
                                         ib_num_t *result)
{
    IB_FTRACE_INIT();

    assert(ib!=NULL);
    assert(tx!=NULL);
    assert(tx->dpi!=NULL);
    assert(data!=NULL);

    int matches;
    ib_status_t ib_rc;
    const int ovecsize = 3 * MATCH_MAX;
    int *ovector = (int *)malloc(ovecsize*sizeof(*ovector));
    const char* subject;
    size_t subject_len;
    const ib_bytestr_t* bytestr;
    pcre_rule_data_t *rule_data = (pcre_rule_data_t *)data;
    pcre *regex;
    pcre_extra *regex_extra = NULL;
#ifdef PCRE_JIT_STACK
    pcre_jit_stack *jit_stack = pcre_jit_stack_alloc(PCRE_JIT_MIN_STACK_SZ,
                                                     PCRE_JIT_MAX_STACK_SZ);
#endif

    if (ovector==NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    if (field->type == IB_FTYPE_NULSTR) {
        ib_rc = ib_field_value(field, ib_ftype_nulstr_out(&subject));
        if (ib_rc != IB_OK) {
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        subject_len = strlen(subject);
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        ib_rc = ib_field_value(field, ib_ftype_bytestr_out(&bytestr));
        if (ib_rc != IB_OK) {
            IB_FTRACE_RET_STATUS(ib_rc);
        }

        subject_len = ib_bytestr_length(bytestr);
        subject = (const char *) ib_bytestr_const_ptr(bytestr);
    }
    else {
        free(ovector);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Debug block. Escapes a string and prints it to the log.
     * Memory is freed. */
    if (ib_log_get_level(ib) >= 9) {

        /* Worst case, we can have a string that is 4x larger.
         * Consider if a string of 0xF7 is passed.  That single character
         * will expand to a string of 4 printed characters +1 for the \0
         * character. */
        char *debug_str = ib_util_hex_escape(subject, subject_len);

        if ( debug_str != NULL ) {
            ib_log_debug3_tx(tx, "Matching against: %s", debug_str);
            free( debug_str );
        }
    }

    /* Alloc space to copy regex. */
    regex = (pcre *)malloc(rule_data->cpatt_sz);

    if (regex == NULL ) {
        free(ovector);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    memcpy(regex, rule_data->cpatt, rule_data->cpatt_sz);

    if (rule_data->study_data_sz == 0 ) {
        regex_extra = NULL;
    }
    else {
        regex_extra = (pcre_extra *) malloc(sizeof(*regex_extra));

        if (regex_extra == NULL ) {
            free(ovector);
            free(regex);
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }
        *regex_extra = *rule_data->edata;

        if ( rule_data->study_data_sz == 0 ) {
            regex_extra->study_data = NULL;
        }
        else {
            regex_extra->study_data = malloc(rule_data->study_data_sz);

            if (regex_extra->study_data == NULL ) {
                free(ovector);
                if (regex_extra != NULL) {
                    free(regex_extra);
                }
                free(regex);
                IB_FTRACE_RET_STATUS(IB_EALLOC);
            }

            memcpy(regex_extra->study_data,
                   rule_data->edata->study_data,
                   rule_data->study_data_sz);
        }

        /* Put some modest limits on our regex. */
        regex_extra->match_limit = 1000;
        regex_extra->match_limit_recursion = 1000;
        regex_extra->flags = regex_extra->flags |
                            PCRE_EXTRA_MATCH_LIMIT |
                            PCRE_EXTRA_MATCH_LIMIT_RECURSION;
    }

#ifdef PCRE_JIT_STACK
    if (jit_stack == NULL) {
        if ( regex_extra != NULL ) {
            if ( regex_extra->study_data != NULL ) {
                free(regex_extra->study_data);
            }

            free(regex_extra);
        }
        free(ovector);
        free(regex);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    pcre_assign_jit_stack(regex_extra, NULL, jit_stack);
#endif

    matches = pcre_exec(regex,
                        regex_extra,
                        subject,
                        subject_len,
                        0, /* Starting offset. */
                        0, /* Options. */
                        ovector,
                        ovecsize);

#ifdef PCRE_JIT_STACK
    pcre_jit_stack_free(jit_stack);
#endif

    if (matches > 0) {
        pcre_set_matches(ib, tx, "TX", ovector, matches, subject);
        ib_rc = IB_OK;
        *result = 1;
    }
    else if (matches == PCRE_ERROR_NOMATCH) {

        if (ib_log_get_level(ib) >= 7) {
            char* tmp_c = malloc(subject_len+1);
            memcpy(tmp_c, subject, subject_len);
            tmp_c[subject_len] = '\0';
            /* No match. Return false to the caller (*result = 0). */
            ib_log_debug2_tx(tx, "No match for [%s] using pattern [%s].",
                        tmp_c,
                        rule_data->patt);
            free(tmp_c);
        }


        ib_rc = IB_OK;
        *result = 0;
    }
    else {
        /* Some other error occurred. Set the status to false and
        report the error. */
        ib_rc = IB_EUNKNOWN;
        *result = 0;
    }

    if ( regex_extra != NULL ) {
        if ( regex_extra->study_data != NULL ) {
            free(regex_extra->study_data);
        }

        free(regex_extra);
    }
    free(ovector);
    free(regex);
    IB_FTRACE_RET_STATUS(ib_rc);
}