diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-03-05 19:58:32 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-03-05 20:05:46 +0100 |
commit | d47c78be4a2acbb631a26af11b7ce2ef57f55996 (patch) | |
tree | 024967d8250f9dea111ca82dff3b45a4c0b81573 /src/shared | |
parent | 2f2343c6b15ec5495eb5032ae36b937fe36177cc (diff) |
util: properly escape corner cases in bus_path_escape(), too
This follows the suggestions from:
http://lists.freedesktop.org/archives/systemd-devel/2013-March/009363.html
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/util.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index e643cd367c..b7ba7fbe84 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1325,16 +1325,24 @@ char *bus_path_escape(const char *s) { assert(s); /* Escapes all chars that D-Bus' object path cannot deal - * with. Can be reverse with bus_path_unescape() */ + * with. Can be reverse with bus_path_unescape(). We special + * case the empty string. */ - if (!(r = new(char, strlen(s)*3+1))) + 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 >= '0' && *f <= '9')) { + !(f > s && *f >= '0' && *f <= '9')) { *(t++) = '_'; *(t++) = hexchar(*f >> 4); *(t++) = hexchar(*f); @@ -1352,7 +1360,12 @@ char *bus_path_unescape(const char *f) { assert(f); - if (!(r = strdup(f))) + /* Special case for the empty string */ + if (streq(f, "_")) + return strdup(""); + + r = new(char, strlen(f) + 1); + if (!r) return NULL; for (t = r; *f; f++) { |