chiark / gitweb /
replace_untrusted_chars: replace all whitespace with space
[elogind.git] / udev_utils_string.c
index 8cda47272ffc9ee83cef43e2a55c2b7f416b78b4..6f51aef01417790988d55683fd1435796a128704 100644 (file)
@@ -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++;