// Test pattern matching a field. TEST(TestIronBee, test_data_pcre) { ib_engine_t *ib; ib_data_config_t *dataconfig; ib_data_t *data; ib_field_t *list_field; ib_field_t *out_field; ib_list_t *list; ib_list_t *out_list; ib_field_t *field1; ib_field_t *field2; ib_field_t *field3; ib_num_t num1 = 1; ib_num_t num2 = 2; ib_num_t num3 = 3; ibtest_engine_create(&ib); ASSERT_EQ(IB_OK, ib_data_config_create(ib_engine_pool_main_get(ib), & dataconfig)); ASSERT_EQ(IB_OK, ib_data_create(dataconfig, ib_engine_pool_main_get(ib), &data)); ASSERT_TRUE(data); ASSERT_IB_OK( ib_field_create(&field1, ib_data_pool(data), "field1", 6, IB_FTYPE_NUM, &num1)); ASSERT_IB_OK( ib_field_create(&field2, ib_data_pool(data), "field2", 6, IB_FTYPE_NUM, &num2)); ASSERT_IB_OK( ib_field_create(&field3, ib_data_pool(data), "field3", 6, IB_FTYPE_NUM, &num3)); ASSERT_IB_OK(ib_data_add_list(data, "ARGV", &list_field)); ASSERT_IB_OK(ib_data_get(data, "ARGV", &out_field)); ASSERT_IB_OK(ib_field_value(list_field, &list)); ASSERT_IB_OK(ib_list_push(list, field1)); ASSERT_IB_OK(ib_list_push(list, field2)); ASSERT_IB_OK(ib_list_push(list, field3)); ASSERT_IB_OK(ib_data_get(data, "ARGV:/.*(1|3)/", &out_field)); ASSERT_IB_OK(ib_field_value(out_field, &out_list)); ASSERT_NE(list, out_list); /* Make sure it's a different list. */ ASSERT_EQ(2U, IB_LIST_ELEMENTS(out_list)); out_field = (ib_field_t *) IB_LIST_FIRST(out_list)->data; ASSERT_FALSE(memcmp(out_field->name, field1->name, field1->nlen)); out_field = (ib_field_t *) IB_LIST_LAST(out_list)->data; ASSERT_FALSE(memcmp(out_field->name, field3->name, field3->nlen)); ibtest_engine_destroy(ib); }
/// @test Test ironbee library - transformation registration TEST(TestIronBee, test_tfn) { ib_engine_t *ib; ib_status_t rc; ib_tfn_t *tfn = (ib_tfn_t *)-1; ib_flags_t flags; uint8_t data_in[128]; ib_field_t *fin; const ib_field_t *fout; ib_bytestr_t *bs; ibtest_engine_create(&ib); ASSERT_EQ(IB_OK, ib_tfn_register(ib, "foo2bar", foo2bar, IB_TFN_FLAG_NONE, NULL)); ASSERT_EQ(IB_OK, ib_tfn_lookup(ib, "foo2bar", &tfn)); ASSERT_NE((ib_tfn_t *)-1, tfn); ASSERT_TRUE(tfn); ib_bytestr_dup_nulstr(&bs, ib->mp, "foo"); fin = NULL; ib_field_create( &fin, ib->mp, IB_FIELD_NAME("ByteStr"), IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs) ); fout = NULL; flags = 0; rc = ib_tfn_transform(ib, ib->mp, tfn, fin, &fout, &flags); ASSERT_EQ(rc, IB_OK); ASSERT_NE((ib_tfn_t *)-1, tfn); ASSERT_TRUE(IB_TFN_CHECK_FMODIFIED(flags)); ASSERT_NE(fin, fout); strcpy((char *)data_in, "foo"); fin = NULL; ib_field_create( &fin, ib->mp, IB_FIELD_NAME("NulStr"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in((char *)data_in) ); fout = NULL; flags = 0; rc = ib_tfn_transform(ib, ib->mp, tfn, fin, &fout, &flags); ASSERT_EQ(rc, IB_OK); ASSERT_NE((ib_tfn_t *)-1, tfn); ASSERT_TRUE(IB_TFN_CHECK_FMODIFIED(flags)); ASSERT_NE(fin, fout); ibtest_engine_destroy(ib); }
static ib_status_t dyn_get( const ib_field_t *f, void *out_value, const void *arg, size_t alen, void *data ) { ib_mpool_t *mp = (ib_mpool_t *)data; ib_num_t numval = 5; ib_field_t *newf; ib_status_t rc; ib_list_t *l; const char* carg = (const char *)arg; rc = ib_list_create(&l, mp); if (rc != IB_OK) { return rc; } rc = ib_field_create(&newf, mp, carg, alen, IB_FTYPE_NUM, ib_ftype_num_in(&numval)); if (rc != IB_OK) { return rc; } rc = ib_list_push(l, newf); *(void**)out_value = l; return IB_OK; }
/// @test Test util field library - ib_field_format() with numeric types TEST_F(TestIBUtilField, test_field_format_num) { ib_field_t *f; ib_status_t rc; char fmtbuf[32]; ib_num_t num; const char *tname; const char *buf; num = -10; rc = ib_field_create(&f, MemPool(), IB_FIELD_NAME("test_num"), IB_FTYPE_NUM, ib_ftype_num_in(&num)); ASSERT_EQ(IB_OK, rc); ASSERT_TRUE(f); buf = ib_field_format(f, false, false, &tname, fmtbuf, sizeof(fmtbuf)); ASSERT_STREQ("-10", fmtbuf); ASSERT_STREQ("NUM", tname); ASSERT_EQ(buf, fmtbuf); buf = ib_field_format(f, true, true, &tname, fmtbuf, sizeof(fmtbuf)); ASSERT_STREQ("-10", fmtbuf); ASSERT_STREQ("NUM", tname); ASSERT_EQ(buf, fmtbuf); }
static void core_gen_tx_numeric_field(ib_tx_t *tx, const char *name, ib_num_t val) { ib_field_t *f; assert(tx != NULL); assert(name != NULL); ib_num_t num = val; ib_status_t rc = ib_field_create(&f, tx->mp, name, strlen(name), IB_FTYPE_NUM, &num); if (rc != IB_OK) { ib_log_warning(tx->ib, "Failed to create \"%s\" field: %s", name, ib_status_to_string(rc)); return; } rc = ib_data_add(tx->data, f); if (rc != IB_OK) { ib_log_warning_tx(tx, "Failed add \"%s\" field to transaction data store: %s", name, ib_status_to_string(rc) ); } }
/** * Set the matches from a multi-match dfa as a list in the CAPTURE * collection (all with "0" key). * * @param[in] tx Current transaction. * @param[in] capture Collection to capture to. * @param[in] ovector The vector of integer pairs of matches from PCRE. * @param[in] matches The number of matches. * @param[in] subject The matched-against string data. * * @returns IB_OK or IB_EALLOC. */ static ib_status_t pcre_dfa_set_match( ib_tx_t *tx, ib_field_t *capture, int *ovector, int matches, const char *subject ) { assert(tx != NULL); assert(tx->ib != NULL); assert(capture != NULL); assert(ovector != NULL); int i; /* We have a match! Now populate TX:0-9 in tx->data. */ ib_log_debug2_tx(tx, "DFA populating %d matches", matches); for (i = 0; i < matches; ++i) { size_t match_len; const char *match_start; const char *name; ib_bytestr_t *bs; ib_field_t *field; ib_status_t rc; /* Readability. Mark the start and length of the string. */ match_start = subject+ovector[i * 2]; match_len = ovector[i * 2 + 1] - ovector[i * 2]; /* Create a byte-string representation */ rc = ib_bytestr_dup_mem(&bs, tx->mp, (const uint8_t*)match_start, match_len); if (rc != IB_OK) { return rc; } /* Create a field to hold the byte-string */ name = ib_capture_name(0); rc = ib_field_create(&field, tx->mp, name, strlen(name), IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs)); if (rc != IB_OK) { return rc; } /* Add it to the capture collection */ rc = ib_capture_add_item(capture, field); if (rc != IB_OK) { return rc; } } return IB_OK; }
ib_status_t ib_action_inst_create_ex( ib_engine_t *ib, const char *name, const char *parameters, ib_action_inst_t **act_inst) { assert(ib != NULL); assert(name != NULL); ib_hash_t *action_hash = ib->actions; ib_action_t *action; ib_status_t rc; ib_mpool_t *mpool = ib_engine_pool_main_get(ib); assert(mpool != NULL); rc = ib_hash_get(action_hash, &action, name); if (rc != IB_OK) { /* name is not registered */ return rc; } *act_inst = (ib_action_inst_t *)ib_mpool_alloc(mpool, sizeof(ib_action_inst_t)); if (*act_inst == NULL) { return IB_EALLOC; } (*act_inst)->action = action; (*act_inst)->params = ib_mpool_strdup(mpool, parameters); (*act_inst)->fparam = NULL; if (action->fn_create != NULL) { rc = action->fn_create( ib, parameters, *act_inst, action->cbdata_create ); if (rc != IB_OK) { return rc; } } else { rc = IB_OK; } if ((*act_inst)->fparam == NULL) { rc = ib_field_create(&((*act_inst)->fparam), mpool, IB_FIELD_NAME("param"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(parameters)); } return rc; }
/** * Eudoxus first match callback function. Called when a match occurs. * * Always returns IA_EUDOXUS_CMD_STOP to stop matching (unless an * error occurs). If capture is enabled the matched text will be stored in the * capture variable. * * @param[in] engine Eudoxus engine. * @param[in] output Output defined by automata. * @param[in] output_length Length of output. * @param[in] input Current location in the input (first character * after the match). * @param[in,out] cbdata Pointer to the ee_callback_data_t instance we are * handling. This is needed for handling capture * of the match. * @return IA_EUDOXUS_CMD_ERROR on error, IA_EUDOXUS_CMD_STOP otherwise. */ static ia_eudoxus_command_t ee_first_match_callback(ia_eudoxus_t* engine, const char *output, size_t output_length, const uint8_t *input, void *cbdata) { assert(cbdata != NULL); assert(output != NULL); ib_status_t rc; uint32_t match_len; const ee_callback_data_t *ee_cbdata = cbdata; ib_tx_t *tx = ee_cbdata->tx; ib_field_t *capture = ee_cbdata->capture; ib_bytestr_t *bs; ib_field_t *field; const char *name; assert(tx != NULL); if (capture != NULL) { if (output_length != sizeof(uint32_t)) { return IA_EUDOXUS_CMD_ERROR; } match_len = *(uint32_t *)(output); rc = ib_capture_clear(capture); if (rc != IB_OK) { ib_log_error_tx(tx, "Error clearing captures: %s", ib_status_to_string(rc)); return IA_EUDOXUS_CMD_ERROR; } /* Create a byte-string representation */ rc = ib_bytestr_dup_mem(&bs, tx->mp, (input - match_len), match_len); if (rc != IB_OK) { return IA_EUDOXUS_CMD_ERROR; } name = ib_capture_name(0); rc = ib_field_create(&field, tx->mp, name, strlen(name), IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs)); if (rc != IB_OK) { return IA_EUDOXUS_CMD_ERROR; } rc = ib_capture_set_item(capture, 0, tx->mp, field); if (rc != IB_OK) { return IA_EUDOXUS_CMD_ERROR; } } return IA_EUDOXUS_CMD_STOP; }
TEST_F(TestIronBeeModuleRulesLua, operator_test) { const ib_operator_t *op; void *instance_data; ib_num_t result; ib_field_t* field1; const char* op_name = "test_module_rules_lua.lua"; const char* rule_name = "luarule001"; char* str1 = (char *)ib_mpool_strdup(ib_engine->mp, "string 1"); ASSERT_TRUE(str1); // Create field 1. ASSERT_EQ(IB_OK, ib_field_create( &field1, ib_engine->mp, IB_FIELD_NAME("field1"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(str1) ) ); /* Configure the operator. */ configureIronBee(); // Ensure that the operator exists. ASSERT_EQ(IB_OK, ib_operator_lookup(ib_engine, op_name, &op) ); ASSERT_EQ(IB_OK, ib_operator_inst_create(op, ib_context_main(ib_engine), IB_OP_CAPABILITY_NON_STREAM, rule_name, &instance_data)); performTx(); // Attempt to match. ASSERT_EQ(IB_OK, ib_operator_inst_execute(op, instance_data, ib_tx, field1, NULL, &result)); // This time we should succeed. ASSERT_TRUE(result); }
/// @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); }
TEST_F(CoreOperatorsTest, NeTest) { ib_status_t status; ib_num_t call_result; ib_operator_inst_t *op; ib_rule_t *rule = NULL; /* Not used by this operator. */ status = ib_operator_inst_create(ib_engine, NULL, rule, IB_OP_FLAG_PHASE, "ne", "1", IB_OPINST_FLAG_NONE, &op); ASSERT_EQ(IB_OK, status); // call contains ib_field_t *field; const ib_num_t matching = 2; const ib_num_t nonmatching = 1; ib_field_create( &field, ib_engine_pool_main_get(ib_engine), IB_FIELD_NAME("testfield"), IB_FTYPE_NUM, ib_ftype_num_in(&matching) ); ib_rule_exec_t rule_exec; memset(&rule_exec, 0, sizeof(rule_exec)); rule_exec.ib = ib_engine; rule_exec.tx = ib_tx; rule_exec.rule = rule; ib_field_setv(field, ib_ftype_num_in(&matching)); status = ib_operator_execute(&rule_exec, op, field, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(1, call_result); ib_field_setv(field, ib_ftype_num_in(&nonmatching)); status = ib_operator_execute(&rule_exec, op, field, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(0, call_result); }
TEST_F(CoreOperatorsTest, ContainsTest) { ib_status_t status; ib_num_t call_result; ib_operator_inst_t *op; ib_rule_t *rule = NULL; /* Not used by this operator. */ status = ib_operator_inst_create(ib_engine, NULL, rule, IB_OP_FLAG_PHASE, "contains", "needle", IB_OPINST_FLAG_NONE, &op); ASSERT_EQ(IB_OK, status); // call contains ib_field_t *field; const char *matching = "data with needle in it"; const char *nonmatching = "non matching string"; ib_field_create( &field, ib_engine_pool_main_get(ib_engine), IB_FIELD_NAME("testfield"), IB_FTYPE_NULSTR, NULL ); ib_rule_exec_t rule_exec; memset(&rule_exec, 0, sizeof(rule_exec)); rule_exec.ib = ib_engine; rule_exec.rule = rule; ib_field_setv(field, ib_ftype_nulstr_in(matching)); status = ib_operator_execute(&rule_exec, op, field, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(1, call_result); ib_field_setv(field, ib_ftype_nulstr_in(nonmatching)); status = ib_operator_execute(&rule_exec, op, field, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(0, call_result); }
/** * Store a field in the agent list * * Creates a new field and adds it to the agent list field list. * * @param[in] ib IronBee object * @param[in,out] mp Memory pool to allocate from * @param[in] agent_list Field to add the field to * @param[in] name Field name * @param[in] value Field value * * @returns Status code */ static ib_status_t modua_store_field(ib_engine_t *ib, ib_mpool_t *mp, ib_field_t *agent_list, const char *name, const char *value) { IB_FTRACE_INIT(); ib_field_t *tmp_field = NULL; ib_status_t rc = IB_OK; /* No value? Do nothing */ if (value == NULL) { ib_log_debug3(ib, "No %s field in user agent", name); IB_FTRACE_RET_STATUS(IB_OK); } /* Create the field */ rc = ib_field_create( &tmp_field, mp, IB_FIELD_NAME(name), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(value) ); if (rc != IB_OK) { ib_log_alert(ib, "Error creating user agent %s field: %s", name, ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(rc); } /* Add the field to the list */ rc = ib_field_list_add(agent_list, tmp_field); if (rc != IB_OK) { ib_log_alert(ib, "Error adding user agent %s field: %s", name, ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(rc); } ib_log_debug3(ib, "Stored user agent %s '%s'", name, value); IB_FTRACE_RET_STATUS(IB_OK); }
static void core_gen_tx_numeric(ib_tx_t *tx, const char *name, ib_num_t val) { assert(tx != NULL); assert(name != NULL); ib_field_t *f; ib_num_t num = val; ib_status_t rc; ib_var_source_t *source; rc = ib_field_create(&f, tx->mp, name, strlen(name), IB_FTYPE_NUM, &num); if (rc != IB_OK) { ib_log_warning_tx(tx, "Failed to create \"%s\" field: %s", name, ib_status_to_string(rc)); return; } rc = ib_var_source_acquire( &source, tx->mp, ib_var_store_config(tx->var_store), name, strlen(name) ); if (rc != IB_OK) { ib_log_warning_tx(tx, "Failed to acquire \"%s\" var: %s", name, ib_status_to_string(rc)); return; } rc = ib_var_source_set(source, tx->var_store, f); if (rc != IB_OK) { ib_log_warning_tx(tx, "Failed add \"%s\" var to transaction: %s", name, ib_status_to_string(rc) ); } }
TEST_F(CoreOperatorsTest, ContainsTest) { ib_status_t status; ib_num_t call_result; const ib_operator_t *op; void *instance_data; status = ib_operator_lookup(ib_engine, "contains", &op); ASSERT_EQ(IB_OK, status); status = ib_operator_inst_create(op, ib_context_main(ib_engine), IB_OP_CAPABILITY_NON_STREAM, "needle", &instance_data); ASSERT_EQ(IB_OK, status); // call contains ib_field_t *field; const char *matching = "data with needle in it"; const char *nonmatching = "non matching string"; ib_field_create( &field, ib_engine_pool_main_get(ib_engine), IB_FIELD_NAME("testfield"), IB_FTYPE_NULSTR, NULL ); ib_field_setv(field, ib_ftype_nulstr_in(matching)); status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(1, call_result); ib_field_setv(field, ib_ftype_nulstr_in(nonmatching)); status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(0, call_result); }
Field create_field( MemoryPool pool, const char* name, size_t name_length, Field::type_e type, void* in_value ) { ib_field_t* f = NULL; ib_status_t rc = ib_field_create( &f, pool.ib(), name, name_length, static_cast<ib_ftype_t>(type), in_value ); throw_if_error(rc); return Field(f); }
TEST_F(CoreOperatorsTest, NeTest) { ib_status_t status; ib_num_t call_result; const ib_operator_t *op; void *instance_data; status = ib_operator_lookup(ib_engine, "ne", &op); ASSERT_EQ(IB_OK, status); status = ib_operator_inst_create(op, ib_context_main(ib_engine), IB_OP_CAPABILITY_NON_STREAM, "1", &instance_data); ASSERT_EQ(IB_OK, status); // call contains ib_field_t *field; const ib_num_t matching = 2; const ib_num_t nonmatching = 1; ib_field_create( &field, ib_engine_pool_main_get(ib_engine), IB_FIELD_NAME("testfield"), IB_FTYPE_NUM, ib_ftype_num_in(&matching) ); ib_field_setv(field, ib_ftype_num_in(&matching)); status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(1, call_result); ib_field_setv(field, ib_ftype_num_in(&nonmatching)); status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(0, call_result); }
TEST_F(OperatorTest, OperatorCallTest) { ib_status_t status; ib_num_t call_result; void *instance_data; ib_operator_t *op; const ib_operator_t *cop; status = ib_operator_create_and_register( &op, ib_engine, "test_op", IB_OP_CAPABILITY_NON_STREAM, test_create_fn, NULL, NULL, NULL, test_execute_fn, NULL ); ASSERT_EQ(IB_OK, status); status = ib_operator_lookup(ib_engine, "test_op", &cop); ASSERT_EQ(IB_OK, status); status = ib_operator_inst_create(op, ib_context_main(ib_engine), IB_OP_CAPABILITY_NON_STREAM, "INVALID", &instance_data); ASSERT_EQ(IB_EINVAL, status); status = ib_operator_inst_create(op, ib_context_main(ib_engine), IB_OP_CAPABILITY_NON_STREAM, "data", &instance_data); ASSERT_EQ(IB_OK, status); ib_field_t *field; const char *matching = "data matching string"; const char *nonmatching = "non matching string"; ib_field_create( &field, ib_engine_pool_main_get(ib_engine), IB_FIELD_NAME("testfield"), IB_FTYPE_NULSTR, NULL ); ib_field_setv(field, ib_ftype_nulstr_in(matching)); status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(1, call_result); ib_field_setv(field, ib_ftype_nulstr_in(nonmatching)); status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result); ASSERT_EQ(IB_OK, status); EXPECT_EQ(0, call_result); status = ib_operator_inst_destroy(op, instance_data); ASSERT_EQ(IB_OK, status); }
virtual void SetUp() { ib_status_t rc; const char *s1 = "string 1"; const char *s2 = "string 2"; BaseTransactionFixture::SetUp(); configureIronBee(); performTx(); ib_mm_t mm = ib_engine_mm_main_get(ib_engine); char* str1 = (char *)ib_mm_alloc(mm, (strlen(s1)+1)); if (str1 == NULL) { throw std::runtime_error("Could not allocate string 1."); } strcpy(str1, s1); char* str2 = (char *)ib_mm_alloc(mm, (strlen(s2)+1)); if (str1 == NULL) { throw std::runtime_error("Could not allocate string 2."); } strcpy(str2, s2); // Create field 1. rc = ib_field_create(&field1, mm, IB_S2SL("field1"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(str1)); if (rc != IB_OK) { throw std::runtime_error("Could not initialize field1."); } // Create field 2. rc = ib_field_create(&field2, mm, IB_S2SL("field2"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(str2)); if (rc != IB_OK) { throw std::runtime_error("Could not initialize field2."); } /* Create rule 1 */ rc = ib_rule_create(ib_engine, ib_context_engine(ib_engine), __FILE__, __LINE__, true, &rule1); if (rc != IB_OK) { throw std::runtime_error("Could not create rule1."); } rc = ib_rule_set_id(ib_engine, rule1, "rule1"); if (rc != IB_OK) { throw std::runtime_error("Could not set ID for rule1."); } /* Create the rule execution object #1 */ memset(&rule_exec1, 0, sizeof(rule_exec1)); rule_exec1.ib = ib_engine; rule_exec1.tx = ib_tx; rule_exec1.rule = rule1; /* Create rule 2 */ rc = (ib_rule_create(ib_engine, ib_context_engine(ib_engine), __FILE__, __LINE__, true, &rule2)); if (rc != IB_OK) { throw std::runtime_error("Could not create rule2."); } rc = ib_rule_set_id(ib_engine, rule2, "rule2"); if (rc != IB_OK) { throw std::runtime_error("Could not set ID for rule2."); } rule2->flags |= IB_RULE_FLAG_CAPTURE; /* Create the rule execution object #1 */ memset(&rule_exec2, 0, sizeof(rule_exec2)); rule_exec2.ib = ib_engine; rule_exec2.tx = ib_tx; rule_exec2.rule = rule2; }
/** * Lookup the IP address in the GeoIP database * * @param[in] ib IronBee engine * @param[in] tx Transaction * @param[in] event Event * @param[in] data callback data (Module configuration) */ static ib_status_t geoip_lookup( ib_engine_t *ib, ib_tx_t *tx, ib_state_event_type_t event, void *data ) { assert(ib != NULL); assert(event == handle_context_tx_event); assert(data != NULL); const char *ip = tx->er_ipstr; const module_data_t *mod_data = (const module_data_t *)data; if (ip == NULL) { ib_log_alert_tx(tx, "Trying to lookup NULL IP in GEOIP"); return IB_EINVAL; } #ifdef GEOIP_HAVE_VERSION /** * Some configurations exist as single characters and must be converted to * a string. This is simply a place to assemble that string before * it is passed into ip_data_add_nulstr. * This is only needed if we have support confidence items. WAM */ char one_char_str[2] = { '\0', '\0' }; #endif /* GEOIP_HAVE_VERSION */ ib_status_t rc; /* Declare and initialize the GeoIP property list. * Regardless of if we find a record or not, we want to create the list * artifact so that later modules know we ran and did [not] find a * record. */ ib_field_t *geoip_lst = NULL; ib_field_t *tmp_field = NULL; /* Id of geo ip record to read. */ int geoip_id; ib_log_debug_tx(tx, "GeoIP Lookup '%s'", ip); /* Build a new list. */ rc = ib_var_source_initialize( mod_data->geoip_source, &geoip_lst, tx->var_store, IB_FTYPE_LIST ); /* NOTICE: Called before GeoIP_record_by_addr allocates a * GeoIPRecord. */ if (rc != IB_OK) { ib_log_alert_tx(tx, "Unable to add GEOIP var."); return IB_EINVAL; } if (mod_data->geoip_db == NULL) { ib_log_alert_tx(tx, "GeoIP database was never opened. Perhaps the " "configuration file needs a GeoIPDatabaseFile " "\"/usr/share/geoip/GeoLite.dat\" line?"); return IB_EINVAL; } geoip_id = GeoIP_id_by_addr(mod_data->geoip_db, ip); if (geoip_id > 0) { const char *tmp_str; ib_log_debug_tx(tx, "GeoIP record found."); /* Add integers. */ tmp_field = NULL; tmp_str = GeoIP_code_by_id(geoip_id); if (tmp_str) { ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("country_code"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(tmp_str)); ib_field_list_add(geoip_lst, tmp_field); } tmp_str = GeoIP_code3_by_id(geoip_id); if (tmp_str) { ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("country_code3"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(tmp_str)); ib_field_list_add(geoip_lst, tmp_field); } tmp_str = GeoIP_country_name_by_id(mod_data->geoip_db, geoip_id); if (tmp_str) { ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("country_name"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(tmp_str)); ib_field_list_add(geoip_lst, tmp_field); } tmp_str = GeoIP_continent_by_id(geoip_id); if (tmp_str) { ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("continent_code"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in(tmp_str)); ib_field_list_add(geoip_lst, tmp_field); } } else { ib_log_debug_tx(tx, "No GeoIP record found."); ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("country_code"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in("O1")); ib_field_list_add(geoip_lst, tmp_field); ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("country_code3"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in("O01")); ib_field_list_add(geoip_lst, tmp_field); ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("country_name"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in("Other Country")); ib_field_list_add(geoip_lst, tmp_field); ib_field_create(&tmp_field, tx->mp, IB_FIELD_NAME("continent_code"), IB_FTYPE_NULSTR, ib_ftype_nulstr_in("O1")); ib_field_list_add(geoip_lst, tmp_field); } return IB_OK; }
ib_status_t ib_tfn_execute( ib_mpool_t *mp, const ib_tfn_t *tfn, const ib_field_t *fin, const ib_field_t **fout ) { assert(mp != NULL); assert(tfn != NULL); assert(fin != NULL); assert(fout != NULL); ib_status_t rc; const ib_field_t *out = NULL; if (fin->type == IB_FTYPE_LIST && ! ib_tfn_handle_list(tfn)) { /* Unroll list */ const ib_list_t *value_list; const ib_list_node_t *node; ib_list_t *out_list; ib_field_t *fnew; rc = ib_field_value(fin, ib_ftype_list_out(&value_list)); if (rc != IB_OK) { return rc; } rc = ib_list_create(&out_list, mp); if (rc != IB_OK) { return rc; } IB_LIST_LOOP_CONST(value_list, node) { const ib_field_t *in; const ib_field_t *tfn_out; in = (const ib_field_t *)ib_list_node_data_const(node); assert(in != NULL); rc = ib_tfn_execute(mp, tfn, in, &tfn_out); if (rc != IB_OK) { return rc; } if (tfn_out == NULL) { return IB_EINVAL; } rc = ib_list_push(out_list, (void *)tfn_out); if (rc != IB_OK) { return rc; } } /* Finally, create the output field (list) and return it */ rc = ib_field_create(&fnew, mp, fin->name, fin->nlen, IB_FTYPE_LIST, ib_ftype_list_in(out_list)); if (rc != IB_OK) { return rc; } out = fnew; } else {
ib_status_t ib_field_copy( ib_field_t **pf, ib_mpool_t *mp, const char *name, size_t nlen, const ib_field_t *src ) { ib_status_t rc; if (ib_field_is_dynamic(src)) { rc = ib_field_create_dynamic( pf, mp, name, nlen, src->type, src->val->fn_get, src->val->cbdata_get, src->val->fn_set, src->val->cbdata_set ); } else { switch (src->type) { case IB_FTYPE_NUM: { ib_num_t v; rc = ib_field_value(src, ib_ftype_num_out(&v)); if (rc != IB_OK) { goto failed; } rc = ib_field_create( pf, mp, name, nlen, src->type, ib_ftype_num_in(&v) ); break; } case IB_FTYPE_FLOAT: { ib_float_t v; rc = ib_field_value(src, ib_ftype_float_out(&v)); if (rc != IB_OK) { goto failed; } rc = ib_field_create( pf, mp, name, nlen, src->type, ib_ftype_float_in(&v) ); break; } default: { void *v; rc = ib_field_value(src, &v); if (rc != IB_OK) { goto failed; } rc = ib_field_create( pf, mp, name, nlen, src->type, v ); } } } if (rc != IB_OK) { goto failed; } ib_field_util_log_debug("FIELD_COPY", (*pf)); return rc; failed: *pf = NULL; return rc; }
/** * 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; }
TEST_F(TestIBUtilField, ConvertNumbers) { ib_field_t *f1; ib_field_t *f2; ib_status_t rc; ib_num_t num; ib_float_t flt; /* * Convert numeric to a float */ /* Create the field */ num = 1; rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_NUM, ib_ftype_num_in(&num)); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_FLOAT, f1, &f2); ASSERT_EQ(IB_OK, rc); /* Pull out param value for check. */ rc = ib_field_value(f2, ib_ftype_float_out(&flt)); ASSERT_EQ(IB_OK, rc); ASSERT_FLOAT_EQ(1.0, flt); /* * Convert floating-point to num */ /* Create the field */ flt = 1.0; rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_FLOAT, ib_ftype_float_in(&flt)); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_NUM, f1, &f2); ASSERT_EQ(IB_OK, rc); /* Pull out param value for check. */ rc = ib_field_value(f2, ib_ftype_num_in(&num)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1, num); /* * Convert floating-point to num */ /* Create the field */ flt = 1.1; rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_FLOAT, ib_ftype_float_in(&flt)); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_NUM, f1, &f2); ASSERT_EQ(IB_OK, rc); /* Pull out param value for check. */ rc = ib_field_value(f2, ib_ftype_num_in(&num)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1, num); }
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 { const ib_num_t len = 1; rc = ib_field_create( &fnew, mp, fin->name, fin->nlen, IB_FTYPE_NUM, ib_ftype_num_in(&len) ); } if (rc == IB_OK) { *fout = fnew; } return rc; } /** * Count 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.
/** * 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; }
/** * 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 {
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; }
/** * Set the matches into the given field name as .0, .1, .2 ... .9. * * @param[in] ib The IronBee engine to log to. * @param[in] tx The transaction to store the values into (tx->dpi). * @param[in] field_name The field to populate with Regex matches. * @param[in] ovector The vector of integer pairs of matches from PCRE. * @param[in] matches The number of matches. * @param[in] subject The matched-against string data. * * @returns IB_OK or IB_EALLOC. */ static ib_status_t pcre_set_matches(ib_engine_t *ib, ib_tx_t *tx, int *ovector, int matches, const char *subject) { IB_FTRACE_INIT(); /* IronBee status. */ ib_status_t rc; /* Iterator. */ int i; rc = ib_data_capture_clear(tx); if (rc != IB_OK) { ib_log_error_tx(tx, "Error clearing captures: %s", ib_status_to_string(rc)); } /* We have a match! Now populate TX:0-9 in tx->dpi. */ ib_log_debug2_tx(tx, "REGEX populating %d matches", matches); for (i=0; i<matches; i++) { /* The length of the match. */ size_t match_len; /* The first character in the match. */ const char *match_start; /* Field name */ const char *name; /* Holder for a copy of the field value when creating a new field. */ ib_bytestr_t *bs; /* Field holder. */ ib_field_t *field; /* Readability. Mark the start and length of the string. */ match_start = subject+ovector[i*2]; match_len = ovector[i*2+1] - ovector[i*2]; /* If debugging this, copy the string value out and print it to the * log. This could be dangerous as there could be non-character * values in the match. */ ib_log_debug2_tx(tx, "REGEX Setting #%d=%.*s", i, (int)match_len, match_start); /* Create a byte-string representation */ rc = ib_bytestr_dup_mem(&bs, tx->mp, (const uint8_t*)match_start, match_len); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } /* Create a field to hold the byte-string */ name = ib_data_capture_name(i); rc = ib_field_create(&field, tx->mp, name, strlen(name), IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } /* Add it to the capture collection */ rc = ib_data_capture_set_item(tx, i, field); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } } IB_FTRACE_RET_STATUS(IB_OK); }
TEST_F(TestIBUtilField, ConvertString) { ib_field_t *f1; ib_field_t *f2; ib_status_t rc; ib_num_t num; ib_float_t flt; /* * Convert numeric string to number */ /* Create the field */ rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_NULSTR, ib_ftype_nulstr_in("1")); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_NUM, f1, &f2); ASSERT_EQ(IB_OK, rc); /* Pull out param value for check. */ rc = ib_field_value(f2, ib_ftype_num_out(&num)); ASSERT_EQ(IB_OK, rc); ASSERT_EQ(1, num); /* * Convert floating-point string to float */ /* Create the field */ rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_NULSTR, ib_ftype_nulstr_in("1.1")); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_FLOAT, f1, &f2); ASSERT_EQ(IB_OK, rc); /* Pull out param value for check. */ rc = ib_field_value(f2, ib_ftype_float_out(&flt)); ASSERT_EQ(IB_OK, rc); ASSERT_FLOAT_EQ(1.1, flt); /* * Convert non-numeric string to number */ /* Create the field */ rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_NULSTR, ib_ftype_nulstr_in("x1")); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_NUM, f1, &f2); ASSERT_EQ(IB_EINVAL, rc); /* * Convert floating-point string to number */ /* Create the field */ rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_NULSTR, ib_ftype_nulstr_in("1.1")); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_NUM, f1, &f2); ASSERT_EQ(IB_EINVAL, rc); /* * Convert non-numeric string to float */ /* Create the field */ rc = ib_field_create(&f1, MM(), "one", 3, IB_FTYPE_NULSTR, ib_ftype_nulstr_in("x1.1")); ASSERT_EQ(IB_OK, rc); /* Attempt a numeric conversion. */ rc = ib_field_convert(MM(), IB_FTYPE_FLOAT, f1, &f2); ASSERT_EQ(IB_EINVAL, rc); }