diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 02:25:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 02:25:50 +0000 |
commit | 19f4f86bfed21c5326ed2acebe1163f3a83e832b (patch) | |
tree | d59b9989ce55ed23693e80974d94c856f1c2c8b1 /src/basic/bus-label.c | |
parent | Initial commit. (diff) | |
download | systemd-d54215faec6264b9021f699873239ee9e4d99e5b.tar.xz systemd-d54215faec6264b9021f699873239ee9e4d99e5b.zip |
Adding upstream version 241.upstream/241upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/basic/bus-label.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/basic/bus-label.c b/src/basic/bus-label.c new file mode 100644 index 0000000..1613cf7 --- /dev/null +++ b/src/basic/bus-label.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include <stdlib.h> + +#include "alloc-util.h" +#include "bus-label.h" +#include "hexdecoct.h" +#include "macro.h" + +char *bus_label_escape(const char *s) { + char *r, *t; + const char *f; + + assert_return(s, NULL); + + /* Escapes all chars that D-Bus' object path cannot deal + * with. Can be reversed with bus_path_unescape(). We special + * case the empty string. */ + + if (*s == 0) + return strdup("_"); + + r = new(char, strlen(s)*3 + 1); + if (!r) + return NULL; + + for (f = s, t = r; *f; f++) { + + /* Escape everything that is not a-zA-Z0-9. We also + * escape 0-9 if it's the first character */ + + if (!(*f >= 'A' && *f <= 'Z') && + !(*f >= 'a' && *f <= 'z') && + !(f > s && *f >= '0' && *f <= '9')) { + *(t++) = '_'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *bus_label_unescape_n(const char *f, size_t l) { + char *r, *t; + size_t i; + + assert_return(f, NULL); + + /* Special case for the empty string */ + if (l == 1 && *f == '_') + return strdup(""); + + r = new(char, l + 1); + if (!r) + return NULL; + + for (i = 0, t = r; i < l; ++i) { + if (f[i] == '_') { + int a, b; + + if (l - i < 3 || + (a = unhexchar(f[i + 1])) < 0 || + (b = unhexchar(f[i + 2])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '_'; + } else { + *(t++) = (char) ((a << 4) | b); + i += 2; + } + } else + *(t++) = f[i]; + } + + *t = 0; + + return r; +} |