How to fix Invalid UTF-8 string passed to pango_layout_set_text()

Jack picture Jack · Oct 29, 2012 · Viewed 11k times · Source

I'm getting the following warning from my application that uses gtk+:

(foo:11333): Pango-WARNING **: Invalid UTF-8 string passed to pango_layout_set_text()

the function that is emitting the warning is the following:

static void show_error(GtkWindow *parent, const gchar *fmt, ...)
{
  GtkWidget *dialog;
  va_list args;

  va_start(args,fmt);
  dialog = gtk_message_dialog_new(parent,
                  GTK_DIALOG_DESTROY_WITH_PARENT,
                  GTK_MESSAGE_ERROR,
                  GTK_BUTTONS_OK,
                  fmt,
                  args);

  (void)gtk_dialog_run(GTK_DIALOG(dialog));

  gtk_widget_destroy(dialog);
  va_end(args);
}

and I'm calling with ui_show_error(window, "error canno't read file %s", filename);

where filename is null-terminatted-string, that works fine to str*() and *printf() functions family.

How to fix this?

Answer

ergosys picture ergosys · Oct 29, 2012

It's not possible to chain va_list arguments that way. See this faq entry. What's happening is gtk_message_dialog_new is interpreting the va_list argument (which has some compiler-defined format) as a pointer to a string, so you're getting garbage. Since there's no message dialog function which takes a va_list, your only choice is to build a string using vsprintf or one of the similar glib functions and pass it as one argument to gtk_message_dialog_new with a format like "%s".

To build the string in the face of an unknown format string, usually the technique is use one of the "n" variants, like vsnprintf with a largish buffer, and if truncation occurs, increasing the buffer size and doing it over. However, glib has g_vasprintf(), which allocates the buffer for you. It also has g_printf_string_upper_bound() which can be used to size a buffer based on the format string.