chiark / gitweb /
run_program: close pipe fd's which are connected to child process
[elogind.git] / udev_utils_string.c
index a30181e760d5592625fd83831a5a4a0f2bb27f3b..225e1985879ef16de3fc34b75c81479a3ac59711 100644 (file)
 #include <syslog.h>
 #include <sys/utsname.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "logging.h"
-#include "udev_utils.h"
-#include "list.h"
-
-/* compare string with pattern (like fnmatch(), supports * ? [0-9] [!A-Z]) */
-int strcmp_pattern(const char *p, const char *s)
-{
-       if (s[0] == '\0') {
-               while (p[0] == '*')
-                       p++;
-               return (p[0] != '\0');
-       }
-       switch (p[0]) {
-       case '[':
-               {
-                       int not = 0;
-                       p++;
-                       if (p[0] == '!') {
-                               not = 1;
-                               p++;
-                       }
-                       while ((p[0] != '\0') && (p[0] != ']')) {
-                               int match = 0;
-                               if (p[1] == '-') {
-                                       if ((s[0] >= p[0]) && (s[0] <= p[2]))
-                                               match = 1;
-                                       p += 3;
-                               } else {
-                                       match = (p[0] == s[0]);
-                                       p++;
-                               }
-                               if (match ^ not) {
-                                       while ((p[0] != '\0') && (p[0] != ']'))
-                                               p++;
-                                       if (p[0] == ']')
-                                               return strcmp_pattern(p+1, s+1);
-                               }
-                       }
-               }
-               break;
-       case '*':
-               if (strcmp_pattern(p, s+1))
-                       return strcmp_pattern(p+1, s);
-               return 0;
-       case '\0':
-               if (s[0] == '\0') {
-                       return 0;
-               }
-               break;
-       default:
-               if ((p[0] == s[0]) || (p[0] == '?'))
-                       return strcmp_pattern(p+1, s+1);
-               break;
-       }
-       return 1;
-}
 
 int string_is_true(const char *str)
 {
@@ -100,7 +43,7 @@ int string_is_true(const char *str)
        return 0;
 }
 
-void remove_trailing_char(char *path, char c)
+void remove_trailing_chars(char *path, char c)
 {
        size_t len;
 
@@ -232,12 +175,35 @@ int utf8_encoded_valid_unichar(const char *str)
        return len;
 }
 
-void replace_untrusted_chars(char *string)
+/* replace everything but whitelisted plain ascii and valid utf8 */
+int replace_untrusted_chars(char *str)
 {
-       size_t len;
+       size_t i = 0;
+       int replaced = 0;
+
+       while (str[i] != '\0') {
+               int len;
+
+               /* valid printable ascii char */
+               if ((str[i] >= '0' && str[i] <= '9') ||
+                   (str[i] >= 'A' && str[i] <= 'Z') ||
+                   (str[i] >= 'a' && str[i] <= 'z') ||
+                   strchr(" #$%+-./:=?@_,", str[i])) {
+                       i++;
+                       continue;
+               }
+               /* valid utf8 is accepted */
+               len = utf8_encoded_valid_unichar(&str[i]);
+               if (len > 1) {
+                       i += len;
+                       continue;
+               }
 
-       for (len = 0; string[len] != '\0'; len++) {
-               if (strchr(";,~\\()\'", string[len]))
-                       string[len] = '_';
+               /* everything else is garbage */
+               str[i] = '_';
+               i++;
+               replaced++;
        }
+
+       return replaced;
 }