sys-apps/systemd: backport fix for trailing space in unit hanging systemd

This commit is contained in:
mischief 2015-03-24 13:59:12 -07:00
parent 5cc0cecd7a
commit c37554a1dc
2 changed files with 155 additions and 0 deletions

View File

@ -0,0 +1,151 @@
From ba774317ac7d3e67fdb9ed81663264d38859df59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 18 Dec 2014 17:51:38 -0500
Subject: [PATCH] Treat a trailing backslash as an error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit a2a5291b3f5 changed the parser to reject unfinished quoted
strings. Unfortunately it introduced an error where a trailing
backslash would case an infinite loop. Of course this must fixed, but
the question is what to to instead. Allowing trailing backslashes and
treating them as normal characters would be one option, but this seems
suboptimal. First, there would be inconsistency between handling of
quoting and of backslashes. Second, a trailing backslash is most
likely an error, at it seems better to point it out to the user than
to try to continue.
Updated rules:
ExecStart=/bin/echo \\ → OK, prints a backslash
ExecStart=/bin/echo \ → error
ExecStart=/bin/echo "x → error
ExecStart=/bin/echo "x"y → error
---
src/shared/util.c | 8 +++++++-
src/test/test-strv.c | 4 ++++
src/test/test-util.c | 49 ++++++++++++++++++++++++++++++-------------------
3 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/src/shared/util.c b/src/shared/util.c
index 364f618..91cf670 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -521,7 +521,7 @@ int safe_atod(const char *s, double *ret_d) {
static size_t strcspn_escaped(const char *s, const char *reject) {
bool escaped = false;
- size_t n;
+ int n;
for (n=0; s[n]; n++) {
if (escaped)
@@ -531,6 +531,7 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
else if (strchr(reject, s[n]))
break;
}
+
/* if s ends in \, return index of previous char */
return n - escaped;
}
@@ -566,6 +567,11 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
*state = current++ + *l + 2;
} else if (quoted) {
*l = strcspn_escaped(current, separator);
+ if (current[*l] && !strchr(separator, current[*l])) {
+ /* unfinished escape */
+ *state = current;
+ return NULL;
+ }
*state = current + *l;
} else {
*l = strcspn(current, separator);
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index 0b78086..f343eab 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -520,6 +520,10 @@ int main(int argc, char *argv[]) {
test_strv_unquote(" \"x'\" ", STRV_MAKE("x'"));
test_strv_unquote("a '--b=c \"d e\"'", STRV_MAKE("a", "--b=c \"d e\""));
+ /* trailing backslashes */
+ test_strv_unquote(" x\\\\", STRV_MAKE("x\\"));
+ test_invalid_unquote(" x\\");
+
test_invalid_unquote("a --b='c \"d e\"''");
test_invalid_unquote("a --b='c \"d e\" '\"");
test_invalid_unquote("a --b='c \"d e\"garbage");
diff --git a/src/test/test-util.c b/src/test/test-util.c
index bbf7512..222af9a 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -406,28 +406,12 @@ static void test_foreach_word(void) {
assert_se(strneq(expected[i++], word, l));
}
-static void test_foreach_word_quoted(void) {
+static void check(const char *test, char** expected, bool trailing) {
const char *word, *state;
size_t l;
int i = 0;
- const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
- const char * const expected[] = {
- "test",
- "a",
- "b",
- "c",
- "d",
- "e",
- "",
- "",
- "hhh",
- "",
- "",
- "a b c",
- NULL
- };
- printf("<%s>\n", test);
+ printf("<<<%s>>>\n", test);
FOREACH_WORD_QUOTED(word, l, test, state) {
_cleanup_free_ char *t = NULL;
@@ -435,7 +419,34 @@ static void test_foreach_word_quoted(void) {
assert_se(strneq(expected[i++], word, l));
printf("<%s>\n", t);
}
- assert_se(isempty(state));
+ printf("<<<%s>>>\n", state);
+ assert(expected[i] == NULL);
+ assert_se(isempty(state) == !trailing);
+}
+
+static void test_foreach_word_quoted(void) {
+ check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
+ STRV_MAKE("test",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "",
+ "",
+ "hhh",
+ "",
+ "",
+ "a b c"),
+ false);
+
+ check("test \"xxx",
+ STRV_MAKE("test"),
+ true);
+
+ check("test\\",
+ STRV_MAKE_EMPTY,
+ true);
}
static void test_default_term_for_tty(void) {
--
2.0.5

View File

@ -196,6 +196,10 @@ fi
# https://github.com/coreos/bugs/issues/279
epatch "${FILESDIR}"/218-0006-networkd-fix-systemd-networkd-wait-online-with-multi.patch
# stops systemd from hanging when there's trailing space after a line
# contiuation
epatch "${FILESDIR}"/218-0007-Treat-a-trailing-backslash-as-an-error.patch
autotools-utils_src_prepare
}