X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev_utils_string.c;h=6f51aef01417790988d55683fd1435796a128704;hp=8cda47272ffc9ee83cef43e2a55c2b7f416b78b4;hb=ca4f2c41b016530b5865b40b8dbbf0a3a0e8e634;hpb=27b77df44daebbd7597c572343105c16de099233 diff --git a/udev_utils_string.c b/udev_utils_string.c index 8cda47272..6f51aef01 100644 --- a/udev_utils_string.c +++ b/udev_utils_string.c @@ -50,6 +50,49 @@ void remove_trailing_chars(char *path, char c) path[--len] = '\0'; } +size_t path_encode(char *s, size_t len) +{ + char t[(len * 3)+1]; + size_t i, j; + + t[0] = '\0'; + for (i = 0, j = 0; s[i] != '\0'; i++) { + if (s[i] == '/') { + memcpy(&t[j], "\\x2f", 4); + j += 4; + } else if (s[i] == '\\') { + memcpy(&t[j], "\\x5c", 4); + j += 4; + } else { + t[j] = s[i]; + j++; + } + } + t[j] = '\0'; + strncpy(s, t, len); + return j; +} + +size_t path_decode(char *s) +{ + size_t i, j; + + for (i = 0, j = 0; s[i] != '\0'; j++) { + if (memcmp(&s[i], "\\x2f", 4) == 0) { + s[j] = '/'; + i += 4; + }else if (memcmp(&s[i], "\\x5c", 4) == 0) { + s[j] = '\\'; + i += 4; + } else { + s[j] = s[i]; + i++; + } + } + s[j] = '\0'; + return j; +} + /* count of characters used to encode one unicode char */ static int utf8_encoded_expected_len(const char *str) { @@ -186,10 +229,17 @@ int replace_untrusted_chars(char *str) if ((str[i] >= '0' && str[i] <= '9') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z') || - strchr(" #$%+-./:=?@_,", str[i])) { + strchr("#$%+-./:=?@_,", str[i])) { i++; continue; } + + /* hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + /* valid utf8 is accepted */ len = utf8_encoded_valid_unichar(&str[i]); if (len > 1) { @@ -197,6 +247,14 @@ int replace_untrusted_chars(char *str) continue; } + /* whitespace replaced with ordinary space */ + if (isspace(str[i])) { + str[i] = ' '; + i++; + replaced++; + continue; + } + /* everything else is garbage */ str[i] = '_'; i++;