summary refs log tree commit diff
path: root/shared/systemd/src/basic/extract-word.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
committerMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
commitaafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch)
treea2a9bb4d007339a0b1304540388230ccedac32bd /shared/systemd/src/basic/extract-word.c
parente7b44ef4c80907346ec7492a09c45277459924fc (diff)
New upstream version 1.27.90 upstream/1.27.90
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;