chiark / gitweb /
rules: adapt tape rules to new scsi_id
[elogind.git] / udev_utils_string.c
index b0641f002b01b2c1f676c41900518c27e447c5b5..e3dc137e63257be33471a2d1a8ede3523a281dd4 100644 (file)
@@ -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++;