diff -up cups-1.5.4/notifier/dbus.c.dbus-utf8 cups-1.5.4/notifier/dbus.c --- cups-1.5.4/notifier/dbus.c.dbus-utf8 2012-01-13 23:00:22.000000000 +0000 +++ cups-1.5.4/notifier/dbus.c 2012-10-31 11:30:08.217215685 +0000 @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include #ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND @@ -156,10 +159,82 @@ 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) + { + if (buffer == NULL) + /* Set encoding type to UTF-8 the first time we need to */ + setlocale (LC_CTYPE, "en_US.UTF-8"); + + 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 buffer; +} + +/* * 'main()' - Read events and send DBUS notifications. */ @@ -226,6 +301,7 @@ main(int argc, /* I - Number of comm int no = 0; /* Boolean "no" value */ int params = PARAMS_NONE; /* What parameters to include? */ + const char *val; /* @@ -365,7 +441,8 @@ main(int argc, /* I - Number of comm attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT); if (!attr) goto bail; - if (!dbus_message_iter_append_string(&iter, &(attr->values[0].string.text))) + val = validate_utf8 (attr->values[0].string.text); + if (!dbus_message_iter_append_string(&iter, &val)) goto bail; if (params >= PARAMS_PRINTER) @@ -509,8 +586,8 @@ main(int argc, /* I - Number of comm attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME); if (attr) { - if (!dbus_message_iter_append_string(&iter, - &(attr->values[0].string.text))) + val = validate_utf8 (attr->values[0].string.text); + if (!dbus_message_iter_append_string(&iter, &val)) goto bail; } else