Blob Blame Raw
From b8ea1456a156ffe54b2d8a972b14f89cc8f014eb Mon Sep 17 00:00:00 2001
From: Dominic Cleal <dcleal@redhat.com>
Date: Tue, 9 Sep 2014 11:29:25 +0100
Subject: [PATCH] Systemd: parse semicolons inside entry values, not as EOL
 comments

Fixes RHBZ#1139498

(cherry picked from commit 414f049a8e65d84eb579d1e40dbf75045ed8d3bd)

Conflicts:
	NEWS
---
 lenses/systemd.aug            | 24 ++++++++++++++----------
 lenses/tests/test_systemd.aug | 29 +++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/lenses/systemd.aug b/lenses/systemd.aug
index 370945b..e1d9e5a 100644
--- a/lenses/systemd.aug
+++ b/lenses/systemd.aug
@@ -29,9 +29,13 @@ autoload xfm
 (* View: eol *)
 let eol = Util.eol
 
-(* View: comment
-   An <IniFile.comment> entry *)
-let comment    = IniFile.comment IniFile.comment_re "#"
+(* View: eol_comment
+   An <IniFile.comment> entry for standalone comment lines (; or #) *)
+let comment     = IniFile.comment IniFile.comment_re "#"
+
+(* View: eol_comment
+   An <IniFile.comment> entry for end of line comments (# only) *)
+let eol_comment = IniFile.comment "#" "#"
 
 (* View: sep
    An <IniFile.sep> entry *)
@@ -52,7 +56,7 @@ let entry_multi_kw   =
   in /[A-Za-z][A-Za-z0-9._-]+/ - forbidden
 
 (* Variable: value_single_re *)
-let value_single_re  = /[^;# \t\n\\][^;#\n\\]*[^;# \t\n\\]|[^;# \t\n\\]/
+let value_single_re  = /[^# \t\n\\][^#\n\\]*[^# \t\n\\]|[^# \t\n\\]/
 
 (* View: sto_value_single
    Support multiline values with a backslash *)
@@ -61,7 +65,7 @@ let sto_value_single = Util.del_opt_ws ""
                                 . (/\\\\\n/ . value_single_re)*)
 
 (* View: sto_value *)
-let sto_value = store /[^;# \t\n]*[^;# \t\n\\]/
+let sto_value = store /[^# \t\n]*[^# \t\n\\]/
 
 (* Variable: value_sep
    Multi-value entries separated by whitespace or backslash and newline *)
@@ -69,7 +73,7 @@ let value_sep = del /[ \t]+|[ \t]*\\\\[ \t]*\n[ \t]*/ " "
 
 (* Variable: value_cmd_re
    Don't parse @ and - prefix flags *)
-let value_cmd_re = /[^;#@ \t\n\\-][^;#@ \t\n\\-][^;# \t\n\\]*/
+let value_cmd_re = /[^#@ \t\n\\-][^#@ \t\n\\-][^# \t\n\\]*/
 
 (* Variable: env_key *)
 let env_key = /[A-Za-z0-9_]+(\[[0-9]+\])?/
@@ -89,7 +93,7 @@ Supported entry features, selected by key names:
 (* View: entry_fn
    Prototype for our various key=value lines, with optional comment *)
 let entry_fn (kw:regexp) (val:lens) =
-    [ key kw . sep . val . (comment|eol) ]
+    [ key kw . sep . val . (eol_comment|eol) ]
 
 (* View: entry_value
    Store a value that doesn't contain spaces *)
@@ -127,9 +131,9 @@ let entry_command =
 let entry_env =
      let envkv (env_val:lens) = key env_key . Util.del_str "=" . env_val
      (* bare has no spaces, and is optionally quoted *)
-  in let bare = Quote.do_quote_opt (envkv (store /[^;#'" \t\n]*[^;#'" \t\n\\]/)?)
+  in let bare = Quote.do_quote_opt (envkv (store /[^#'" \t\n]*[^#'" \t\n\\]/)?)
      (* quoted has at least one space, and must be quoted *)
-  in let quoted = Quote.do_quote (envkv (store /[^;#"'\n]*[ \t]+[^;#"'\n]*/))
+  in let quoted = Quote.do_quote (envkv (store /[^#"'\n]*[ \t]+[^#"'\n]*/))
   in let envkv_quoted = [ bare ] | [ quoted ]
   in entry_fn entry_env_kw ( Build.opt_list envkv_quoted value_sep )
 
@@ -145,7 +149,7 @@ let entry   = entry_single | entry_multi | entry_command | entry_env | comment
 (* View: include
    Includes another file at this position *)
 let include = [ key ".include" . Util.del_ws_spc . sto_value
-                . (comment|eol) ]
+                . (eol_comment|eol) ]
 
 (* View: title
    An <IniFile.title> *)
diff --git a/lenses/tests/test_systemd.aug b/lenses/tests/test_systemd.aug
index b1574e1..82516b3 100644
--- a/lenses/tests/test_systemd.aug
+++ b/lenses/tests/test_systemd.aug
@@ -307,3 +307,32 @@ test Systemd.entry_command get "ExecStart=/usr/bin/find /var/lib/sudo -exec /usr
       { "7" = "\073" }
     }
   }
+
+let exec_tmux = "ExecStart=/usr/bin/tmux unbind-key -a; \
+                        kill-window -t anaconda:shell; \
+                        bind-key ? list-keys\n"
+
+(* Test: Systemd.lns
+     Semicolons are permitted in entry values, e.g. as part of a command *)
+test Systemd.entry_command get exec_tmux =
+  { "ExecStart"
+    { "command" = "/usr/bin/tmux" }
+    { "arguments"
+      { "1" = "unbind-key" }
+      { "2" = "-a;" }
+      { "3" = "kill-window" }
+      { "4" = "-t" }
+      { "5" = "anaconda:shell;" }
+      { "6" = "bind-key" }
+      { "7" = "?" }
+      { "8" = "list-keys" } } }
+
+(* Test: Systemd.lns
+     # and ; are OK for standalone comments, but # only for EOL comments *)
+test Systemd.lns get "[Service]\n# hash\n; semicolon\nExecStart=/bin/echo # hash\n" =
+  { "Service"
+    { "#comment" = "hash" }
+    { "#comment" = "semicolon" }
+    { "ExecStart"
+      { "command" = "/bin/echo" }
+      { "#comment" = "hash" } } }