]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3471: parser: string-ify ExpandVars
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 21 Jun 2022 12:43:13 +0000 (12:43 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 21 Jun 2022 12:43:13 +0000 (12:43 +0000)
Merge in SNORT/snort3 from ~DKYRYLOV/snort3:expand_vars to master

Squashed commit of the following:

commit ea934e0f3d339916be87ccc60ffd880eeb06b398
Author: dkyrylov <dkyrylov@cisco.com>
Date:   Tue Jun 14 13:07:24 2022 +0300

    parser: use std::string in ExpandVars

src/parser/parse_conf.cc
src/parser/vars.cc
src/parser/vars.h

index 5efc9a83b184b913aa94b609f62fefe536505c61..b04e23f1642d6f69b05b87a9cfddd74ec125077e 100644 (file)
@@ -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();
 }
index d8b336b18a376b0137844358d622202f782909ec..142c3f6041ad27f77a10577568362b0bd29a2d9f 100644 (file)
@@ -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();
 }
-
index 0d129f9add558847519568a85ba6001105ef43b1..cd145415758bb1076160a0d33643c37fe3b17cb6 100644 (file)
@@ -21,6 +21,7 @@
 #define VARS_H
 
 #include <cstdint>
+#include <string>
 
 #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