chiark / gitweb /
core: do not print invalid utf-8 in error messages
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 18 Jan 2014 02:28:41 +0000 (21:28 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 8 Feb 2014 18:07:39 +0000 (13:07 -0500)
TODO
src/shared/fileio.c
src/shared/utf8.c
src/shared/utf8.h
src/test/test-utf8.c

diff --git a/TODO b/TODO
index 57e82ff262a39fa49f3cc84f84eb7606de9f9c37..1a1e8893196bd1ca5ec45a2e150ae6a0a963b658 100644 (file)
--- a/TODO
+++ b/TODO
@@ -16,9 +16,6 @@ Bugfixes:
 
 * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
 
 
 * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
 
-* When we detect invalid UTF-8, we cannot use it in an error message:
-  log...("Path is not UTF-8 clean, ignoring assignment: %s", rvalue);
-
 * shorten the message to sane length:
 
   Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory. See system logs and 'systemctl status display-manager.service' for details.
 * shorten the message to sane length:
 
   Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory. See system logs and 'systemctl status display-manager.service' for details.
index 838d1284332793a09c20a11c58dfd3a9fef0b640..b81eeb272a4bdc8aa28d89f97fce7d4d5976b977 100644 (file)
@@ -539,15 +539,18 @@ static int parse_env_file_push(const char *filename, unsigned line,
         va_list aq, *ap = userdata;
 
         if (!utf8_is_valid(key)) {
         va_list aq, *ap = userdata;
 
         if (!utf8_is_valid(key)) {
-                log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.",
-                          filename, line, key);
+                _cleanup_free_ char *p = utf8_escape_invalid(key);
+
+                log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.",
+                          filename, line, p);
                 return -EINVAL;
         }
 
         if (value && !utf8_is_valid(value)) {
                 return -EINVAL;
         }
 
         if (value && !utf8_is_valid(value)) {
-                /* FIXME: filter UTF-8 */
+                _cleanup_free_ char *p = utf8_escape_invalid(value);
+
                 log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
                 log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
-                          filename, line, key, value);
+                          filename, line, key, p);
                 return -EINVAL;
         }
 
                 return -EINVAL;
         }
 
index 6e5ba9abf4ad115b9fcc2d3e78fbef6e65664815..0b524d8a9041eae0348382cdf47159f7c2f8d0b3 100644 (file)
@@ -174,6 +174,32 @@ const char *utf8_is_valid(const char *str) {
         return str;
 }
 
         return str;
 }
 
+char *utf8_escape_invalid(const char *str) {
+        char *p, *s;
+
+        assert(str);
+
+        p = s = malloc(strlen(str) * 4 + 1);
+        if (!p)
+                return NULL;
+
+        while (*str) {
+                int len;
+
+                len = utf8_encoded_valid_unichar(str);
+                if (len > 0) {
+                        s = mempcpy(s, str, len);
+                        str += len;
+                } else {
+                        s = mempcpy(s, UTF8_REPLACEMENT_CHARACTER, strlen(UTF8_REPLACEMENT_CHARACTER));
+                        str += 1;
+                }
+        }
+        *s = '\0';
+
+        return p;
+}
+
 char *ascii_is_valid(const char *str) {
         const char *p;
 
 char *ascii_is_valid(const char *str) {
         const char *p;
 
index f56077438aa6970d7d6950b5452c5d9db97a85ff..c0eb73a21d32ea5a483fea51fa39ff6de96ddc4d 100644 (file)
 
 #include "macro.h"
 
 
 #include "macro.h"
 
+#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
+
 const char *utf8_is_valid(const char *s) _pure_;
 char *ascii_is_valid(const char *s) _pure_;
 const char *utf8_is_valid(const char *s) _pure_;
 char *ascii_is_valid(const char *s) _pure_;
+char *utf8_escape_invalid(const char *s);
 
 bool utf8_is_printable(const char* str, size_t length) _pure_;
 
 
 bool utf8_is_printable(const char* str, size_t length) _pure_;
 
index d2198fdc743a403f88eba7a91f5facbb7fbc2c06..b7d988f22d8f1e2d35ab7a8d3a65a75ca3458cf1 100644 (file)
@@ -50,11 +50,28 @@ static void test_utf8_encoded_valid_unichar(void) {
 
 }
 
 
 }
 
+static void test_utf8_escaping(void) {
+        _cleanup_free_ char *p1, *p2, *p3;
+
+        p1 = utf8_escape_invalid("goo goo goo");
+        puts(p1);
+        assert_se(utf8_is_valid(p1));
+
+        p2 = utf8_escape_invalid("\341\204\341\204");
+        puts(p2);
+        assert_se(utf8_is_valid(p2));
+
+        p3 = utf8_escape_invalid("\341\204");
+        puts(p3);
+        assert_se(utf8_is_valid(p3));
+}
+
 int main(int argc, char *argv[]) {
         test_utf8_is_valid();
         test_utf8_is_printable();
         test_ascii_is_valid();
         test_utf8_encoded_valid_unichar();
 int main(int argc, char *argv[]) {
         test_utf8_is_valid();
         test_utf8_is_printable();
         test_ascii_is_valid();
         test_utf8_encoded_valid_unichar();
+        test_utf8_escaping();
 
         return 0;
 }
 
         return 0;
 }