diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/fileio.c | 11 | ||||
-rw-r--r-- | src/shared/utf8.c | 26 | ||||
-rw-r--r-- | src/shared/utf8.h | 3 |
3 files changed, 36 insertions, 4 deletions
diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 838d128433..b81eeb272a 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -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)) { - 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)) { - /* 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.", - filename, line, key, value); + filename, line, key, p); return -EINVAL; } diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 6e5ba9abf4..0b524d8a90 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -174,6 +174,32 @@ const char *utf8_is_valid(const char *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; diff --git a/src/shared/utf8.h b/src/shared/utf8.h index f56077438a..c0eb73a21d 100644 --- a/src/shared/utf8.h +++ b/src/shared/utf8.h @@ -25,8 +25,11 @@ #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_; +char *utf8_escape_invalid(const char *s); bool utf8_is_printable(const char* str, size_t length) _pure_; |