]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #5079: snort2lua: fix failure in converting patterns containing commas.
authorVitalii Serhiiovych Horbatov -X (vhorbato - SOFTSERVE INC at Cisco) <vhorbato@cisco.com>
Fri, 9 Jan 2026 09:15:00 +0000 (09:15 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Fri, 9 Jan 2026 09:15:00 +0000 (09:15 +0000)
Merge in SNORT/snort3 from ~VHORBATO/snort3:s2l_comma to master

Squashed commit of the following:

commit e59ff8ab76ae27d3409412174192ee0f2c1fc451
Author: vhorbato <vhorbato@cisco.com>
Date:   Tue Jan 6 15:41:43 2026 +0200

    snort2lua: fix failure in converting patterns containing commas

tools/snort2lua/rule_states/rule_content.cc

index ad83757c0fee08d305b9ccd364580e048c9405f8..0d03bffe8eaea56c383a7ad479d5fe57c5ed1efa 100644 (file)
@@ -174,23 +174,61 @@ template<const std::string* option_name>
 bool Content<option_name>::extract_payload(std::istringstream& stream,
     std::string& option)
 {
-    if ( !stream.good() )
-        return false;
+    while (stream.good() && std::isspace(stream.peek()))
+        stream.get();
 
-    std::getline(stream, option, ',');
-    if (option.empty())
+    if (!stream.good())
         return false;
 
-    const std::size_t quote = option.find('"');
-    if ( (quote != std::string::npos) && (quote == option.rfind('"')) )
+    if (stream.peek() == '!')
     {
-        std::string tmp;
-        std::getline(stream, tmp, '"');
-        option += "," + tmp + "\"";
-        std::getline(stream, tmp, ',');
-        option += tmp;
+        char c;
+        stream.get(c);
+        option.push_back(c);
+
+        while (stream.good() && std::isspace(stream.peek()))
+            stream.get();
     }
 
+    if (stream.peek() == '"')
+    {
+        char c;
+        stream.get(c);
+        option.push_back(c);
+
+        bool escaped = false;
+
+        while (stream.get(c))
+        {
+            option.push_back(c);
+
+            if (escaped)
+                escaped = false;
+            else if (c == '\\')
+                escaped = true;
+            else if (c == '"')
+                break;
+        }
+
+        while (stream.good())
+        {
+            const int next = stream.peek();
+
+            if (next == ',')
+            {
+                stream.get();
+                break;
+            }
+
+            if (next == EOF or !std::isspace(next))
+                break;
+
+            stream.get();
+        }
+    }
+    else
+        return false;
+
     util::trim(option);
     return true;
 }
@@ -218,7 +256,7 @@ bool Content<option_name>::convert(std::istringstream& data_stream)
 
     // This first loop parses all of the options between the
     // content keyword and the first semicolon.
-    while ( extract_payload(arg_stream, keyword) )
+    while ( std::getline(arg_stream, keyword, ',') )
     {
         std::istringstream opts(keyword);
         val = "";