]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add function to remove escaped chars
authorKarel Zak <kzak@redhat.com>
Mon, 5 May 2025 11:04:54 +0000 (13:04 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 5 May 2025 11:08:42 +0000 (13:08 +0200)
Follow-up: 8a69fa852dd5f41f8456756d18bfac6d8208219f https://github.com/util-linux/util-linux/pull/3541
Signed-off-by: Karel Zak <kzak@redhat.com>
include/mangle.h
lib/mangle.c
libmount/src/hook_mount.c

index 59396916ffb80e54f162ed350633c3505f9e67dc..7deb8bed52843f7d6d5daa468a335b18c9eb7ab0 100644 (file)
@@ -13,6 +13,7 @@ extern char *mangle(const char *s);
 
 extern void unmangle_to_buffer(const char *s, char *buf, size_t len);
 extern size_t unhexmangle_to_buffer(const char *s, char *buf, size_t len);
+extern size_t unescape_to_buffer(const char *s, const char *wanted, char *buf, size_t len);
 
 extern char *unmangle(const char *s, const char **end);
 
@@ -28,5 +29,11 @@ static inline void unhexmangle_string(char *s)
                unhexmangle_to_buffer(s, s, strlen(s) + 1);
 }
 
+static inline void unescape_string(char *s, const char *wanted)
+{
+       if (s)
+               unescape_to_buffer(s, wanted, s, strlen(s) + 1);
+}
+
 #endif /* UTIL_LINUX_MANGLE_H */
 
index 1a3b89ae488848d6b14a29ad2659f427bdbdda85..2d31943cb3c7d97e91973a05d9e7747ad073e2a4 100644 (file)
@@ -95,6 +95,25 @@ size_t unhexmangle_to_buffer(const char *s, char *buf, size_t len)
        return buf - buf0 + 1;
 }
 
+size_t unescape_to_buffer(const char *s, const char *wanted, char *buf, size_t len)
+{
+       size_t sz = 0;
+       const char *buf0 = buf;
+
+       while (*s && sz < len - 1) {
+               if (*s == '\\' && sz + 1 < len - 1 && strchr(wanted, s[1])) {
+                       *buf++ = s[1];
+                       s += 2;
+                       sz += 2;
+               } else {
+                       *buf++ = *s++;;
+                       sz++;
+               }
+       }
+       *buf = '\0';
+       return buf - buf0 + 1;
+}
+
 static inline const char *skip_nonspaces(const char *s)
 {
        while (s && *s && !(*s == ' ' || *s == '\t'))
@@ -136,7 +155,7 @@ int main(int argc, char *argv[])
 {
        char *p = NULL;
        if (argc < 3) {
-               fprintf(stderr, "usage: %s --mangle|unmangle <string>\n",
+               fprintf(stderr, "usage: %s --mangle|unmangle|unescape <string>\n",
                                                program_invocation_short_name);
                return EXIT_FAILURE;
        }
@@ -164,6 +183,16 @@ int main(int argc, char *argv[])
                }
        }
 
+       else if (!strcmp(argv[1], "--unescape")) {
+               char *x = strdup(argv[2]);
+               if (x) {
+                       unescape_to_buffer(x, ",\"", x, strlen(x) + 1);
+
+                       printf("self-unescaped: '%s'\n", x);
+                       free(x);
+               }
+       }
+
        return EXIT_SUCCESS;
 }
 #endif /* TEST_PROGRAM_MANGLE */
index 9f722b27f2b76e0d1196d026d2757d1a2ce27ce3..35f3a8d749ce7a1a50f52c210e8f5aee70b6ecf2 100644 (file)
@@ -46,6 +46,7 @@
 #include "mountP.h"
 #include "fileutils.h" /* statx() fallback */
 #include "strutils.h"
+#include "mangle.h"
 #include "linux_version.h"
 
 #ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
@@ -138,19 +139,12 @@ static inline int fsconfig_set_value(
        int rc;
        char *s = NULL;
 
-       /* "\," is a way to use comma in values, let's remove \ escape */
-       if (value && strstr(value, "\\,")) {
-               char *x, *p;
-
+       /* Remove \, and \" escapes, both supported by ul_optstr_next() */
+       if (value && strchr(value, '\\')) {
                s = strdup(value);
                if (!s)
-                       return -EINVAL;
-               for (x = p = s; *x; p++, x++) {
-                       if (*x == '\\' && *(x + 1) == ',')
-                               x++;
-                       *p = *x;
-               }
-               *p = '\0';
+                       return -ENOMEM;
+               unescape_string(s, ",\"");
                value = s;
        }