0453073
From e7a90c1117e4d37be191a6567b405d7908a30434 Mon Sep 17 00:00:00 2001
0453073
From: Martin Pitt <martin.pitt@ubuntu.com>
0453073
Date: Wed, 22 Apr 2015 23:09:43 +0100
0453073
Subject: [PATCH] util: Fix assertion in split() on missing '
0453073
0453073
When parsing a unit with a trailing slash after an escaped line break, like
0453073
0453073
  ExecStart=/bin/echo 'foo \
0453073
    bar'
0453073
0453073
the split() function (through config_parse()) asserted and crashed pid 1:
0453073
0453073
  Assertion 'current[*l + 1] == quotechars[0]' failed at ../src/shared/util.c:583, function split(). Aborting.
0453073
0453073
Fix this by returning an error in this case ("trailing garbage").
0453073
0453073
Add corresponding test case. Also fix the missing "unit" argument of
0453073
config_parse_exec() in the comment.
0453073
0453073
https://launchpad.net/bugs/1447243
0453073
(cherry picked from commit 470dca63cd2b1579f45f72b6b9777494abeff105)
0453073
---
0453073
 src/shared/util.c         |  3 +--
0453073
 src/test/test-unit-file.c | 15 +++++++++++++++
0453073
 2 files changed, 16 insertions(+), 2 deletions(-)
0453073
0453073
diff --git a/src/shared/util.c b/src/shared/util.c
0453073
index 1e1bf944f2..649344d88f 100644
0453073
--- a/src/shared/util.c
0453073
+++ b/src/shared/util.c
0453073
@@ -571,13 +571,12 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
0453073
                 char quotechars[2] = {*current, '\0'};
0453073
 
0453073
                 *l = strcspn_escaped(current + 1, quotechars);
0453073
-                if (current[*l + 1] == '\0' ||
0453073
+                if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
0453073
                     (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
0453073
                         /* right quote missing or garbage at the end */
0453073
                         *state = current;
0453073
                         return NULL;
0453073
                 }
0453073
-                assert(current[*l + 1] == quotechars[0]);
0453073
                 *state = current++ + *l + 2;
0453073
         } else if (quoted) {
0453073
                 *l = strcspn_escaped(current, separator);
0453073
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
0453073
index e517f571d6..9f3e3a227e 100644
0453073
--- a/src/test/test-unit-file.c
0453073
+++ b/src/test/test-unit-file.c
0453073
@@ -92,6 +92,7 @@ static void check_execcommand(ExecCommand *c,
0453073
 
0453073
 static void test_config_parse_exec(void) {
0453073
         /* int config_parse_exec(
0453073
+                 const char *unit,
0453073
                  const char *filename,
0453073
                  unsigned line,
0453073
                  const char *section,
0453073
@@ -303,6 +304,20 @@ static void test_config_parse_exec(void) {
0453073
         assert_se(r == 0);
0453073
         assert_se(c1->command_next == NULL);
0453073
 
0453073
+        log_info("/* missing ending ' */");
0453073
+        r = config_parse_exec(NULL, "fake", 4, "section", 1,
0453073
+                              "LValue", 0, "/path 'foo",
0453073
+                              &c, NULL);
0453073
+        assert_se(r == 0);
0453073
+        assert_se(c1->command_next == NULL);
0453073
+
0453073
+        log_info("/* missing ending ' with trailing backslash */");
0453073
+        r = config_parse_exec(NULL, "fake", 4, "section", 1,
0453073
+                              "LValue", 0, "/path 'foo\\",
0453073
+                              &c, NULL);
0453073
+        assert_se(r == 0);
0453073
+        assert_se(c1->command_next == NULL);
0453073
+
0453073
         exec_command_free_list(c);
0453073
 }
0453073