summary refs log tree commit diff
path: root/shared/systemd/src/basic/extract-word.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/systemd/src/basic/extract-word.c')
-rw-r--r--shared/systemd/src/basic/extract-word.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/shared/systemd/src/basic/extract-word.c b/shared/systemd/src/basic/extract-word.c
index 62f015f3..e32b4c7f 100644
--- a/shared/systemd/src/basic/extract-word.c
+++ b/shared/systemd/src/basic/extract-word.c
@@ -16,6 +16,7 @@
 #include "log.h"
 #include "macro.h"
 #include "string-util.h"
+#include "strv.h"
 #include "utf8.h"
 
 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
@@ -88,25 +89,30 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
                                 return -EINVAL;
                         }
 
-                        if (flags & EXTRACT_CUNESCAPE) {
+                        if (flags & (EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS)) {
                                 bool eight_bit = false;
                                 char32_t u;
 
-                                r = cunescape_one(*p, (size_t) -1, &u, &eight_bit, false);
-                                if (r < 0) {
-                                        if (flags & EXTRACT_CUNESCAPE_RELAX) {
-                                                s[sz++] = '\\';
-                                                s[sz++] = c;
-                                        } else
-                                                return -EINVAL;
-                                } else {
+                                if ((flags & EXTRACT_CUNESCAPE) &&
+                                    (r = cunescape_one(*p, (size_t) -1, &u, &eight_bit, false)) >= 0) {
+                                        /* A valid escaped sequence */
+                                        assert(r >= 1);
+
                                         (*p) += r - 1;
 
                                         if (eight_bit)
                                                 s[sz++] = u;
                                         else
                                                 sz += utf8_encode_unichar(s + sz, u);
-                                }
+                                } else if ((flags & EXTRACT_UNESCAPE_SEPARATORS) &&
+                                           strchr(separators, **p))
+                                        /* An escaped separator char */
+                                        s[sz++] = c;
+                                else if (flags & EXTRACT_CUNESCAPE_RELAX) {
+                                        s[sz++] = '\\';
+                                        s[sz++] = c;
+                                } else
+                                        return -EINVAL;
                         } else
                                 s[sz++] = c;