From: Karel Zak Date: Mon, 5 May 2025 11:04:54 +0000 (+0200) Subject: libmount: add function to remove escaped chars X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=00e70d300c8e73a3c6a9e7398a48f780fc006f59;p=thirdparty%2Futil-linux.git libmount: add function to remove escaped chars Follow-up: 8a69fa852dd5f41f8456756d18bfac6d8208219f https://github.com/util-linux/util-linux/pull/3541 Signed-off-by: Karel Zak --- diff --git a/include/mangle.h b/include/mangle.h index 59396916f..7deb8bed5 100644 --- a/include/mangle.h +++ b/include/mangle.h @@ -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 */ diff --git a/lib/mangle.c b/lib/mangle.c index 1a3b89ae4..2d31943cb 100644 --- a/lib/mangle.c +++ b/lib/mangle.c @@ -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 \n", + fprintf(stderr, "usage: %s --mangle|unmangle|unescape \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 */ diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 9f722b27f..35f3a8d74 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -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; }