mirror of
https://github.com/systemd/systemd.git
synced 2026-08-03 22:50:29 +00:00
util: Don't interpret quotes by default in extract_first_word
This adds an EXTRACT_QUOTES option to allow the previous behaviour, of not interpreting any character inside ' or " quotes as separators.
This commit is contained in:
@@ -289,7 +289,7 @@ int strv_split_quoted(char ***t, const char *s, ExtractFlags flags) {
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&s, &word, NULL, flags);
|
||||
r = extract_first_word(&s, &word, NULL, flags|EXTRACT_QUOTES);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
|
||||
@@ -4843,7 +4843,7 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
char *value = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_RELAX);
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
@@ -4883,7 +4883,7 @@ int get_proc_cmdline_key(const char *key, char **value) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
const char *e;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_RELAX);
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
@@ -5746,14 +5746,14 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
case VALUE:
|
||||
if (c == 0)
|
||||
goto finish_force_terminate;
|
||||
else if (c == '\'') {
|
||||
else if (c == '\'' && (flags & EXTRACT_QUOTES)) {
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+1))
|
||||
return -ENOMEM;
|
||||
|
||||
state = SINGLE_QUOTE;
|
||||
} else if (c == '\\')
|
||||
state = VALUE_ESCAPE;
|
||||
else if (c == '\"') {
|
||||
else if (c == '\"' && (flags & EXTRACT_QUOTES)) {
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+1))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -858,6 +858,7 @@ typedef enum ExtractFlags {
|
||||
EXTRACT_RELAX = 1,
|
||||
EXTRACT_CUNESCAPE = 2,
|
||||
EXTRACT_CUNESCAPE_RELAX = 4,
|
||||
EXTRACT_QUOTES = 8,
|
||||
} ExtractFlags;
|
||||
|
||||
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
|
||||
|
||||
@@ -552,7 +552,7 @@ int config_parse_exec(
|
||||
|
||||
semicolon = false;
|
||||
|
||||
r = extract_first_word_and_warn(&p, &firstword, WHITESPACE, EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
|
||||
r = extract_first_word_and_warn(&p, &firstword, WHITESPACE, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
@@ -642,7 +642,7 @@ int config_parse_exec(
|
||||
continue;
|
||||
}
|
||||
|
||||
r = extract_first_word_and_warn(&p, &word, WHITESPACE, EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
|
||||
r = extract_first_word_and_warn(&p, &word, WHITESPACE, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
|
||||
if (r == 0)
|
||||
break;
|
||||
else if (r < 0)
|
||||
|
||||
@@ -101,7 +101,7 @@ static int condition_test_kernel_command_line(Condition *c) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
bool found;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_RELAX);
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
|
||||
@@ -1380,7 +1380,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
|
||||
/* Parse columns */
|
||||
p = buffer;
|
||||
r = extract_many_words(&p, NULL, 0, &action, &name, &id, &description, &home, NULL);
|
||||
r = extract_many_words(&p, NULL, EXTRACT_QUOTES, &action, &name, &id, &description, &home, NULL);
|
||||
if (r < 0) {
|
||||
log_error("[%s:%u] Syntax error.", fname, line);
|
||||
return r;
|
||||
|
||||
@@ -1508,11 +1508,26 @@ static void test_extract_first_word(void) {
|
||||
|
||||
p = original = "\"foobar\" \'waldo\'";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
|
||||
assert_se(streq(t, "foobar"));
|
||||
assert_se(streq(t, "\"foobar\""));
|
||||
free(t);
|
||||
assert_se(p == original + 9);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
|
||||
assert_se(streq(t, "\'waldo\'"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
|
||||
assert_se(!t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"foobar\" \'waldo\'";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
|
||||
assert_se(streq(t, "foobar"));
|
||||
free(t);
|
||||
assert_se(p == original + 9);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
|
||||
assert_se(streq(t, "waldo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1522,25 +1537,46 @@ static void test_extract_first_word(void) {
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
|
||||
assert_se(streq(t, "\""));
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
|
||||
assert_se(p == original + 1);
|
||||
|
||||
p = original = "\'";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
|
||||
assert_se(streq(t, "\'"));
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\'";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
|
||||
assert_se(p == original + 1);
|
||||
|
||||
p = original = "\'fooo";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
|
||||
assert_se(streq(t, "\'fooo"));
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\'fooo";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
|
||||
assert_se(p == original + 5);
|
||||
|
||||
p = original = "\'fooo";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
|
||||
assert_se(streq(t, "fooo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "yay\'foo\'bar";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
|
||||
assert_se(streq(t, "yay\'foo\'bar"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "yay\'foo\'bar";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
|
||||
assert_se(streq(t, "yayfoobar"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1569,7 +1605,7 @@ static void test_extract_first_word(void) {
|
||||
free(t);
|
||||
assert_se(p == original + 13);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
|
||||
assert_se(streq(t, "pi\360\237\222\251le"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1603,7 +1639,7 @@ static void test_extract_first_word(void) {
|
||||
assert_se(p == original + 5);
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
|
||||
assert_se(streq(t, "foo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1639,17 +1675,17 @@ static void test_extract_first_word(void) {
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
|
||||
assert_se(p == original + 5);
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
|
||||
assert_se(streq(t, "foo\\"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
|
||||
assert_se(streq(t, "foo\\"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1699,12 +1735,12 @@ static void test_extract_first_word(void) {
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "-N ''";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
|
||||
assert_se(streq(t, "-N"));
|
||||
free(t);
|
||||
assert_se(p == original + 3);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
|
||||
assert_se(streq(t, ""));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1730,12 +1766,12 @@ static void test_extract_first_word_and_warn(void) {
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"foobar\" \'waldo\'";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
|
||||
assert_se(streq(t, "foobar"));
|
||||
free(t);
|
||||
assert_se(p == original + 9);
|
||||
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
|
||||
assert_se(streq(t, "waldo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1745,19 +1781,19 @@ static void test_extract_first_word_and_warn(void) {
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(p == original + 1);
|
||||
|
||||
p = original = "\'";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(p == original + 1);
|
||||
|
||||
p = original = "\'fooo";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(p == original + 5);
|
||||
|
||||
p = original = "\'fooo";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
|
||||
assert_se(streq(t, "fooo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1780,7 +1816,7 @@ static void test_extract_first_word_and_warn(void) {
|
||||
free(t);
|
||||
assert_se(p == original + 13);
|
||||
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
|
||||
assert_se(streq(t, "pi\360\237\222\251le"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1804,21 +1840,21 @@ static void test_extract_first_word_and_warn(void) {
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(p == original + 5);
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
|
||||
assert_se(streq(t, "foo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
|
||||
assert_se(p == original + 5);
|
||||
|
||||
p = original = "\"foo\\";
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
|
||||
assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
|
||||
assert_se(streq(t, "foo"));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
@@ -1871,6 +1907,15 @@ static void test_extract_many_words(void) {
|
||||
p = original = "'foobar' wa\"ld\"i ";
|
||||
assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
|
||||
assert_se(isempty(p));
|
||||
assert_se(streq_ptr(a, "'foobar'"));
|
||||
assert_se(streq_ptr(b, "wa\"ld\"i"));
|
||||
assert_se(streq_ptr(c, NULL));
|
||||
free(a);
|
||||
free(b);
|
||||
|
||||
p = original = "'foobar' wa\"ld\"i ";
|
||||
assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
|
||||
assert_se(isempty(p));
|
||||
assert_se(streq_ptr(a, "foobar"));
|
||||
assert_se(streq_ptr(b, "waldi"));
|
||||
assert_se(streq_ptr(c, NULL));
|
||||
|
||||
@@ -662,7 +662,7 @@ static int parse_xattrs_from_arg(Item *i) {
|
||||
for (;;) {
|
||||
_cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL, *xattr_replaced = NULL;
|
||||
|
||||
r = extract_first_word(&p, &xattr, NULL, EXTRACT_CUNESCAPE);
|
||||
r = extract_first_word(&p, &xattr, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse extended attribute '%s', ignoring: %m", p);
|
||||
if (r <= 0)
|
||||
@@ -1763,7 +1763,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
r = extract_many_words(
|
||||
&buffer,
|
||||
NULL,
|
||||
0,
|
||||
EXTRACT_QUOTES,
|
||||
&action,
|
||||
&path,
|
||||
&mode,
|
||||
|
||||
Reference in New Issue
Block a user