chiark / gitweb /
Reject invalid quoted strings
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 30 Jul 2014 02:01:36 +0000 (22:01 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 31 Jul 2014 08:00:31 +0000 (04:00 -0400)
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

33 files changed:
src/core/device.c
src/core/load-fragment.c
src/core/main.c
src/cryptsetup/cryptsetup.c
src/delta/delta.c
src/getty-generator/getty-generator.c
src/journal-remote/journal-remote.c
src/journal/journald-server.c
src/journal/sd-journal.c
src/libsystemd-network/network-internal.c
src/libsystemd/sd-login/sd-login.c
src/login/logind-inhibit.c
src/machine/machine.c
src/nspawn/nspawn.c
src/resolve/resolved-manager.c
src/shared/cgroup-util.c
src/shared/condition-util.c
src/shared/conf-parser.c
src/shared/conf-parser.h
src/shared/install.c
src/shared/log.c
src/shared/path-util.c
src/shared/sleep-config.c
src/shared/strv.c
src/shared/util.c
src/shared/util.h
src/systemctl/systemctl.c
src/sysv-generator/sysv-generator.c
src/test/test-strv.c
src/test/test-util.c
src/timesync/timesyncd.c
src/udev/net/link-config.c
src/udev/udevd.c

index 444286e02b2a7bfc14bd3a5b3c6bab6f10f1955b..2c41c7b6f44964b787ebdf4cfef72cbec6b4b353 100644 (file)
@@ -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))
index 6d8431015da00394520a4dced4a755f12a5ac1fb..b0448e2c4b3277c035721aa3840ff6aec307aa3d 100644 (file)
@@ -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();
 
index 2741989c4864ac10cc5b3c8dbb3e18eb10db58b6..fad15c7c3f3d88443e16677724fdd4f3024b7161 100644 (file)
@@ -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();
 
index 67dc88fa515c37a02eef4d366badac4399a35203..94570eb82d07ac9b836907d86b8cadfb34305176 100644 (file)
@@ -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);
index 96a9fa5ee14e0378ab643c8b29790f29cfddeaf7..dd7523d473ad343478cd42a6f290cf003b066746 100644 (file)
@@ -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;
index 7d4b546f72751af2508832c445f091387ddedf8b..c78a511f94da878cba6e7d53de5dc208b6756474 100644 (file)
@@ -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;
index 37ad9029fd008b39771b80a6ceb80f225a64abe8..3249027b63d93e524efbd5b40bc99024a6451719 100644 (file)
@@ -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) {
index 4ea9d43c0dc1ce60369323d3cb1aa245d979453f..eac0a4ca67ede68e7dcd40ad70ee44c343e79fee 100644 (file)
@@ -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;
 
index 6349aeb78545a9995d35e631ea5c3a117063e9f9..01c91e4c02780f1148fd5d9cc784a411a667998f 100644 (file)
@@ -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);
index 603ee6dbe978de0db9234d29948faac6d0b8bbae..7f744215cc14569f7c238fd37c27efe6c8ae79d8 100644 (file)
@@ -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);
index 38ff944892ca5abcf75c01add375b16759378703..95cb6ff5812c1dd95119377d24ac8e7839b982b2 100644 (file)
@@ -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;
index 64a62ffeae6f51b0f3f86aed4e39aa6275621006..a9e14af8dbf29148b1f510a765740f9d70f17a1b 100644 (file)
@@ -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;
index 0ed18d74ece89a8c0680e6f70b73a79ba0c74728..1c9177e1c379b9a60ad2a7424b42bf2b8af8b4a6 100644 (file)
@@ -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;
index 7c47f6ecd2434356a3a1f6851fbdeaca2238f5bc..ddf1c371a0f7459182e56ef2b046dabfd037ef97 100644 (file)
@@ -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))
index 319baf7887d84b0d210a621af005efb11b790d39..995621c9156235b0d139418353548d402e5c219b 100644 (file)
@@ -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;
 
index c1c4d409ae5ee6bcc30d5d743473417861dbc6e4..f683ae990ed2ffdbb77d464709ac554959f78019 100644 (file)
@@ -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;
                         }
index 928edeeb9dbc9d7dfe5f1bbf5d0bf2fa88bdadf2..f88ddc19e29461e02d05b00639d8c7bbc9d789d1 100644 (file)
@@ -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;
index 0be7226871218e0a38f687ad59d6a55ca6fc9dc2..cd189adfc3e9813b5af2fa327d761941662736eb 100644 (file)
@@ -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();
 
index ea7b710dece722b5cecb1ed90c809a579029fa86..a17dde90699b8e5814cc7c2d52e0912b963aa5aa 100644 (file)
@@ -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;                                \
                                                                                \
index cc61c01e20d05ad2587606a3fa725f6e45de4037..c32d6599a68ef1906ebd949efb62d9c973722708 100644 (file)
@@ -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;
 
index 3941e3e1c202d0015b42e9ebff3a93174003efb0..a7c3195f3923680efaa88e5131ccca5724780e1d 100644 (file)
@@ -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;
                         }
index 5bc5012fe89ed61900f038dd260d348593ec58fd..57554cd294613eed7068c6a978edb0f01149f768 100644 (file)
@@ -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)
index 16a488d56b982537385c3588cc62f2bbc0a06e9f..d8de644a92cd692bf4a25937fec932bbbe297646 100644 (file)
@@ -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;
                 }
         }
index b4c476eff27df9858698ad4f52e66210b6696bb7..0ac66b927c167d166a4918c7c85fbca5f2cc7780 100644 (file)
@@ -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;
index d8a75bdc6a5c156af242e42090d83bfc62f0efc4..cb9687cb02085703fa4416d083625abacc65c3d9 100644 (file)
@@ -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;
 
index 81da59b20cf68cfae46c53ea538dd238a7babff4..45294800e4dcf4556556092146265f1643ec608c 100644 (file)
@@ -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);
index 4699a670f7791ee1bf2b9ea0f14daca19fbcfcc9..21e33d5bfc9607de6b4c8066bdddf6f850126d31 100644 (file)
@@ -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) {
index 9a869badcade5f65fa967e48860c07962d75acc3..cfae1d75b3b2ece288ba0a87c239c8847e498e47 100644 (file)
@@ -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;
 
index 370219121bc9a3b4b26b9df9eb2c6fb65737b255..cdd2a539af9f024d9af91084e76678bb760e4462 100644 (file)
@@ -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();
index 9a28ef9eec4a2d73075ab50acf4fec523f31ca73..a56b3556728c3d55cd217e2df78e700945b32f74 100644 (file)
@@ -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);
         }
 }
index b80e03b349340fcfbdbc0dcfa90ff7f8652a0c97..8bb79fb5ee339fc9f8e574b5600f726ac314148c 100644 (file)
@@ -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);
index 512885f9c8604ced0757f4dd476133e7b3ab9dc8..946715ce5a106911819982898beab5329b813a52 100644 (file)
@@ -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;
index b75145eebfbbcfaca30e5a41db8e8ad62798557a..f882cfb3ad43540065c783f2a97484051813d32f 100644 (file)
@@ -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;