diff -up cups-1.6.1/notifier/dbus.c.dbus-utf8 cups-1.6.1/notifier/dbus.c --- cups-1.6.1/notifier/dbus.c.dbus-utf8 2012-01-20 19:00:32.000000000 +0000 +++ cups-1.6.1/notifier/dbus.c 2012-10-30 17:03:40.260833091 +0000 @@ -31,6 +31,8 @@ #include #include #include +#include +#include #ifdef HAVE_DBUS # include @@ -157,10 +159,78 @@ enum * Local functions... */ -static int acquire_lock(int *fd, char *lockfile, size_t locksize); +static int acquire_lock(int *fd, char *lockfile, size_t locksize); +static const char *validate_utf8(const char *str); /* + * 'validate_utf8()' - Convert to valid UTF-8 + */ + +static const char * +validate_utf8 (const char *str) +{ + static char *buffer = NULL; + static size_t buflen = 0; + char *p; + size_t str_len; + unsigned int i; + mbstate_t instate, outstate; + + if (str == NULL) + { + free (buffer); + return (NULL); + } + + /* Is it already valid? */ + if (mbstowcs (NULL, str, 0) != (size_t) -1) + return str; + + /* Make sure our buffer is at least as large as the input string */ + str_len = strlen (str); + if (str_len > buflen) + { + buflen = str_len + 1; + buffer = realloc (buffer, buflen); + } + + memset (&instate, '\0', sizeof (mbstate_t)); + memset (&outstate, '\0', sizeof (mbstate_t)); + p = buffer; + i = 0; + while (i < str_len) + { + wchar_t wc; + size_t used, written; + mbstate_t orig_instate = instate; + used = mbrtowc (&wc, str + i, str_len - i, &instate); + switch (used) + { + case (size_t) -2: + case (size_t) -1: + wc = L'?'; /* so replacement is never longer than original char */ + instate = orig_instate; + /* fallthru */ + case 0: + used = 1; + } + + written = wcrtomb (p, wc, &outstate); + if (written != -1) + { + p += written; + assert (p - buffer < buflen); + } + + i += used; + } + + *p = '\0'; + return p; +} + +/* * 'main()' - Read events and send DBUS notifications. */ @@ -366,7 +436,7 @@ main(int argc, /* I - Number of comm attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT); if (attr) { - const char *val = ippGetString(attr, 0, NULL); + const char *val = validate_utf8 (ippGetString(attr, 0, NULL)); if (!dbus_message_iter_append_string(&iter, &val)) goto bail; } @@ -530,7 +600,7 @@ main(int argc, /* I - Number of comm attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME); if (attr) { - const char *val = ippGetString(attr, 0, NULL); + const char *val = validate_utf8 (ippGetString(attr, 0, NULL)); if (!dbus_message_iter_append_string(&iter, &val)) goto bail; }