RuleContext profile(state);
int result = 0;
- int rval = (int)IpsOption::NO_MATCH; // FIXIT-L refactor to eliminate casts to int
+ int rval;
char tmp_noalert_flag = 0;
Cursor cursor = orig_cursor;
bool continue_loop = true;
// No, haven't evaluated this one before... Check it.
do
{
+ rval = (int)IpsOption::NO_MATCH; // FIXIT-L refactor to eliminate casts to int.
if ( node->otn )
{
SnortProtocolId snort_protocol_id = p->get_snort_protocol_id();
if ( continue_loop && rval == (int)IpsOption::MATCH && node->relative_children )
{
IpsOption* opt = (IpsOption*)node->option_data;
- continue_loop = opt->retry(cursor);
+ continue_loop = opt->retry(cursor, orig_cursor);
}
else
continue_loop = false;
// packet threads
virtual bool is_relative() { return false; }
- virtual bool retry(Cursor&) { return false; }
+ virtual bool retry(Cursor&, const Cursor&) { return false; }
virtual void action(Packet*) { }
enum EvalStatus { NO_MATCH, MATCH, NO_ALERT, FAILED_BIT };
bool is_relative() override
{ return config->pmd.is_relative(); }
- bool retry(Cursor&) override;
+ bool retry(Cursor&, const Cursor&) override;
ContentData* get_data()
{ return config; }
ContentData* config;
};
-bool ContentOption::retry(Cursor& c)
+bool ContentOption::retry(Cursor& current_cursor, const Cursor& orig_cursor)
{
if ( config->pmd.is_negated() )
return false;
if ( !config->pmd.depth )
return true;
- // FIXIT-L consider moving adjusting delta from eval to retry
- assert(c.get_delta() >= config->match_delta);
-
- unsigned min = c.get_delta() + config->pmd.pattern_size;
- unsigned max = c.get_delta() - config->match_delta + config->pmd.offset + config->pmd.depth;
+ // Do not retry if the current pattern would extend beyond the area
+ // in which we're looking for it.
+ unsigned min = current_cursor.get_delta() + config->pmd.pattern_size;
+ unsigned max = orig_cursor.get_delta() + config->pmd.offset + config->pmd.depth;
return min <= max;
}
return -1;
}
+ // FIXIT-M: The depth on retries should not be the same as that used
+ // on the first try.
+
const uint8_t* base = c.buffer() + pos;
int found = cd->searcher->search(search_handle, base, depth);
{ return (config->options & SNORT_PCRE_RELATIVE) != 0; }
EvalStatus eval(Cursor&, Packet*) override;
- bool retry(Cursor&) override;
+ bool retry(Cursor&, const Cursor&) override;
PcreData* get_data()
{ return config; }
// using content, but more advanced pcre won't work for the relative /
// overlap case.
-bool PcreOption::retry(Cursor&)
+bool PcreOption::retry(Cursor&, const Cursor&)
{
if ((config->options & (SNORT_PCRE_INVERT | SNORT_PCRE_ANCHORED)))
{
bool is_relative() override
{ return config.pmd.is_relative(); }
- bool retry(Cursor&) override;
+ bool retry(Cursor&, const Cursor&) override;
PatternMatchData* get_pattern(SnortProtocolId, RuleDirection) override
{ return &config.pmd; }
return NO_MATCH;
}
-bool RegexOption::retry(Cursor&)
+bool RegexOption::retry(Cursor&, const Cursor&)
{ return !is_relative(); }
//-------------------------------------------------------------------------
Cursor c(&pkt);
CHECK(opt->eval(c, &pkt) == IpsOption::MATCH);
CHECK(!strcmp((const char*) c.start(), " stew *"));
- CHECK(opt->retry(c));
+ CHECK(opt->retry(c,c));
}
TEST(ips_regex_option, no_match_delta)
CHECK(opt->is_relative());
CHECK(opt->eval(c, &pkt) == IpsOption::NO_MATCH);
- CHECK(!opt->retry(c));
+ CHECK(!opt->retry(c,c));
}
//-------------------------------------------------------------------------
buffer_info == hio.buffer_info;
}
-bool HttpIpsOption::retry(Cursor& c)
+bool HttpIpsOption::retry(Cursor& current_cursor, const Cursor&)
{
if (buffer_info.type == HTTP_BUFFER_PARAM)
{
- HttpCursorData* cd = (HttpCursorData*)c.get_data(HttpCursorData::id);
+ HttpCursorData* cd = (HttpCursorData*)current_cursor.get_data(HttpCursorData::id);
if (cd)
return cd->retry();
EvalStatus eval(Cursor&, snort::Packet*) override;
uint32_t hash() const override;
bool operator==(const snort::IpsOption& ips) const override;
- bool retry(Cursor&) override;
+ bool retry(Cursor&, const Cursor&) override;
static IpsOption* opt_ctor(snort::Module* m, OptTreeNode*)
{ return new HttpIpsOption((HttpCursorModule*)m); }
static void opt_dtor(snort::IpsOption* p) { delete p; }