From: Josh Date: Mon, 12 Jan 2015 19:10:33 +0000 (-0600) Subject: Snort2Lua 'append' patch X-Git-Tag: 3.0.0-233~1088^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77e4fc8b01e2cd1f41d37d63d9616ef015499400;p=thirdparty%2Fsnort3.git Snort2Lua 'append' patch --- diff --git a/tools/snort2lua/data/data_types/dt_table.cc b/tools/snort2lua/data/data_types/dt_table.cc index f24bbd64e..ab6abeeec 100644 --- a/tools/snort2lua/data/data_types/dt_table.cc +++ b/tools/snort2lua/data/data_types/dt_table.cc @@ -25,11 +25,11 @@ static inline Table* find_table(std::vector vec, std::string name) { - if(name.empty()) + if (name.empty()) return nullptr; for( auto *t : vec) - if(!name.compare(t->get_name())) + if (!name.compare(t->get_name())) return t; return nullptr; @@ -59,6 +59,9 @@ Table::~Table() for( Option* o : options) delete o; + for( Option* a : append_options) + delete a; + delete comments; } @@ -85,7 +88,7 @@ Table* Table::open_table(std::string table_name) { Table* t = find_table(tables, table_name); - if(t) + if (t) return t; t = new Table(table_name, depth + 1); @@ -123,11 +126,37 @@ bool Table::add_option(std::string opt_name, std::string value) return true; } +void Table::append_option(std::string opt_name, int value) +{ + if (!has_option(opt_name, value)) + { + Option *a = new Option(opt_name, value, 0); + append_options.push_back(a); + } +} + +void Table::append_option(std::string opt_name, bool value) +{ + if (!has_option(opt_name, value)) + { + Option *a = new Option(opt_name, value, 0); + append_options.push_back(a); + } +} + +void Table::append_option(std::string opt_name, std::string value) +{ + if (!has_option(opt_name, value)) + { + Option *a = new Option(opt_name, value, 0); + append_options.push_back(a); + } +} bool Table::add_list(std::string list_name, std::string next_elem) { for (auto l : lists) - if(l->get_name() == list_name) + if (l->get_name() == list_name) return l->add_value(next_elem); Variable *var = new Variable(list_name, depth + 1); @@ -141,6 +170,10 @@ bool Table::has_option(const std::string opt_name) if (!opt_name.compare(o->get_name())) return true; + for (Option* a : append_options) + if (!opt_name.compare(a->get_name())) + return true; + return false; } @@ -151,6 +184,10 @@ bool Table::has_option(Option opt) if ( (*o) == opt) return true; + for (Option* a : append_options) + if ( (*a) == opt) + return true; + return false; } @@ -185,7 +222,7 @@ std::ostream &operator<<( std::ostream& out, const Table &t) for(int i = 0; i < t.depth; i++) whitespace += " "; - if(!t.name.empty()) + if (!t.name.empty()) out << whitespace << t.name << " =" << std::endl; out << whitespace << '{' << std::endl; @@ -211,12 +248,16 @@ std::ostream &operator<<( std::ostream& out, const Table &t) out << (*sub_t) << ",\n"; } + out << whitespace << "}"; + + // Now, print all options which need to be appended/overwrite earlier options + if (!t.append_options.empty()) + { + out << "\n"; + + for (Option* a : t.append_options) + out << (*a) << "\n"; + } - // don't add a comma if the depth is zero - if(t.depth == 0) - out << "}"; - else - out << whitespace << "}"; - return out; } diff --git a/tools/snort2lua/data/data_types/dt_table.h b/tools/snort2lua/data/data_types/dt_table.h index 6bfe625bc..38f8a0852 100644 --- a/tools/snort2lua/data/data_types/dt_table.h +++ b/tools/snort2lua/data/data_types/dt_table.h @@ -47,6 +47,13 @@ public: void add_comment(std::string comment); bool has_option(const std::string); + /* emit options after table has finished printing. */ + /* These options will be appended to the previous table as supposed */ + /* to overwriting the entire table */ + void append_option(std::string opt_name, int val); + void append_option(std::string opt_name, bool val); + void append_option(std::string opt_name, std::string val); + friend std::ostream &operator<<( std::ostream&, const Table &); private: @@ -56,6 +63,7 @@ private: std::vector tables; std::vector options; std::vector lists; + std::vector append_options; bool has_option(std::string name, int val); diff --git a/tools/snort2lua/data/dt_table_api.cc b/tools/snort2lua/data/dt_table_api.cc index 3d507daa8..76f82a3ed 100644 --- a/tools/snort2lua/data/dt_table_api.cc +++ b/tools/snort2lua/data/dt_table_api.cc @@ -48,6 +48,8 @@ void TableApi::reset_state() { std::stack empty; open_tables.swap(empty); + std::stack empty_two; + top_level_tables.swap(empty_two); curr_data_bad = false; } @@ -62,6 +64,10 @@ void TableApi::open_top_level_table(std::string table_name) } open_tables.push(t); + + // ignore the initial table + if(open_tables.size() > 1) + top_level_tables.push(open_tables.size()); } void TableApi::open_table(std::string table_name) @@ -106,7 +112,14 @@ void TableApi::close_table() if (open_tables.size() == 0) DataApi::developer_error("No open tables to close!!"); else + { + if ( !top_level_tables.empty() ) + if ( open_tables.size() == top_level_tables.top() ) + top_level_tables.pop(); + open_tables.pop(); + } + } @@ -157,6 +170,92 @@ bool TableApi::add_option(const std::string option_name, const bool val) bool TableApi::add_option(const std::string name, const char* const v) { return add_option(name, std::string(v)); } +void TableApi::create_append_data(std::string& fqn, Table* &t) +{ + unsigned start = 0; + + if (!top_level_tables.empty()) + start = top_level_tables.top(); + + // I need to iterate over the stack of open tables. However, + // stack's don't allow iteration without popping. So, rather + // than change the underlying stack data structure, I am going + // to just copy the entire data structure. Innedficciant, but + // not pressed for speed here. + std::stack copy(open_tables); + + while(!copy.empty() && copy.size() >= start) + { + fqn = copy.top()->get_name() + "." + fqn; + t = copy.top(); + copy.pop(); + } +} + +void TableApi::append_option(const std::string option_name, const std::string val) +{ + if(open_tables.size() == 0) + { + DataApi::developer_error("Must open table before adding an option!!: " + + option_name + " = " + val); + return; + } + + Table* t = nullptr; + std::string opt_name = option_name; + create_append_data(opt_name, t); + + if ( t != nullptr) + t->append_option(opt_name, val); + else + DataApi::developer_error("Snort2lua cannot find a Table to append the option: " + + option_name + " = " + val); +} + +void TableApi::append_option(const std::string option_name, const int val) +{ + if(open_tables.size() == 0) + { + DataApi::developer_error("Must open table before adding an option!!: " + + option_name + " = " + std::to_string(val)); + return; + } + + Table* t = nullptr; + std::string opt_name = option_name; + create_append_data(opt_name, t); + + if ( t != nullptr) + t->append_option(opt_name, val); + else + DataApi::developer_error("Snort2lua cannot find a Table to append the option: " + + opt_name + " = " + std::to_string(val)); +} + +void TableApi::append_option(const std::string option_name, const bool val) +{ + if(open_tables.size() == 0) + { + DataApi::developer_error("Must open table before adding an option!!: " + + option_name + " = " + std::to_string(val)); + return; + } + + Table* t = nullptr; + std::string opt_name = option_name; + create_append_data(opt_name, t); + + if ( t != nullptr) + t->append_option(opt_name, val); + else + DataApi::developer_error("Snort2lua cannot find a Table to append the option: " + + opt_name + " = " + std::to_string(val)); +} + +void TableApi::append_option(const std::string name, const char* const v) +{ append_option(name, std::string(v)); } + + bool TableApi::add_list(std::string list_name, std::string next_elem) { if(open_tables.size() == 0) diff --git a/tools/snort2lua/data/dt_table_api.h b/tools/snort2lua/data/dt_table_api.h index 7d6fc33c1..7d8a85c32 100644 --- a/tools/snort2lua/data/dt_table_api.h +++ b/tools/snort2lua/data/dt_table_api.h @@ -87,10 +87,20 @@ void swap_tables(std::vector& new_tables); */ // add an string, bool, or int option to the table. --> table = { name = var |'var'}; -bool add_option(const std::string name, const std::string val); -bool add_option(const std::string name, const int val); -bool add_option(const std::string name, const bool val); -bool add_option(const std::string name, const char* const v); +bool add_option(const std::string opt_name, const std::string val); +bool add_option(const std::string opt_name, const int val); +bool add_option(const std::string opt_name, const bool val); +bool add_option(const std::string opt_name, const char* const v); + +// sometimes, you may need to create a default option, before overwriting that +// option later. For instance, if you have a default table, and then you +// need to overwrite a single option in that default table, you can use these +// methods to overwrite that option. +void append_option(const std::string opt_name, const std::string val); +void append_option(const std::string opt_name, const int val); +void append_option(const std::string opt_name, const bool val); +void append_option(const std::string opt_name, const char* const v); + // add an option with a list of variables --> table = { name = 'elem1 elem2 ...' } // corresponds to Parameter::PT_MULTI bool add_list(std::string list_name, std::string next_elem); @@ -107,13 +117,16 @@ bool add_unsupported_comment(std::string unsupported_var); // return true if this name exists as an option name for the selected table bool option_exists(const std::string name); - private: -std::vector tables; +void create_append_data(std::string& fqn, Table* &t); -// various convenience pointers and holders +// Data +std::vector tables; std::stack open_tables; +std::stack top_level_tables; bool curr_data_bad; + + };