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