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