public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Robert Obkircher <r.obkircher@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v1 proxmox-ve-rs] fix #6399: firewall: fix parsing rule comments that contain hash signs
Date: Fri, 28 Nov 2025 14:22:13 +0100	[thread overview]
Message-ID: <20251128132458.177476-1-r.obkircher@proxmox.com> (raw)

Match the behavior of the corresponding perl code in parse_fw_rule and
treat everything after the first '#' on a line as the comment. This
works because validation prevents fields like the interface name from
contianing that symbol.

This fixes a bug where the firewall wouldn't start if a comment on a
rule contained a number sign.

Signed-off-by: Robert Obkircher <r.obkircher@proxmox.com>
---
The test in cluster.rs might be a bit overkill. Also, rust-analyzer
doesn't seem to work correctly at the end of that file as I can't seem
navigate to the defninitions of fields or methods.


 proxmox-ve-config/src/firewall/cluster.rs    | 66 +++++++++++++++++++-
 proxmox-ve-config/src/firewall/types/rule.rs |  8 ++-
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/proxmox-ve-config/src/firewall/cluster.rs b/proxmox-ve-config/src/firewall/cluster.rs
index 69d3bcd..b8ecb69 100644
--- a/proxmox-ve-config/src/firewall/cluster.rs
+++ b/proxmox-ve-config/src/firewall/cluster.rs
@@ -147,7 +147,8 @@ mod tests {
         log::{LogLevel, LogRateLimitTimescale},
         rule::{Kind, RuleGroup},
         rule_match::{
-            Icmpv6, Icmpv6Code, Icmpv6Type, IpAddrMatch, IpMatch, Ports, Protocol, RuleMatch, Tcp, Udp
+            Icmpv6, Icmpv6Code, Icmpv6Type, IpAddrMatch, IpMatch, Ports, Protocol, RuleMatch, Tcp,
+            Udp,
         },
     };
 
@@ -394,4 +395,67 @@ IN BGP(REJECT) -log crit -source 1.2.3.4
         assert!(empty_config.config.ipsets.is_empty());
         assert!(empty_config.config.groups.is_empty());
     }
+
+    #[test]
+    fn test_parse_config_comments() {
+        const CONFIG: &str = r#"
+# ignore lines that start with a # symbol
+[OPTIONS]
+[ALIASES]
+
+alias1 192.168.0.1 # comment # on alias1
+
+[IPSET ipset1] # comment # on ipset1
+
+dc/alias1 # comment # on ipset1 #1
+
+[RULES]
+
+GROUP testgroup # comment # on rule #1
+IN ACCEPT -p udp -dport 1234 -log nolog # comment # on rule #2
+
+[group testgroup] # comment # on testgroup
+
+IN ACCEPT -source dc/alias1 -p tcp -sport 1111 -log nolog # comment # on testgroup #1
+
+"#;
+
+        let mut config = CONFIG.as_bytes();
+        let config = Config::parse(&mut config).unwrap();
+
+        assert_eq!(config.config.aliases.len(), 1);
+        assert_eq!(
+            config.config.aliases["alias1"].comment(),
+            Some("comment # on alias1")
+        );
+
+        assert_eq!(config.config.ipsets.len(), 1);
+
+        let ipset1 = &config.config.ipsets["ipset1"];
+        assert_eq!(ipset1.comment.as_deref(), Some("comment # on ipset1"));
+
+        assert_eq!(ipset1.len(), 1);
+        assert_eq!(ipset1[0].comment.as_deref(), Some("comment # on ipset1 #1"));
+
+        assert_eq!(config.config.rules.len(), 2);
+        assert_eq!(
+            config.config.rules[0].comment.as_deref(),
+            Some("comment # on rule #1")
+        );
+        assert_eq!(
+            config.config.rules[1].comment.as_deref(),
+            Some("comment # on rule #2")
+        );
+
+        assert_eq!(config.config.groups.len(), 1);
+
+        let entry = &config.config.groups["testgroup"];
+        assert_eq!(entry.comment(), Some("comment # on testgroup"));
+
+        assert_eq!(entry.rules().len(), 1);
+        assert_eq!(
+            entry.rules()[0].comment.as_deref(),
+            Some("comment # on testgroup #1")
+        );
+    }
 }
diff --git a/proxmox-ve-config/src/firewall/types/rule.rs b/proxmox-ve-config/src/firewall/types/rule.rs
index 811256c..2648fa8 100644
--- a/proxmox-ve-config/src/firewall/types/rule.rs
+++ b/proxmox-ve-config/src/firewall/types/rule.rs
@@ -115,7 +115,7 @@ impl FromStr for Rule {
             bail!("rule must not contain any newlines!");
         }
 
-        let (line, comment) = match input.rsplit_once('#') {
+        let (line, comment) = match input.split_once('#') {
             Some((line, comment)) if !comment.is_empty() => (line.trim(), Some(comment.trim())),
             _ => (input.trim(), None),
         };
@@ -261,13 +261,15 @@ mod tests {
 
     #[test]
     fn test_parse_rule() {
-        let mut rule: Rule = "|GROUP tgr -i eth0 # acomm".parse().expect("valid rule");
+        let mut rule: Rule = "|GROUP tgr -i eth0 # acomm #comment"
+            .parse()
+            .expect("valid rule");
 
         assert_eq!(
             rule,
             Rule {
                 disabled: true,
-                comment: Some("acomm".to_string()),
+                comment: Some("acomm #comment".to_string()),
                 kind: Kind::Group(RuleGroup {
                     group: "tgr".to_string(),
                     iface: Some("eth0".to_string()),
-- 
2.47.3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


                 reply	other threads:[~2025-11-28 13:25 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251128132458.177476-1-r.obkircher@proxmox.com \
    --to=r.obkircher@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal