summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-07-29 22:01:36 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-07-31 04:00:31 -0400
commita2a5291b3f5ab6ed4c92f51d0fd10a03047380d8 (patch)
tree1a74a85c70861b0a411d9dd325b039976de4fd4e
parent73381fcf54e38456067f0e87b8611a21eff99169 (diff)
Reject invalid quoted strings
String which ended in an unfinished quote were accepted, potentially with bad memory accesses. Reject anything which ends in a unfished quote, or contains non-whitespace characters right after the closing quote. _FOREACH_WORD now returns the invalid character in *state. But this return value is not checked anywhere yet. Also, make 'word' and 'state' variables const pointers, and rename 'w' to 'word' in various places. Things are easier to read if the same name is used consistently. mbiebl_> am I correct that something like this doesn't work mbiebl_> ExecStart=/usr/bin/encfs --extpass='/bin/systemd-ask-passwd "Unlock EncFS"' mbiebl_> systemd seems to strip of the quotes mbiebl_> systemctl status shows mbiebl_> ExecStart=/usr/bin/encfs --extpass='/bin/systemd-ask-password Unlock EncFS $RootDir $MountPoint mbiebl_> which is pretty weird
-rw-r--r--src/core/device.c12
-rw-r--r--src/core/load-fragment.c139
-rw-r--r--src/core/main.c13
-rw-r--r--src/cryptsetup/cryptsetup.c6
-rw-r--r--src/delta/delta.c18
-rw-r--r--src/getty-generator/getty-generator.c12
-rw-r--r--src/journal-remote/journal-remote.c2
-rw-r--r--src/journal/journald-server.c2
-rw-r--r--src/journal/sd-journal.c20
-rw-r--r--src/libsystemd-network/network-internal.c6
-rw-r--r--src/libsystemd/sd-login/sd-login.c22
-rw-r--r--src/login/logind-inhibit.c18
-rw-r--r--src/machine/machine.c6
-rw-r--r--src/nspawn/nspawn.c9
-rw-r--r--src/resolve/resolved-manager.c2
-rw-r--r--src/shared/cgroup-util.c12
-rw-r--r--src/shared/condition-util.c3
-rw-r--r--src/shared/conf-parser.c7
-rw-r--r--src/shared/conf-parser.h6
-rw-r--r--src/shared/install.c7
-rw-r--r--src/shared/log.c6
-rw-r--r--src/shared/path-util.c6
-rw-r--r--src/shared/sleep-config.c19
-rw-r--r--src/shared/strv.c21
-rw-r--r--src/shared/util.c47
-rw-r--r--src/shared/util.h4
-rw-r--r--src/systemctl/systemctl.c6
-rw-r--r--src/sysv-generator/sysv-generator.c12
-rw-r--r--src/test/test-strv.c16
-rw-r--r--src/test/test-util.c15
-rw-r--r--src/timesync/timesyncd.c6
-rw-r--r--src/udev/net/link-config.c6
-rw-r--r--src/udev/udevd.c6
33 files changed, 259 insertions, 233 deletions
diff --git a/src/core/device.c b/src/core/device.c
index 444286e02..2c41c7b6f 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -220,7 +220,7 @@ static int device_make_description(Unit *u, struct udev_device *dev, const char
static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
const char *wants;
- char *state, *w;
+ const char *word, *state;
size_t l;
int r;
@@ -234,11 +234,11 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
if (!wants)
return 0;
- FOREACH_WORD_QUOTED(w, l, wants, state) {
+ FOREACH_WORD_QUOTED(word, l, wants, state) {
_cleanup_free_ char *n = NULL;
char e[l+1];
- memcpy(e, w, l);
+ memcpy(e, word, l);
e[l] = 0;
n = unit_name_mangle(e, MANGLE_NOGLOB);
@@ -393,13 +393,13 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
* aliases */
alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
if (alias) {
- char *state, *w;
+ const char *word, *state;
size_t l;
- FOREACH_WORD_QUOTED(w, l, alias, state) {
+ FOREACH_WORD_QUOTED(word, l, alias, state) {
char e[l+1];
- memcpy(e, w, l);
+ memcpy(e, word, l);
e[l] = 0;
if (path_is_absolute(e))
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 6d8431015..b0448e2c4 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -97,18 +97,18 @@ int config_parse_unit_deps(const char* unit,
UnitDependency d = ltype;
Unit *u = userdata;
- char *w, *state;
+ const char *word, *state;
size_t l;
assert(filename);
assert(lvalue);
assert(rvalue);
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL, *k = NULL;
int r;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -227,7 +227,8 @@ int config_parse_unit_path_strv_printf(
void *data,
void *userdata) {
- char *w, *state, ***x = data;
+ char ***x = data;
+ const char *word, *state;
Unit *u = userdata;
size_t l;
int r;
@@ -237,11 +238,11 @@ int config_parse_unit_path_strv_printf(
assert(rvalue);
assert(u);
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *k = NULL;
char t[l+1];
- memcpy(t, w, l);
+ memcpy(t, word, l);
t[l] = 0;
r = unit_full_printf(u, t, &k);
@@ -533,9 +534,8 @@ int config_parse_exec(const char *unit,
* overriding of argv[0]. */
for (;;) {
int i;
- char *w;
+ const char *word, *state;
size_t l;
- char *state;
bool honour_argv0 = false, ignore = false;
path = NULL;
@@ -566,8 +566,8 @@ int config_parse_exec(const char *unit,
}
k = 0;
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- if (strneq(w, ";", MAX(l, 1U)))
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+ if (strneq(word, ";", MAX(l, 1U)))
break;
k++;
@@ -578,16 +578,16 @@ int config_parse_exec(const char *unit,
return log_oom();
k = 0;
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- if (strneq(w, ";", MAX(l, 1U)))
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+ if (strneq(word, ";", MAX(l, 1U)))
break;
- else if (strneq(w, "\\;", MAX(l, 1U)))
- w ++;
+ else if (strneq(word, "\\;", MAX(l, 1U)))
+ word ++;
- if (honour_argv0 && w == rvalue) {
+ if (honour_argv0 && word == rvalue) {
assert(!path);
- path = strndup(w, l);
+ path = strndup(word, l);
if (!path) {
r = log_oom();
goto fail;
@@ -602,7 +602,7 @@ int config_parse_exec(const char *unit,
} else {
char *c;
- c = n[k++] = cunescape_length(w, l);
+ c = n[k++] = cunescape_length(word, l);
if (!c) {
r = log_oom();
goto fail;
@@ -854,9 +854,8 @@ int config_parse_exec_cpu_affinity(const char *unit,
void *userdata) {
ExecContext *c = data;
- char *w;
+ const char *word, *state;
size_t l;
- char *state;
assert(filename);
assert(lvalue);
@@ -871,12 +870,12 @@ int config_parse_exec_cpu_affinity(const char *unit,
return 0;
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL;
int r;
unsigned cpu;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -945,9 +944,8 @@ int config_parse_exec_secure_bits(const char *unit,
void *userdata) {
ExecContext *c = data;
- char *w;
size_t l;
- char *state;
+ const char *word, *state;
assert(filename);
assert(lvalue);
@@ -960,18 +958,18 @@ int config_parse_exec_secure_bits(const char *unit,
return 0;
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- if (first_word(w, "keep-caps"))
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+ if (first_word(word, "keep-caps"))
c->secure_bits |= 1<<SECURE_KEEP_CAPS;
- else if (first_word(w, "keep-caps-locked"))
+ else if (first_word(word, "keep-caps-locked"))
c->secure_bits |= 1<<SECURE_KEEP_CAPS_LOCKED;
- else if (first_word(w, "no-setuid-fixup"))
+ else if (first_word(word, "no-setuid-fixup"))
c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP;
- else if (first_word(w, "no-setuid-fixup-locked"))
+ else if (first_word(word, "no-setuid-fixup-locked"))
c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP_LOCKED;
- else if (first_word(w, "noroot"))
+ else if (first_word(word, "noroot"))
c->secure_bits |= 1<<SECURE_NOROOT;
- else if (first_word(w, "noroot-locked"))
+ else if (first_word(word, "noroot-locked"))
c->secure_bits |= 1<<SECURE_NOROOT_LOCKED;
else {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
@@ -995,9 +993,8 @@ int config_parse_bounding_set(const char *unit,
void *userdata) {
uint64_t *capability_bounding_set_drop = data;
- char *w;
+ const char *word, *state;
size_t l;
- char *state;
bool invert = false;
uint64_t sum = 0;
@@ -1016,12 +1013,12 @@ int config_parse_bounding_set(const char *unit,
* non-inverted everywhere to have a fully normalized
* interface. */
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL;
int r;
cap_value_t cap;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -1163,9 +1160,8 @@ int config_parse_exec_mount_flags(const char *unit,
void *userdata) {
ExecContext *c = data;
- char *w;
+ const char *word, *state;
size_t l;
- char *state;
unsigned long flags = 0;
assert(filename);
@@ -1173,10 +1169,10 @@ int config_parse_exec_mount_flags(const char *unit,
assert(rvalue);
assert(data);
- FOREACH_WORD_SEPARATOR(w, l, rvalue, ", ", state) {
+ FOREACH_WORD_SEPARATOR(word, l, rvalue, ", ", state) {
_cleanup_free_ char *t;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -1184,7 +1180,7 @@ int config_parse_exec_mount_flags(const char *unit,
flags = MS_SHARED;
else if (streq(t, "slave"))
flags = MS_SLAVE;
- else if (streq(w, "private"))
+ else if (streq(word, "private"))
flags = MS_PRIVATE;
else {
log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse mount flag %s, ignoring: %s", t, rvalue);
@@ -1538,7 +1534,7 @@ int config_parse_service_sockets(const char *unit,
Service *s = data;
int r;
- char *state, *w;
+ const char *word, *state;
size_t l;
assert(filename);
@@ -1546,10 +1542,10 @@ int config_parse_service_sockets(const char *unit,
assert(rvalue);
assert(data);
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL, *k = NULL;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -1780,7 +1776,8 @@ int config_parse_environ(const char *unit,
void *userdata) {
Unit *u = userdata;
- char*** env = data, *w, *state;
+ char*** env = data;
+ const char *word, *state;
size_t l;
_cleanup_free_ char *k = NULL;
int r;
@@ -1809,11 +1806,11 @@ int config_parse_environ(const char *unit,
if (!k)
return log_oom();
- FOREACH_WORD_QUOTED(w, l, k, state) {
+ FOREACH_WORD_QUOTED(word, l, k, state) {
_cleanup_free_ char *n;
char **x;
- n = cunescape_length(w, l);
+ n = cunescape_length(word, l);
if (!n)
return log_oom();
@@ -2052,20 +2049,19 @@ int config_parse_unit_requires_mounts_for(
void *userdata) {
Unit *u = userdata;
- char *state;
+ const char *word, *state;
size_t l;
- char *w;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
int r;
_cleanup_free_ char *n;
- n = strndup(w, l);
+ n = strndup(word, l);
if (!n)
return log_oom();
@@ -2156,7 +2152,7 @@ int config_parse_syscall_filter(
ExecContext *c = data;
Unit *u = userdata;
bool invert = false;
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
@@ -2209,11 +2205,11 @@ int config_parse_syscall_filter(
}
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL;
int id;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -2257,7 +2253,7 @@ int config_parse_syscall_archs(
void *userdata) {
Set **archs = data;
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
@@ -2271,11 +2267,11 @@ int config_parse_syscall_archs(
if (r < 0)
return log_oom();
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL;
uint32_t a;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -2345,7 +2341,7 @@ int config_parse_address_families(
ExecContext *c = data;
Unit *u = userdata;
bool invert = false;
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
@@ -2375,11 +2371,11 @@ int config_parse_address_families(
c->address_families_whitelist = !invert;
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL;
int af;
- t = strndup(w, l);
+ t = strndup(word, l);
if (!t)
return log_oom();
@@ -2874,7 +2870,8 @@ int config_parse_runtime_directory(
void *data,
void *userdata) {
- char***rt = data, *w, *state;
+ char***rt = data;
+ const char *word, *state;
size_t l;
int r;
@@ -2890,10 +2887,10 @@ int config_parse_runtime_directory(
return 0;
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *n;
- n = strndup(w, l);
+ n = strndup(word, l);
if (!n)
return log_oom();
@@ -2924,9 +2921,8 @@ int config_parse_set_status(
void *data,
void *userdata) {
- char *w;
size_t l;
- char *state;
+ const char *word, *state;
int r;
ExitStatusSet *status_set = data;
@@ -2941,11 +2937,11 @@ int config_parse_set_status(
return 0;
}
- FOREACH_WORD(w, l, rvalue, state) {
+ FOREACH_WORD(word, l, rvalue, state) {
_cleanup_free_ char *temp;
int val;
- temp = strndup(w, l);
+ temp = strndup(word, l);
if (!temp)
return log_oom();
@@ -2960,11 +2956,11 @@ int config_parse_set_status(
r = set_put(status_set->signal, INT_TO_PTR(val));
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, -r, "Unable to store: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, -r, "Unable to store: %s", word);
return r;
}
} else {
- log_syntax(unit, LOG_ERR, filename, line, -val, "Failed to parse value, ignoring: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, -val, "Failed to parse value, ignoring: %s", word);
return 0;
}
} else {
@@ -2977,7 +2973,7 @@ int config_parse_set_status(
r = set_put(status_set->status, INT_TO_PTR(val));
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, -r, "Unable to store: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, -r, "Unable to store: %s", word);
return r;
}
}
@@ -2999,7 +2995,8 @@ int config_parse_namespace_path_strv(
void *data,
void *userdata) {
- char*** sv = data, *w, *state;
+ char*** sv = data;
+ const char *word, *state;
size_t l;
int r;
@@ -3015,11 +3012,11 @@ int config_parse_namespace_path_strv(
return 0;
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *n;
int offset;
- n = strndup(w, l);
+ n = strndup(word, l);
if (!n)
return log_oom();
diff --git a/src/core/main.c b/src/core/main.c
index 2741989c4..fad15c7c3 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -455,9 +455,8 @@ static int config_parse_cpu_affinity2(
void *data,
void *userdata) {
- char *w;
+ const char *word, *state;
size_t l;
- char *state;
cpu_set_t *c = NULL;
unsigned ncpus = 0;
@@ -465,12 +464,12 @@ static int config_parse_cpu_affinity2(
assert(lvalue);
assert(rvalue);
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
char *t;
int r;
unsigned cpu;
- if (!(t = strndup(w, l)))
+ if (!(t = strndup(word, l)))
return log_oom();
r = safe_atou(t, &cpu);
@@ -559,7 +558,7 @@ static int config_parse_join_controllers(const char *unit,
void *userdata) {
unsigned n = 0;
- char *state, *w;
+ const char *word, *state;
size_t length;
assert(filename);
@@ -568,10 +567,10 @@ static int config_parse_join_controllers(const char *unit,
free_join_controllers();
- FOREACH_WORD_QUOTED(w, length, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, length, rvalue, state) {
char *s, **l;
- s = strndup(w, length);
+ s = strndup(word, length);
if (!s)
return log_oom();
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 67dc88fa5..94570eb82 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -175,16 +175,16 @@ static int parse_one_option(const char *option) {
}
static int parse_options(const char *options) {
- char *state, *w;
+ const char *word, *state;
size_t l;
int r;
assert(options);
- FOREACH_WORD_SEPARATOR(w, l, options, ",", state) {
+ FOREACH_WORD_SEPARATOR(word, l, options, ",", state) {
_cleanup_free_ char *o;
- o = strndup(w, l);
+ o = strndup(word, l);
if (!o)
return -ENOMEM;
r = parse_one_option(o);
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 96a9fa5ee..dd7523d47 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -488,23 +488,23 @@ static int help(void) {
}
static int parse_flags(const char *flag_str, int flags) {
- char *w, *state;
+ const char *word, *state;
size_t l;
- FOREACH_WORD(w, l, flag_str, state) {
- if (strneq("masked", w, l))
+ FOREACH_WORD(word, l, flag_str, state) {
+ if (strneq("masked", word, l))
flags |= SHOW_MASKED;
- else if (strneq ("equivalent", w, l))
+ else if (strneq ("equivalent", word, l))
flags |= SHOW_EQUIVALENT;
- else if (strneq("redirected", w, l))
+ else if (strneq("redirected", word, l))
flags |= SHOW_REDIRECTED;
- else if (strneq("overridden", w, l))
+ else if (strneq("overridden", word, l))
flags |= SHOW_OVERRIDDEN;
- else if (strneq("unchanged", w, l))
+ else if (strneq("unchanged", word, l))
flags |= SHOW_UNCHANGED;
- else if (strneq("extended", w, l))
+ else if (strneq("extended", word, l))
flags |= SHOW_EXTENDED;
- else if (strneq("default", w, l))
+ else if (strneq("default", word, l))
flags |= SHOW_DEFAULTS;
else
return -EINVAL;
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
index 7d4b546f7..c78a511f9 100644
--- a/src/getty-generator/getty-generator.c
+++ b/src/getty-generator/getty-generator.c
@@ -154,14 +154,14 @@ int main(int argc, char *argv[]) {
r = getenv_for_pid(1, "container_ttys", &container_ttys);
if (r > 0) {
- char *w, *state;
+ const char *word, *state;
size_t l;
- FOREACH_WORD(w, l, container_ttys, state) {
+ FOREACH_WORD(word, l, container_ttys, state) {
const char *t;
char tty[l + 1];
- memcpy(tty, w, l);
+ memcpy(tty, word, l);
tty[l] = 0;
/* First strip off /dev/ if it is specified */
@@ -184,15 +184,15 @@ int main(int argc, char *argv[]) {
}
if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
- char *w, *state;
+ const char *word, *state;
size_t l;
/* Automatically add in a serial getty on all active
* kernel consoles */
- FOREACH_WORD(w, l, active, state) {
+ FOREACH_WORD(word, l, active, state) {
_cleanup_free_ char *tty = NULL;
- tty = strndup(w, l);
+ tty = strndup(word, l);
if (!tty) {
log_oom();
return EXIT_FAILURE;
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index 37ad9029f..3249027b6 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -1344,7 +1344,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_GNUTLS_LOG: {
#ifdef HAVE_GNUTLS
- char *word, *state;
+ const char *word, *state;
size_t size;
FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 4ea9d43c0..eac0a4ca6 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1282,7 +1282,7 @@ static int setup_signals(Server *s) {
static int server_parse_proc_cmdline(Server *s) {
_cleanup_free_ char *line = NULL;
- char *w, *state;
+ const char *w, *state;
size_t l;
int r;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 6349aeb78..01c91e4c0 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -997,7 +997,7 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
}
_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
- char *w, *state;
+ const char *word, *state;
size_t l;
unsigned long long seqnum, monotonic, realtime, xor_hash;
bool
@@ -1013,18 +1013,18 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
assert_return(!journal_pid_changed(j), -ECHILD);
assert_return(!isempty(cursor), -EINVAL);
- FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+ FOREACH_WORD_SEPARATOR(word, l, cursor, ";", state) {
char *item;
int k = 0;
- if (l < 2 || w[1] != '=')
+ if (l < 2 || word[1] != '=')
return -EINVAL;
- item = strndup(w, l);
+ item = strndup(word, l);
if (!item)
return -ENOMEM;
- switch (w[0]) {
+ switch (word[0]) {
case 's':
seqnum_id_set = true;
@@ -1103,7 +1103,7 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
_public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
int r;
- char *w, *state;
+ const char *word, *state;
size_t l;
Object *o;
@@ -1118,20 +1118,20 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
if (r < 0)
return r;
- FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+ FOREACH_WORD_SEPARATOR(word, l, cursor, ";", state) {
_cleanup_free_ char *item = NULL;
sd_id128_t id;
unsigned long long ll;
int k = 0;
- if (l < 2 || w[1] != '=')
+ if (l < 2 || word[1] != '=')
return -EINVAL;
- item = strndup(w, l);
+ item = strndup(word, l);
if (!item)
return -ENOMEM;
- switch (w[0]) {
+ switch (word[0]) {
case 's':
k = sd_id128_from_string(item+2, &id);
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 603ee6dbe..7f744215c 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -354,7 +354,7 @@ void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
int deserialize_in_addrs(struct in_addr **ret, const char *string) {
_cleanup_free_ struct in_addr *addresses = NULL;
int size = 0;
- char *word, *state;
+ const char *word, *state;
size_t len;
assert(ret);
@@ -391,7 +391,7 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) {
int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
_cleanup_free_ struct in6_addr *addresses = NULL;
int size = 0;
- char *word, *state;
+ const char *word, *state;
size_t len;
assert(ret);
@@ -446,7 +446,7 @@ void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *route
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
_cleanup_free_ struct sd_dhcp_route *routes = NULL;
size_t size = 0, allocated = 0;
- char *word, *state;
+ const char *word, *state;
size_t len;
assert(ret);
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 38ff94489..95cb6ff58 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -226,11 +226,10 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) {
}
_public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) {
- char *w, *state;
_cleanup_free_ char *t = NULL, *s = NULL, *p = NULL;
size_t l;
int r;
- const char *variable;
+ const char *word, *variable, *state;
assert_return(seat, -EINVAL);
@@ -251,8 +250,8 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat)
if (asprintf(&t, UID_FMT, uid) < 0)
return -ENOMEM;
- FOREACH_WORD(w, l, s, state) {
- if (strneq(t, w, l))
+ FOREACH_WORD(word, l, s, state) {
+ if (strneq(t, word, l))
return 1;
}
@@ -587,10 +586,10 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
}
if (uids && t) {
- char *w, *state;
+ const char *word, *state;
size_t l;
- FOREACH_WORD(w, l, t, state)
+ FOREACH_WORD(word, l, t, state)
n++;
if (n > 0) {
@@ -600,10 +599,10 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
if (!b)
return -ENOMEM;
- FOREACH_WORD(w, l, t, state) {
+ FOREACH_WORD(word, l, t, state) {
_cleanup_free_ char *k = NULL;
- k = strndup(w, l);
+ k = strndup(word, l);
if (!k)
return -ENOMEM;
@@ -789,9 +788,8 @@ _public_ int sd_machine_get_class(const char *machine, char **class) {
_public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) {
_cleanup_free_ char *netif = NULL;
size_t l, allocated = 0, nr = 0;
- char *w, *state;
int *ni = NULL;
- const char *p;
+ const char *p, *word, *state;
int r;
assert_return(machine_name_is_valid(machine), -EINVAL);
@@ -806,11 +804,11 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) {
return 0;
}
- FOREACH_WORD(w, l, netif, state) {
+ FOREACH_WORD(word, l, netif, state) {
char buf[l+1];
int ifi;
- *(char*) (mempcpy(buf, w, l)) = 0;
+ *(char*) (mempcpy(buf, word, l)) = 0;
if (safe_atoi(buf, &ifi) < 0)
continue;
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index 64a62ffea..a9e14af8d 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -439,23 +439,23 @@ const char *inhibit_what_to_string(InhibitWhat w) {
InhibitWhat inhibit_what_from_string(const char *s) {
InhibitWhat what = 0;
- char *w, *state;
+ const char *word, *state;
size_t l;
- FOREACH_WORD_SEPARATOR(w, l, s, ":", state) {
- if (l == 8 && strneq(w, "shutdown", l))
+ FOREACH_WORD_SEPARATOR(word, l, s, ":", state) {
+ if (l == 8 && strneq(word, "shutdown", l))
what |= INHIBIT_SHUTDOWN;
- else if (l == 5 && strneq(w, "sleep", l))
+ else if (l == 5 && strneq(word, "sleep", l))
what |= INHIBIT_SLEEP;
- else if (l == 4 && strneq(w, "idle", l))
+ else if (l == 4 && strneq(word, "idle", l))
what |= INHIBIT_IDLE;
- else if (l == 16 && strneq(w, "handle-power-key", l))
+ else if (l == 16 && strneq(word, "handle-power-key", l))
what |= INHIBIT_HANDLE_POWER_KEY;
- else if (l == 18 && strneq(w, "handle-suspend-key", l))
+ else if (l == 18 && strneq(word, "handle-suspend-key", l))
what |= INHIBIT_HANDLE_SUSPEND_KEY;
- else if (l == 20 && strneq(w, "handle-hibernate-key", l))
+ else if (l == 20 && strneq(word, "handle-hibernate-key", l))
what |= INHIBIT_HANDLE_HIBERNATE_KEY;
- else if (l == 17 && strneq(w, "handle-lid-switch", l))
+ else if (l == 17 && strneq(word, "handle-lid-switch", l))
what |= INHIBIT_HANDLE_LID_SWITCH;
else
return _INHIBIT_WHAT_INVALID;
diff --git a/src/machine/machine.c b/src/machine/machine.c
index 0ed18d74e..1c9177e1c 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -291,14 +291,14 @@ int machine_load(Machine *m) {
if (netif) {
size_t l, allocated = 0, nr = 0;
- char *w, *state;
+ const char *word, *state;
int *ni = NULL;
- FOREACH_WORD(w, l, netif, state) {
+ FOREACH_WORD(word, l, netif, state) {
char buf[l+1];
int ifi;
- *(char*) (mempcpy(buf, w, l)) = 0;
+ *(char*) (mempcpy(buf, word, l)) = 0;
if (safe_atoi(buf, &ifi) < 0)
continue;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 7c47f6ecd..ddf1c371a 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -395,7 +395,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_CAPABILITY:
case ARG_DROP_CAPABILITY: {
- char *state, *word;
+ const char *state, *word;
size_t length;
FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) {
@@ -2602,7 +2602,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
}
static int change_uid_gid(char **_home) {
- char line[LINE_MAX], *w, *x, *state, *u, *g, *h;
+ char line[LINE_MAX], *x, *u, *g, *h;
+ const char *word, *state;
_cleanup_free_ uid_t *uids = NULL;
_cleanup_free_ char *home = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -2752,10 +2753,10 @@ static int change_uid_gid(char **_home) {
x += strcspn(x, WHITESPACE);
x += strspn(x, WHITESPACE);
- FOREACH_WORD(w, l, x, state) {
+ FOREACH_WORD(word, l, x, state) {
char c[l+1];
- memcpy(c, w, l);
+ memcpy(c, word, l);
c[l] = 0;
if (!GREEDY_REALLOC(uids, sz, n_uids+1))
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 319baf788..995621c91 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -304,7 +304,7 @@ static int manager_network_monitor_listen(Manager *m) {
}
static int parse_dns_server_string(Manager *m, const char *string) {
- char *word, *state;
+ const char *word, *state;
size_t length;
int r;
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index c1c4d409a..f683ae990 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -753,9 +753,9 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
cs = strlen(controller);
FOREACH_LINE(line, f, return -errno) {
- char *l, *p, *w, *e;
+ char *l, *p, *e;
size_t k;
- char *state;
+ const char *word, *state;
bool found = false;
truncate_nl(line);
@@ -771,16 +771,16 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
*e = 0;
- FOREACH_WORD_SEPARATOR(w, k, l, ",", state) {
+ FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
- if (k == cs && memcmp(w, controller, cs) == 0) {
+ if (k == cs && memcmp(word, controller, cs) == 0) {
found = true;
break;
}
if (k == 5 + cs &&
- memcmp(w, "name=", 5) == 0 &&
- memcmp(w+5, controller, cs) == 0) {
+ memcmp(word, "name=", 5) == 0 &&
+ memcmp(word+5, controller, cs) == 0) {
found = true;
break;
}
diff --git a/src/shared/condition-util.c b/src/shared/condition-util.c
index 928edeeb9..f88ddc19e 100644
--- a/src/shared/condition-util.c
+++ b/src/shared/condition-util.c
@@ -74,7 +74,8 @@ void condition_free_list(Condition *first) {
}
bool condition_test_kernel_command_line(Condition *c) {
- char *line, *w, *state, *word = NULL;
+ char *line, *word = NULL;
+ const char *w, *state;
bool equal;
int r;
size_t l, pl;
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 0be722687..cd189adfc 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -675,7 +675,8 @@ int config_parse_strv(const char *unit,
void *data,
void *userdata) {
- char *** sv = data, *w, *state;
+ char ***sv = data;
+ const char *word, *state;
size_t l;
int r;
@@ -700,10 +701,10 @@ int config_parse_strv(const char *unit,
return 0;
}
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
char *n;
- n = strndup(w, l);
+ n = strndup(word, l);
if (!n)
return log_oom();
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index ea7b710de..a17dde906 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -170,7 +170,7 @@ int log_syntax_internal(const char *unit, int level,
void *userdata) { \
\
type **enums = data, *xs, x, *ys; \
- char *w, *state; \
+ const char *word, *state; \
size_t l, i = 0; \
\
assert(filename); \
@@ -181,10 +181,10 @@ int log_syntax_internal(const char *unit, int level,
xs = new0(type, 1); \
*xs = invalid; \
\
- FOREACH_WORD(w, l, rvalue, state) { \
+ FOREACH_WORD(word, l, rvalue, state) { \
_cleanup_free_ char *en = NULL; \
\
- en = strndup(w, l); \
+ en = strndup(word, l); \
if (!en) \
return -ENOMEM; \
\
diff --git a/src/shared/install.c b/src/shared/install.c
index cc61c01e2..c32d6599a 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -946,20 +946,19 @@ static int config_parse_also(
void *data,
void *userdata) {
- char *w;
size_t l;
- char *state;
+ const char *word, *state;
InstallContext *c = data;
assert(filename);
assert(lvalue);
assert(rvalue);
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *n;
int r;
- n = strndup(w, l);
+ n = strndup(word, l);
if (!n)
return -ENOMEM;
diff --git a/src/shared/log.c b/src/shared/log.c
index 3941e3e1c..a7c3195f3 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -871,11 +871,11 @@ void log_parse_environment(void) {
if (r < 0)
log_warning("Failed to read /proc/cmdline. Ignoring: %s", strerror(-r));
else if (r > 0) {
- char *w, *state;
+ const char *word, *state;
size_t l;
- FOREACH_WORD_QUOTED(w, l, line, state) {
- if (l == 5 && startswith(w, "debug")) {
+ FOREACH_WORD_QUOTED(word, l, line, state) {
+ if (l == 5 && startswith(word, "debug")) {
log_set_max_level(LOG_DEBUG);
break;
}
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index 5bc5012fe..57554cd29 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -574,7 +574,7 @@ int find_binary(const char *name, char **filename) {
return 0;
} else {
const char *path;
- char *state, *w;
+ const char *word, *state;
size_t l;
/**
@@ -585,10 +585,10 @@ int find_binary(const char *name, char **filename) {
if (!path)
path = DEFAULT_PATH;
- FOREACH_WORD_SEPARATOR(w, l, path, ":", state) {
+ FOREACH_WORD_SEPARATOR(word, l, path, ":", state) {
_cleanup_free_ char *p = NULL;
- if (asprintf(&p, "%.*s/%s", (int) l, w, name) < 0)
+ if (asprintf(&p, "%.*s/%s", (int) l, word, name) < 0)
return -ENOMEM;
if (access(p, X_OK) < 0)
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index 16a488d56..d8de644a9 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -98,7 +98,7 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
}
int can_sleep_state(char **types) {
- char *w, *state, **type;
+ char **type;
int r;
_cleanup_free_ char *p = NULL;
@@ -114,11 +114,12 @@ int can_sleep_state(char **types) {
return false;
STRV_FOREACH(type, types) {
+ const char *word, *state;
size_t l, k;
k = strlen(*type);
- FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
- if (l == k && memcmp(w, *type, l) == 0)
+ FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state)
+ if (l == k && memcmp(word, *type, l) == 0)
return true;
}
@@ -126,7 +127,7 @@ int can_sleep_state(char **types) {
}
int can_sleep_disk(char **types) {
- char *w, *state, **type;
+ char **type;
int r;
_cleanup_free_ char *p = NULL;
@@ -142,14 +143,18 @@ int can_sleep_disk(char **types) {
return false;
STRV_FOREACH(type, types) {
+ const char *word, *state;
size_t l, k;
k = strlen(*type);
- FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
- if (l == k && memcmp(w, *type, l) == 0)
+ FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state) {
+ if (l == k && memcmp(word, *type, l) == 0)
return true;
- if (l == k + 2 && w[0] == '[' && memcmp(w + 1, *type, l - 2) == 0 && w[l-1] == ']')
+ if (l == k + 2 &&
+ word[0] == '[' &&
+ memcmp(word + 1, *type, l - 2) == 0 &&
+ word[l-1] == ']')
return true;
}
}
diff --git a/src/shared/strv.c b/src/shared/strv.c
index b4c476eff..0ac66b927 100644
--- a/src/shared/strv.c
+++ b/src/shared/strv.c
@@ -201,8 +201,7 @@ int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
}
char **strv_split(const char *s, const char *separator) {
- char *state;
- char *w;
+ const char *word, *state;
size_t l;
unsigned n, i;
char **r;
@@ -210,7 +209,7 @@ char **strv_split(const char *s, const char *separator) {
assert(s);
n = 0;
- FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
+ FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
n++;
r = new(char*, n+1);
@@ -218,8 +217,8 @@ char **strv_split(const char *s, const char *separator) {
return NULL;
i = 0;
- FOREACH_WORD_SEPARATOR(w, l, s, separator, state) {
- r[i] = strndup(w, l);
+ FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
+ r[i] = strndup(word, l);
if (!r[i]) {
strv_free(r);
return NULL;
@@ -233,8 +232,7 @@ char **strv_split(const char *s, const char *separator) {
}
char **strv_split_quoted(const char *s) {
- char *state;
- char *w;
+ const char *word, *state;
size_t l;
unsigned n, i;
char **r;
@@ -242,16 +240,19 @@ char **strv_split_quoted(const char *s) {
assert(s);
n = 0;
- FOREACH_WORD_QUOTED(w, l, s, state)
+ FOREACH_WORD_QUOTED(word, l, s, state)
n++;
+ if (*state)
+ /* bad syntax */
+ return NULL;
r = new(char*, n+1);
if (!r)
return NULL;
i = 0;
- FOREACH_WORD_QUOTED(w, l, s, state) {
- r[i] = cunescape_length(w, l);
+ FOREACH_WORD_QUOTED(word, l, s, state) {
+ r[i] = cunescape_length(word, l);
if (!r[i]) {
strv_free(r);
return NULL;
diff --git a/src/shared/util.c b/src/shared/util.c
index d8a75bdc6..cb9687cb0 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -415,37 +415,50 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
else if (s[n] == '\\')
escaped = true;
else if (strchr(reject, s[n]))
- return n;
+ break;
}
- return n;
+ /* if s ends in \, return index of previous char */
+ return n - escaped;
}
/* Split a string into words. */
-char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
- char *current;
+const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
+ const char *current;
- current = *state ? *state : (char*) c;
+ current = *state;
- if (!*current || *c == 0)
+ if (!*current) {
+ assert(**state == '\0');
return NULL;
+ }
current += strspn(current, separator);
- if (!*current)
+ if (!*current) {
+ *state = current;
return NULL;
+ }
if (quoted && strchr("\'\"", *current)) {
- char quotechar = *(current++);
- *l = strcspn_escaped(current, (char[]){quotechar, '\0'});
- *state = current+*l+1;
+ char quotechars[2] = {*current, '\0'};
+
+ *l = strcspn_escaped(current + 1, quotechars);
+ if (current[*l + 1] == '\0' ||
+ (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
+ /* right quote missing or garbage at the end*/
+ *state = current;
+ return NULL;
+ }
+ assert(current[*l + 1] == quotechars[0]);
+ *state = current++ + *l + 2;
} else if (quoted) {
*l = strcspn_escaped(current, separator);
- *state = current+*l;
+ *state = current + *l;
} else {
*l = strcspn(current, separator);
- *state = current+*l;
+ *state = current + *l;
}
- return (char*) current;
+ return current;
}
int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
@@ -6059,7 +6072,7 @@ int split_pair(const char *s, const char *sep, char **l, char **r) {
int shall_restore_state(void) {
_cleanup_free_ char *line = NULL;
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
@@ -6071,12 +6084,12 @@ int shall_restore_state(void) {
r = 1;
- FOREACH_WORD_QUOTED(w, l, line, state) {
+ FOREACH_WORD_QUOTED(word, l, line, state) {
const char *e;
char n[l+1];
int k;
- memcpy(n, w, l);
+ memcpy(n, word, l);
n[l] = 0;
e = startswith(n, "systemd.restore_state=");
@@ -6120,7 +6133,7 @@ int proc_cmdline(char **ret) {
int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
_cleanup_free_ char *line = NULL;
- char *w, *state;
+ const char *w, *state;
size_t l;
int r;
diff --git a/src/shared/util.h b/src/shared/util.h
index 81da59b20..45294800e 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -234,7 +234,7 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) {
return safe_atolli(s, (long long int*) ret_i);
}
-char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state);
+const char* split(const char **state, size_t *l, const char *separator, bool quoted);
#define FOREACH_WORD(word, length, s, state) \
_FOREACH_WORD(word, length, s, WHITESPACE, false, state)
@@ -249,7 +249,7 @@ char *split(const char *c, size_t *l, const char *separator, bool quoted, char *
_FOREACH_WORD(word, length, s, separator, true, state)
#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
- for ((state) = NULL, (word) = split((s), &(length), (separator), (quoted), &(state)); (word); (word) = split((s), &(length), (separator), (quoted), &(state)))
+ for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
int get_starttime_of_pid(pid_t pid, unsigned long long *st);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 4699a670f..21e33d5bf 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -5733,7 +5733,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return 0;
case 't': {
- char *word, *state;
+ const char *word, *state;
size_t size;
FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
@@ -5782,7 +5782,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
if (!arg_properties)
return log_oom();
} else {
- char *word, *state;
+ const char *word, *state;
size_t size;
FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
@@ -5952,7 +5952,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_STATE: {
- char *word, *state;
+ const char *word, *state;
size_t size;
FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 9a869badc..cfae1d75b 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -442,15 +442,15 @@ static int load_sysv(SysvStub *s) {
} else if (state == LSB || state == LSB_DESCRIPTION) {
if (startswith_no_case(t, "Provides:")) {
- char *i, *w;
+ const char *word, *state_;
size_t z;
state = LSB;
- FOREACH_WORD_QUOTED(w, z, t+9, i) {
+ FOREACH_WORD_QUOTED(word, z, t+9, state_) {
_cleanup_free_ char *n = NULL, *m = NULL;
- n = strndup(w, z);
+ n = strndup(word, z);
if (!n)
return -ENOMEM;
@@ -499,16 +499,16 @@ static int load_sysv(SysvStub *s) {
startswith_no_case(t, "Should-Start:") ||
startswith_no_case(t, "X-Start-Before:") ||
startswith_no_case(t, "X-Start-After:")) {
- char *i, *w;
+ const char *word, *state_;
size_t z;
state = LSB;
- FOREACH_WORD_QUOTED(w, z, strchr(t, ':')+1, i) {
+ FOREACH_WORD_QUOTED(word, z, strchr(t, ':')+1, state_) {
_cleanup_free_ char *n = NULL, *m = NULL;
bool is_before;
- n = strndup(w, z);
+ n = strndup(word, z);
if (!n)
return -ENOMEM;
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index 370219121..cdd2a539a 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -159,12 +159,15 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
static void test_strv_unquote(const char *quoted, const char **list) {
_cleanup_strv_free_ char **s;
+ _cleanup_free_ char *j;
unsigned i = 0;
char **t;
s = strv_split_quoted(quoted);
assert_se(s);
- strv_print(s);
+ j = strv_join(s, " | ");
+ assert(j);
+ puts(j);
STRV_FOREACH(t, s)
assert_se(streq(list[i++], *t));
@@ -172,6 +175,13 @@ static void test_strv_unquote(const char *quoted, const char **list) {
assert_se(list[i] == NULL);
}
+static void test_invalid_unquote(const char *quoted) {
+ char **s;
+
+ s = strv_split_quoted(quoted);
+ assert(s == NULL);
+}
+
static void test_strv_split(void) {
char **s;
unsigned i = 0;
@@ -428,7 +438,9 @@ int main(int argc, char *argv[]) {
test_strv_unquote(" \"x'\" ", (const char*[]) { "x'", NULL });
test_strv_unquote("a '--b=c \"d e\"'", (const char*[]) { "a", "--b=c \"d e\"", NULL });
- test_strv_unquote("a --b='c \"d e\"'", (const char*[]) { "a", "--b='c", "\"d", "e\"'", NULL });
+ 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");
test_strv_split();
test_strv_split_newlines();
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 9a28ef9ee..a56b35567 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -311,7 +311,7 @@ static void test_cunescape(void) {
}
static void test_foreach_word(void) {
- char *w, *state;
+ const char *word, *state;
size_t l;
int i = 0;
const char test[] = "test abc d\te f ";
@@ -325,13 +325,12 @@ static void test_foreach_word(void) {
NULL
};
- FOREACH_WORD(w, l, test, state) {
- assert_se(strneq(expected[i++], w, l));
- }
+ FOREACH_WORD(word, l, test, state)
+ assert_se(strneq(expected[i++], word, l));
}
static void test_foreach_word_quoted(void) {
- char *w, *state;
+ const char *word, *state;
size_t l;
int i = 0;
const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
@@ -352,11 +351,11 @@ static void test_foreach_word_quoted(void) {
};
printf("<%s>\n", test);
- FOREACH_WORD_QUOTED(w, l, test, state) {
+ FOREACH_WORD_QUOTED(word, l, test, state) {
_cleanup_free_ char *t = NULL;
- assert_se(t = strndup(w, l));
- assert_se(strneq(expected[i++], w, l));
+ assert_se(t = strndup(word, l));
+ assert_se(strneq(expected[i++], word, l));
printf("<%s>\n", t);
}
}
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index b80e03b34..8bb79fb5e 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -984,17 +984,17 @@ static int manager_add_server(Manager *m, const char *server) {
}
static int manager_add_server_string(Manager *m, const char *string) {
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
assert(m);
assert(string);
- FOREACH_WORD_QUOTED(w, l, string, state) {
+ FOREACH_WORD_QUOTED(word, l, string, state) {
char t[l+1];
- memcpy(t, w, l);
+ memcpy(t, word, l);
t[l] = 0;
r = manager_add_server(m, t);
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 512885f9c..946715ce5 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -193,7 +193,7 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
static bool enable_name_policy(void) {
_cleanup_free_ char *line = NULL;
- char *w, *state;
+ const char *word, *state;
int r;
size_t l;
@@ -203,8 +203,8 @@ static bool enable_name_policy(void) {
if (r <= 0)
return true;
- FOREACH_WORD_QUOTED(w, l, line, state)
- if (strneq(w, "net.ifnames=0", l))
+ FOREACH_WORD_QUOTED(word, l, line, state)
+ if (strneq(word, "net.ifnames=0", l))
return false;
return true;
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index b75145eeb..f882cfb3a 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -956,7 +956,7 @@ static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) {
*/
static void kernel_cmdline_options(struct udev *udev) {
_cleanup_free_ char *line = NULL;
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
@@ -966,10 +966,10 @@ static void kernel_cmdline_options(struct udev *udev) {
if (r <= 0)
return;
- FOREACH_WORD_QUOTED(w, l, line, state) {
+ FOREACH_WORD_QUOTED(word, l, line, state) {
char *s, *opt;
- s = strndup(w, l);
+ s = strndup(word, l);
if (!s)
break;