From: Mike Stepanek (mstepane) Date: Tue, 21 Jun 2022 12:43:13 +0000 (+0000) Subject: Pull request #3471: parser: string-ify ExpandVars X-Git-Tag: 3.1.33.0~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63416ee04f49118adb3609a6b520643c692240a7;p=thirdparty%2Fsnort3.git Pull request #3471: parser: string-ify ExpandVars Merge in SNORT/snort3 from ~DKYRYLOV/snort3:expand_vars to master Squashed commit of the following: commit ea934e0f3d339916be87ccc60ffd880eeb06b398 Author: dkyrylov Date: Tue Jun 14 13:07:24 2022 +0300 parser: use std::string in ExpandVars --- diff --git a/src/parser/parse_conf.cc b/src/parser/parse_conf.cc index 5efc9a83b..b04e23f16 100644 --- a/src/parser/parse_conf.cc +++ b/src/parser/parse_conf.cc @@ -189,17 +189,17 @@ const char* get_config_file(const char* arg, std::string& file) void parse_include(SnortConfig* sc, const char* arg) { assert(arg); - arg = ExpandVars(arg); + std::string conf = ExpandVars(arg); std::string file = !rules_file_depth ? get_ips_policy()->includer : get_parse_file(); - const char* code = get_config_file(arg, file); + const char* code = get_config_file(conf.c_str(), file); if ( !code ) { - ParseError("can't open %s\n", arg); + ParseError("can't open %s\n", conf.c_str()); return; } - push_parse_location(code, file.c_str(), arg); + push_parse_location(code, file.c_str(), conf.c_str()); parse_rules_file(sc, file.c_str()); pop_parse_location(); } diff --git a/src/parser/vars.cc b/src/parser/vars.cc index d8b336b18..142c3f604 100644 --- a/src/parser/vars.cc +++ b/src/parser/vars.cc @@ -310,11 +310,8 @@ void ParsePathVar(const char* name, const char* value) while (tmp != var_table); } - value = ExpandVars(value); - if (!value) - { - ParseAbort("could not expand var('%s').", name); - } + std::string expand_value = ExpandVars(value); + value = expand_value.c_str(); DisallowCrossTableDuplicateVars(name, VAR_TYPE__DEFAULT); @@ -391,7 +388,7 @@ void DeleteVars(VarEntry* var_table) } } -const char* VarSearch(const char* name) +const std::string VarSearch(const std::string& name) { IpsPolicy* dp = get_ips_policy(); VarEntry* var_table = dp->var_table; @@ -399,10 +396,10 @@ const char* VarSearch(const char* name) vartable_t* ip_vartable = dp->ip_vartable; sfip_var_t* ipvar; - if ((ipvar = sfvt_lookup_var(ip_vartable, name)) != nullptr) + if ((ipvar = sfvt_lookup_var(ip_vartable, name.c_str())) != nullptr) return ExpandVars(ipvar->value); - if (PortVarTableFind(portVarTable, name)) + if (PortVarTableFind(portVarTable, name.c_str())) return name; if (var_table != nullptr) @@ -410,147 +407,97 @@ const char* VarSearch(const char* name) VarEntry* p = var_table; do { - if (strcasecmp(p->name, name) == 0) + if (strcasecmp(p->name, name.c_str()) == 0) return p->value; p = p->next; } while (p != var_table); } - return nullptr; + return ""; } - // The expanded string. Note that the string is returned in a - // static variable and most likely needs to be string dup'ed. -const char* ExpandVars(const char* string) +const std::string ExpandVars(const std::string& input_str) { - static char estring[ 65536 ]; // FIXIT-L convert this foo to a std::string - - char rawvarname[128], varname[128], varaux[128], varbuffer[128]; - int quote_toggle = 0; - - if (!string || !*string || !strchr(string, '$')) - return(string); + std::stringstream output; + bool quote_toggle = false; - memset((char*)estring, 0, sizeof(estring)); + if (input_str.find('$') == std::string::npos) + return(input_str); - int i = 0, j = 0; - int l_string = strlen(string); - - while (i < l_string && j < (int)sizeof(estring) - 1) + for (auto i = input_str.begin(); i < input_str.end(); i++) { - int c = string[i++]; - + const char c = *i; if (c == '"') { - /* added checks to make sure that we are inside a quoted string - */ - quote_toggle ^= 1; + // added checks to make sure that we are inside a quoted string + quote_toggle = !quote_toggle; } if (c == '$' && !quote_toggle) { - memset((char*)rawvarname, 0, sizeof(rawvarname)); - int varname_completed = 0; - int name_only = 1; - int iv = i; - int jv = 0; - - if (string[i] == '(') - { - name_only = 0; - iv = i + 1; + auto begin = (i+1); + auto end = begin; + bool name_only = *begin != '('; + if (!name_only) + begin++; + + while (*end != '\0' && ( + ( name_only && (isalnum(*end) || *end == '_') ) || + ( !name_only && *end != ')' ) ) ) { + end++; } - while (!varname_completed - && iv < l_string - && jv < (int)sizeof(rawvarname) - 1) - { - c = string[iv++]; - - if ((name_only && !(isalnum(c) || c == '_')) - || (!name_only && c == ')')) - { - varname_completed = 1; + std::string var_name(begin, end); + std::string var_aux; - if (name_only) - iv--; - } - else - { - rawvarname[jv++] = (char)c; - } - } + i = end; - if (varname_completed || iv == l_string) - { - i = iv; - const char* varcontents = nullptr; + char var_modifier = ' '; - memset((char*)varname, 0, sizeof(varname)); - memset((char*)varaux, 0, sizeof(varaux)); - char varmodifier = ' '; + size_t p = var_name.find(':'); - char* p = strchr(rawvarname, ':'); - - if (p) + if (p != std::string::npos) + { + if (var_name.size() - p >= 2) { - SnortStrncpy(varname, rawvarname, p - rawvarname); - - if (strlen(p) >= 2) - { - varmodifier = *(p + 1); - SnortStrncpy(varaux, p + 2, sizeof(varaux)); - } + var_modifier = var_name[p+1]; + var_aux = var_name.substr(p+2); } - else - SnortStrncpy(varname, rawvarname, sizeof(varname)); + var_name = var_name.substr(0, p); + } - memset((char*)varbuffer, 0, sizeof(varbuffer)); + std::string var_contents = VarSearch(var_name); - varcontents = VarSearch(varname); + switch (var_modifier) + { + case '-': + if (var_contents.empty()) + var_contents = var_aux.c_str(); + break; - switch (varmodifier) + case '?': + if (var_contents.empty()) { - case '-': - if (!varcontents || !strlen(varcontents)) - varcontents = varaux; - break; - - case '?': - if (!varcontents || !strlen(varcontents)) - { - if (strlen(varaux)) - ParseAbort("%s", varaux); - else - ParseAbort("undefined variable '%s'.", varname); - } - break; + if (!var_aux.empty()) + ParseAbort("%s", var_aux.c_str()); + else + ParseAbort("undefined variable '%s'.", var_name.c_str()); } + break; + } - /* If variable not defined now, we're toast */ - if (!varcontents || !strlen(varcontents)) - ParseAbort("undefined variable name: %s.", varname); - - int l_varcontents = strlen(varcontents); - - iv = 0; + // If variable not defined now, we're toast + if (var_contents.empty()) + ParseAbort("undefined variable name: %s.", var_name.c_str()); - while (iv < l_varcontents && j < (int)sizeof(estring) - 1) - estring[j++] = varcontents[iv++]; - } - else - { - estring[j++] = '$'; - } + output << var_contents; } else { - estring[j++] = (char)c; + output << c; } } - - return estring; + return output.str(); } - diff --git a/src/parser/vars.h b/src/parser/vars.h index 0d129f9ad..cd1454157 100644 --- a/src/parser/vars.h +++ b/src/parser/vars.h @@ -21,6 +21,7 @@ #define VARS_H #include +#include #include "sfip/sf_vartable.h" @@ -63,8 +64,8 @@ int VarIsIpAddr(vartable_t* ip_vartable, const char* value); int VarIsIpList(vartable_t* ip_vartable, const char* value); void DisallowCrossTableDuplicateVars(const char* name, VarType var_type); -const char* VarSearch(const char* name); -const char* ExpandVars(const char* string); +const std::string VarSearch(const std::string& name); +const std::string ExpandVars(const std::string& input_str); #endif