When LANG is set to ru_RU.UTF-8 for example xfce4-keyboard-settings would

segfault. This was due to libxklavier passing invalid UTF-8 strings to
a few glib functions which require a UTF-8 string.

Add code to libxklavier to pass correct UTF-8 string to glib.

Submitted by:	rum1cro@yandex.ru
This commit is contained in:
Koop Mast 2015-11-18 18:52:30 +00:00
parent baa06e600b
commit 48263a51f1
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=401888
3 changed files with 138 additions and 0 deletions

View file

@ -3,6 +3,7 @@
PORTNAME= libxklavier
PORTVERSION= 5.3
PORTREVISION= 1
PORTEPOCH= 1
CATEGORIES= x11 gnome
MASTER_SITES= GNOME

View file

@ -0,0 +1,64 @@
--- libxklavier/utf8.c 1970-01-01 03:00:00.000000000 +0300
+++ libxklavier/utf8.c 2015-11-18 01:50:50.406110000 +0300
@@ -0,0 +1,61 @@
+/*
+ * The utf8_check() function scans the '\0'-terminated string starting
+ * at s. It returns a pointer to the first byte of the first malformed
+ * or overlong UTF-8 sequence found, or NULL if the string contains
+ * only correct UTF-8. It also spots UTF-8 sequences that could cause
+ * trouble if converted to UTF-16, namely surrogate characters
+ * (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF). This
+ * routine is very likely to find a malformed sequence if the input
+ * uses any other encoding than UTF-8. It therefore can be used as a
+ * very effective heuristic for distinguishing between UTF-8 and other
+ * encodings.
+ *
+ * I wrote this code mainly as a specification of functionality; there
+ * are no doubt performance optimizations possible for certain CPUs.
+ *
+ * Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> -- 2005-03-30
+ * License: http://www.cl.cam.ac.uk/~mgk25/short-license.html
+ */
+
+
+guchar *
+utf8_check(guchar *s)
+{
+ while (*s) {
+ if (*s < 0x80)
+ /* 0xxxxxxx */
+ s++;
+ else if ((s[0] & 0xe0) == 0xc0) {
+ /* 110XXXXx 10xxxxxx */
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[0] & 0xfe) == 0xc0) /* overlong? */
+ return s;
+ else
+ s += 2;
+ } else if ((s[0] & 0xf0) == 0xe0) {
+ /* 1110XXXX 10Xxxxxx 10xxxxxx */
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[2] & 0xc0) != 0x80 ||
+ (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */
+ (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */
+ (s[0] == 0xef && s[1] == 0xbf &&
+ (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */
+ return s;
+ else
+ s += 3;
+ } else if ((s[0] & 0xf8) == 0xf0) {
+ /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[2] & 0xc0) != 0x80 ||
+ (s[3] & 0xc0) != 0x80 ||
+ (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */
+ (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */
+ return s;
+ else
+ s += 4;
+ } else
+ return s;
+ }
+
+ return NULL;
+}

View file

@ -0,0 +1,73 @@
--- libxklavier/xklavier_config.c 2012-08-24 02:23:02.000000000 +0400
+++ libxklavier/xklavier_config.c 2015-11-18 01:56:26.307937000 +0300
@@ -29,6 +29,8 @@
#include "xklavier_private.h"
+#include "utf8.c"
+
static GObjectClass *parent_class = NULL;
static xmlXPathCompExprPtr models_xpath;
@@ -162,6 +164,8 @@
gchar *vendor = NULL, *translated = NULL, *escaped =
NULL, *unescaped = NULL;
+ guchar *s = NULL;
+
gint i;
*item->name = 0;
@@ -190,17 +194,32 @@
desc_element = xkl_find_element(ptr, XML_TAG_DESCR);
vendor_element = xkl_find_element(ptr, XML_TAG_VENDOR);
- if (name_element != NULL && name_element->children != NULL)
+ if (name_element != NULL && name_element->children != NULL) {
strncat(item->name,
(char *) name_element->children->content,
XKL_MAX_CI_NAME_LENGTH - 1);
+ s = utf8_check((guchar *)item->name);
+
+ for (i = strlen(item->name); i > 0 && s != NULL; i--) {
+ item->name[i] = 0;
+ s = utf8_check((guchar *)item->name);
+ }
+ }
+
if (short_desc_element != NULL
&& short_desc_element->children != NULL) {
strncat(item->short_description,
dgettext(XKB_DOMAIN, (const char *)
short_desc_element->children->content),
XKL_MAX_CI_SHORT_DESC_LENGTH - 1);
+
+ s = utf8_check((guchar *)item->short_description);
+
+ for (i = strlen(item->short_description); i > 0 && s != NULL; i--) {
+ item->short_description[i] = 0;
+ s = utf8_check((guchar *)item->short_description);
+ }
}
if (desc_element != NULL && desc_element->children != NULL) {
@@ -238,8 +257,18 @@
g_free(translated);
translated = unescaped;
}
+
strncat(item->description,
translated, XKL_MAX_CI_DESC_LENGTH - 1);
+
+ s = utf8_check((guchar *)item->description);
+
+ for (i = strlen(item->description); i > 0 && s != NULL; i--) {
+ item->description[i] = 0;
+ s = utf8_check((guchar *)item->description);
+ }
+
+ g_free(s);
g_free(translated);
}