File gkrellm-2.3.5-fix-diskio-corruption.patch of Package gkrellm
Author: Stefan Seyfried
Subject: fix corruption of chart labels
I was seeing corruption in my r/w label in the disk chart.
Investigation showed, that this was caused by invalid UTF8 being passed to pango_layout_set_text().
In the relevant places, I now check if the string is valid UTF8 before passing it (or a NULL pointer)
to pango_layout_set_text().
Also, fix a possible buffer overrun resulting from gkrellm_format_size_abbrev(), because it was
misusing snprintf return code (but this was probably not the reason of the invalid UTF8, as it did
not help that problem :-)
I'm guessing that the original problem is a 32bit overflow in the disk statistics gathering, I
suspect that I/O speeds of over 2GB/sec result in huge negative numbers.
Anyway, the additional check for valid UTF8 makes the corruption go away and that's better
than not fixing it at all.
diff --git a/src/utils.c b/src/utils.c
index c6a2773..1ed7382 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -276,15 +276,24 @@ gkrellm_format_size_abbrev(gchar *buf, size_t buflen, gfloat size,
{
gfloat abs_size;
gint i;
+ int ret;
abs_size = (size < 0.0) ? -size : size;
for (i = 0; i < tbl_size - 1; ++i)
if (abs_size < tbl[i].limit)
break;
- return snprintf(buf, buflen, tbl[i].format, size / tbl[i].divisor);
+ ret = snprintf(buf, buflen, tbl[i].format, size / tbl[i].divisor);
+ if (ret > buflen) {
+ fprintf(stderr, "%s:%d ret>buflen %d > %d\n", __func__, __LINE__, ret, buflen);
+ return buflen;
+ }
+ if (ret < 0) {
+ fprintf(stderr, "%s:%d ret < 0 %d < %d\n", __func__, __LINE__, ret, 0);
+ return 0;
+ }
+ return ret;
}
-
/* Next three calls return string extent info. Width extents are logical
| so that spaces will be counted while height extent is ink so that gkrellm
@@ -366,7 +375,8 @@ gkrellm_text_extents(PangoFontDescription *font_desc, gchar *text,
else
{
utf8 = g_locale_to_utf8(text, -1, NULL, NULL, NULL);
- pango_layout_set_text(layout, utf8, len);
+ if (utf8)
+ pango_layout_set_text(layout, utf8, len);
g_free(utf8);
}
iter = pango_layout_get_iter(layout);
@@ -456,7 +466,8 @@ gkrellm_gdk_draw_text(GdkDrawable *drawable, PangoFontDescription *font_desc,
layout = gtk_widget_create_pango_layout(gkrellm_get_top_window(), NULL);
pango_layout_set_font_description(layout, font_desc);
- pango_layout_set_text(layout, string, len);
+ if (g_utf8_validate(string, -1, NULL))
+ pango_layout_set_text(layout, string, len);
gdk_draw_layout(drawable, gc, x, y, layout);
g_object_unref(layout);
}