Pergunta

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?

Foi útil?

Solução

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.

Outras dicas

I was with exactly this issue in a Linux From Scratch (LFS) build. The problem was affect the java swing interface text inputs, gdk interface text input, sometimes silently ignoring input like the text field was disabled. The cause is the absence of any UTF8 locale. in my case:

$ locale -a
C
POSIX
pt_BR
pt_BR.iso88591

So, to solve I did define a new locale type utf8 like:

localedef -i pt_BR -f UTF-8 pt_BR.UTF-8

after this, all became useful and no more warnings. at least in my case.

OP did not show the actual string and where is ui_show_error function? What Gtk+ version? By default gtk_message_dialog_new "use-markup" property is FALSE, so is there something missing from post?

You could do somthing like:

msg = g_vasprintf(fmt, args);

if (strstr(msg, "</"))
  msg_has_markup = TRUE;

dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
                       "message-type",         GTK_MESSAGE_ERROR,
                       "text",                 msg,
                       "use-markup",           msg_has_markup,
                       "buttons",              GTK_BUTTONS_OK,
                        NULL);
g_free (msg);

Noting that you would still get the same error message if the file name string is wrapped in "<>", i.e. </home/somebody would cause obnoxious pango message. Either do no use the "<>" or do not use pango.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top