Invalid read in g_utf8_collate_key() for short strings
==1382082== Invalid read of size 32
==1382082== at 0x4E59A2E: __wcpncpy_avx2 (strncpy-avx2.S:85)
==1382082== by 0x4DBB560: wcsxfrm_l (strxfrm_l.c:679)
==1382082== by 0x4B3D957: g_utf8_collate_key (gunicollate.c:408)
==1382082== Address 0x5099f50 is 0 bytes inside a block of size 8 alloc'd
==1382082== at 0x484280F: malloc (vg_replace_malloc.c:442)
==1382082== by 0x4B0CB8D: g_malloc (gmem.c:100)
==1382082== by 0x4B3EC25: _g_utf8_normalize_wc (gunidecomp.c:399)
==1382082== by 0x4B3D91A: g_utf8_collate_key (gunicollate.c:402)
I'm not entirely sure if this is GLib's fault or glibc's (2.38 from F39). It feels more like the latter but this function surely can't be that broken in glibc... or for some reason this is fine? __wcpncpy_avx2
seems to assume for some reason that the input is at least one AVX register large.
The following patch to GLib works around it. I can't find anything in the wcsxfrm()
docs that would suggest requiring a minimum buffer size.
diff --git a/glib/gunidecomp.c b/glib/gunidecomp.c
index 5c2d41b1d..bea75f50a 100644
--- a/glib/gunidecomp.c
+++ b/glib/gunidecomp.c
@@ -396,7 +396,7 @@ _g_utf8_normalize_wc (const gchar *str,
p = next;
}
- wc_buffer = g_new (gunichar, n_wc + 1);
+ wc_buffer = g_new (gunichar, MAX (n_wc + 1, 32));
last_start = 0;
n_wc = 0;
Any ideas?