]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
extract-word: introduce EXTRACT_KEEP_QUOTE flag
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 21 Jun 2021 12:01:54 +0000 (21:01 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 21 Jun 2021 12:14:20 +0000 (21:14 +0900)
src/basic/extract-word.c
src/basic/extract-word.h

index 2c14b6f0cf1eed930a79cc99b7a6a027f3d46e50..0c440db691ce107bb12da0e97b37ed37d18c5ef5 100644 (file)
@@ -27,6 +27,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
 
         assert(p);
         assert(ret);
+        assert(!FLAGS_SET(flags, EXTRACT_KEEP_QUOTE | EXTRACT_UNQUOTE));
 
         /* Bail early if called after last value or with no input */
         if (!*p)
@@ -123,25 +124,30 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
                                         return -EINVAL;
                                 } else if (c == quote) {        /* found the end quote */
                                         quote = 0;
-                                        break;
+                                        if (flags & EXTRACT_UNQUOTE)
+                                                break;
                                 } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
                                         backslash = true;
                                         break;
-                                } else {
-                                        if (!GREEDY_REALLOC(s, sz+2))
-                                                return -ENOMEM;
-
-                                        s[sz++] = c;
                                 }
+
+                                if (!GREEDY_REALLOC(s, sz+2))
+                                        return -ENOMEM;
+
+                                s[sz++] = c;
+
+                                if (quote == 0)
+                                        break;
                         }
 
                 } else {
                         for (;; (*p)++, c = **p) {
                                 if (c == 0)
                                         goto finish_force_terminate;
-                                else if (IN_SET(c, '\'', '"') && (flags & EXTRACT_UNQUOTE)) {
+                                else if (IN_SET(c, '\'', '"') && (flags & (EXTRACT_KEEP_QUOTE | EXTRACT_UNQUOTE))) {
                                         quote = c;
-                                        break;
+                                        if (flags & EXTRACT_UNQUOTE)
+                                                break;
                                 } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
                                         backslash = true;
                                         break;
@@ -159,12 +165,15 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
                                         }
                                         goto finish;
 
-                                } else {
-                                        if (!GREEDY_REALLOC(s, sz+2))
-                                                return -ENOMEM;
-
-                                        s[sz++] = c;
                                 }
+
+                                if (!GREEDY_REALLOC(s, sz+2))
+                                        return -ENOMEM;
+
+                                s[sz++] = c;
+
+                                if (quote != 0)
+                                        break;
                         }
                 }
         }
index 0e9e77e93d31bb97d47b36c903cab1f386a16c13..f415872fac97dc2faa3caf12fdf897f257dae93b 100644 (file)
@@ -8,9 +8,10 @@ typedef enum ExtractFlags {
         EXTRACT_CUNESCAPE                = 1 << 1, /* Unescape known escape sequences. */
         EXTRACT_UNESCAPE_RELAX           = 1 << 2, /* Allow and keep unknown escape sequences, allow and keep trailing backslash. */
         EXTRACT_UNESCAPE_SEPARATORS      = 1 << 3, /* Unescape separators (those specified, or whitespace by default). */
-        EXTRACT_UNQUOTE                  = 1 << 4, /* Remove quoting with "" and ''. */
-        EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 5, /* Don't treat multiple adjacent separators as one */
-        EXTRACT_RETAIN_ESCAPE            = 1 << 6, /* Treat escape character '\' as any other character without special meaning */
+        EXTRACT_KEEP_QUOTE               = 1 << 4, /* Ignore separators in quoting with "" and ''. */
+        EXTRACT_UNQUOTE                  = 1 << 5, /* Ignore separators in quoting with "" and '', and remove the quotes. */
+        EXTRACT_DONT_COALESCE_SEPARATORS = 1 << 6, /* Don't treat multiple adjacent separators as one */
+        EXTRACT_RETAIN_ESCAPE            = 1 << 7, /* Treat escape character '\' as any other character without special meaning */
 
         /* Note that if no flags are specified, escaped escape characters will be silently stripped. */
 } ExtractFlags;