X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev_utils_string.c;h=e3dc137e63257be33471a2d1a8ede3523a281dd4;hp=b0641f002b01b2c1f676c41900518c27e447c5b5;hb=788096cb59a7ad1cdd08ccc59e5e3b1d2f4828c2;hpb=9c6ad9fbbac82e517f5e748ddbe166f96f120afe diff --git a/udev_utils_string.c b/udev_utils_string.c index b0641f002..e3dc137e6 100644 --- a/udev_utils_string.c +++ b/udev_utils_string.c @@ -58,11 +58,11 @@ size_t path_encode(char *s, size_t len) t[0] = '\0'; for (i = 0, j = 0; s[i] != '\0'; i++) { if (s[i] == '/') { - memcpy(&t[j], "%2f", 3); - j += 3; - } else if (s[i] == '%') { - memcpy(&t[j], "%25", 3); - j += 3; + memcpy(&t[j], "\\x2f", 4); + j += 4; + } else if (s[i] == '\\') { + memcpy(&t[j], "\\x5c", 4); + j += 4; } else { t[j] = s[i]; j++; @@ -78,12 +78,12 @@ size_t path_decode(char *s) size_t i, j; for (i = 0, j = 0; s[i] != '\0'; j++) { - if (memcmp(&s[i], "%2f", 3) == 0) { + if (memcmp(&s[i], "\\x2f", 4) == 0) { s[j] = '/'; - i += 3; - }else if (memcmp(&s[i], "%25", 3) == 0) { - s[j] = '%'; - i += 3; + i += 4; + }else if (memcmp(&s[i], "\\x5c", 4) == 0) { + s[j] = '\\'; + i += 4; } else { s[j] = s[i]; i++; @@ -216,8 +216,8 @@ int utf8_encoded_valid_unichar(const char *str) return len; } -/* replace everything but whitelisted plain ascii and valid utf8 */ -int replace_untrusted_chars(char *str) +/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ +int replace_chars(char *str, const char *white) { size_t i = 0; int replaced = 0; @@ -225,22 +225,42 @@ int replace_untrusted_chars(char *str) while (str[i] != '\0') { int len; - /* valid printable ascii char */ + /* accept whitelist */ + if (white != NULL && strchr(white, str[i]) != NULL) { + i++; + continue; + } + + /* accept plain ascii char */ if ((str[i] >= '0' && str[i] <= '9') || (str[i] >= 'A' && str[i] <= 'Z') || - (str[i] >= 'a' && str[i] <= 'z') || - strchr(" #$%+-./:=?@_,", str[i])) { + (str[i] >= 'a' && str[i] <= 'z')) { i++; continue; } - /* valid utf8 is accepted */ + + /* accept hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + + /* accept valid utf8 */ len = utf8_encoded_valid_unichar(&str[i]); if (len > 1) { i += len; continue; } - /* everything else is garbage */ + /* if space is allowed, replace whitespace with ordinary space */ + if (isspace(str[i]) && strchr(white, ' ') != NULL) { + str[i] = ' '; + i++; + replaced++; + continue; + } + + /* everything else is replaced with '_' */ str[i] = '_'; i++; replaced++;