Support include directive in user compose file

Also set Ctrl-period to default Emoji shortcut key
This commit is contained in:
Takao Fujiwara 2021-07-15 15:00:08 +09:00
parent 7da805820c
commit 533a7a748e
2 changed files with 515 additions and 1 deletions

View File

@ -2164,6 +2164,486 @@ index 15b2369d..54b7e0d7 100755
--
2.28.0
From 9f9c88be46436b0a7aa8e09e044a2223356b46dc Mon Sep 17 00:00:00 2001
From: lf- <software@lfcode.ca>
Date: Fri, 18 Jun 2021 15:39:19 +0900
Subject: [PATCH] src/ibuscomposetable: Add support for the include
directive
We also fix an issue with excess space at the start of lines stopping
comments being recognized.
BUG=https://github.com/ibus/ibus/pull/2296
---
src/ibuscomposetable.c | 100 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 95 insertions(+), 5 deletions(-)
diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
index 685ac717..66a5dfa7 100644
--- a/src/ibuscomposetable.c
+++ b/src/ibuscomposetable.c
@@ -21,7 +21,6 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <locale.h>
#include <stdlib.h>
#include <string.h>
@@ -36,6 +35,7 @@
#define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable"
#define IBUS_COMPOSE_TABLE_VERSION (3)
+#define PATHLEN_MAX 256
typedef struct {
gunichar *sequence;
@@ -181,7 +181,8 @@ parse_compose_sequence (IBusComposeData *compose_data,
int n = 0;
if (g_strv_length (words) < 2) {
- g_warning ("key sequence format is <a> <b>...: %s", line);
+ g_warning ("too few words; key sequence format is <a> <b>...: %s",
+ line);
goto fail;
}
@@ -244,10 +245,68 @@ fail:
}
+static gchar *
+expand_include_path (const gchar *include_path) {
+ gchar *out = g_malloc0 (PATHLEN_MAX);
+ gchar *out_lastchar = out + PATHLEN_MAX - 2;
+ const gchar *i = include_path;
+ gchar *o = out;
+
+ while (*i && o < out_lastchar) {
+ // expand sequence
+ if (*i == '%') {
+ switch (*(i+1)) {
+ // $HOME
+ case 'H': {
+ const gchar *home = getenv ("HOME");
+ if (!home) {
+ g_warning ("while parsing XCompose include target %s, "
+ "%%H replacement failed because HOME is not "
+ "defined; the include has been ignored",
+ include_path);
+ goto fail;
+ }
+ o = out + g_strlcat (out, home, PATHLEN_MAX);
+ break;
+ }
+ // locale compose file
+ case 'L':
+ g_warning ("while handling XCompose include target %s, found "
+ "redundant %%L include; the include has been "
+ "ignored", include_path);
+ goto fail;
+ // system compose dir
+ case 'S':
+ o = out + g_strlcat (out, "/usr/share/X11/locale",
+ PATHLEN_MAX);
+ break;
+ // escaped %
+ case '%':
+ *o++ = '%';
+ break;
+ default:
+ g_warning ("while parsing XCompose include target %s, found "
+ "unknown substitution character '%c'; the include "
+ "has been ignored", include_path, *(i+1));
+ goto fail;
+ }
+ i += 2;
+ } else {
+ *o++ = *i++;
+ }
+ }
+ return out;
+fail:
+ g_free (out);
+ return NULL;
+}
+
+
static void
parse_compose_line (GList **compose_list,
const gchar *line,
- int *compose_len)
+ int *compose_len,
+ gchar **include)
{
gchar **components = NULL;
IBusComposeData *compose_data = NULL;
@@ -256,11 +315,32 @@ parse_compose_line (GList **compose_list,
g_assert (compose_len);
*compose_len = 0;
+ // eat spaces at the start of the line
+ while (*line && (*line == ' ' || *line == '\t')) line++;
+
if (line[0] == '\0' || line[0] == '#')
return;
- if (g_str_has_prefix (line, "include "))
+ if (g_str_has_prefix (line, "include ")) {
+ const char *rest = line + sizeof ("include ") - 1;
+ while (*rest && *rest == ' ') rest++;
+
+ // grabbed the path part of the line
+ char *rest2;
+ if (*rest == '"') {
+ rest++;
+ rest2 = g_strdup (rest);
+ // eat the closing quote
+ char *i = rest2;
+ while (*i && *i != '"') i++;
+ *i = '\0';
+ } else {
+ rest2 = g_strdup (rest);
+ }
+ *include = expand_include_path (rest2);
+ g_free (rest2);
return;
+ }
components = g_strsplit (line, ":", 2);
@@ -316,8 +396,18 @@ ibus_compose_list_parse_file (const gchar *compose_file,
lines = g_strsplit (contents, "\n", -1);
g_free (contents);
+ gchar *include = NULL;
for (i = 0; lines[i] != NULL; i++) {
- parse_compose_line (&compose_list, lines[i], &compose_len);
+ parse_compose_line (&compose_list, lines[i], &compose_len, &include);
+ if (include && *include) {
+ GList *rest = ibus_compose_list_parse_file (include,
+ max_compose_len);
+ if (rest) {
+ compose_list = g_list_concat (compose_list, rest);
+ }
+ }
+
+ g_clear_pointer (&include, g_free);
if (*max_compose_len < compose_len)
*max_compose_len = compose_len;
}
--
2.28.0
From a755d1601a730b5fa0d463e7820311c12b1f1661 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 18 Jun 2021 15:39:50 +0900
Subject: [PATCH] src/ibuscomposetable: Do not include the same compose
file
BUG=https://github.com/ibus/ibus/pull/2296
---
src/ibuscomposetable.c | 130 +++++++++++++++++++++++++++++++----------
1 file changed, 100 insertions(+), 30 deletions(-)
diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
index 66a5dfa7..916fcae3 100644
--- a/src/ibuscomposetable.c
+++ b/src/ibuscomposetable.c
@@ -34,8 +34,8 @@
#include "ibusenginesimpleprivate.h"
#define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable"
-#define IBUS_COMPOSE_TABLE_VERSION (3)
-#define PATHLEN_MAX 256
+#define IBUS_COMPOSE_TABLE_VERSION (4)
+#define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale"
typedef struct {
gunichar *sequence;
@@ -247,17 +247,15 @@ fail:
static gchar *
expand_include_path (const gchar *include_path) {
- gchar *out = g_malloc0 (PATHLEN_MAX);
- gchar *out_lastchar = out + PATHLEN_MAX - 2;
- const gchar *i = include_path;
- gchar *o = out;
+ gchar *out = strdup ("");
+ const gchar *head, *i;
+ gchar *former, *o;
- while (*i && o < out_lastchar) {
- // expand sequence
+ for (head = i = include_path; *i; ++i) {
+ /* expand sequence */
if (*i == '%') {
- switch (*(i+1)) {
- // $HOME
- case 'H': {
+ switch (*(i + 1)) {
+ case 'H': { /* $HOME */
const gchar *home = getenv ("HOME");
if (!home) {
g_warning ("while parsing XCompose include target %s, "
@@ -266,23 +264,34 @@ expand_include_path (const gchar *include_path) {
include_path);
goto fail;
}
- o = out + g_strlcat (out, home, PATHLEN_MAX);
+ o = out;
+ former = g_strndup (head, i - head);
+ out = g_strdup_printf ("%s%s%s", o, former, home);
+ head = i + 2;
+ g_free (o);
+ g_free (former);
break;
}
- // locale compose file
- case 'L':
+ case 'L': /* locale compose file */
g_warning ("while handling XCompose include target %s, found "
"redundant %%L include; the include has been "
"ignored", include_path);
goto fail;
- // system compose dir
- case 'S':
- o = out + g_strlcat (out, "/usr/share/X11/locale",
- PATHLEN_MAX);
+ case 'S': /* system compose dir */
+ o = out;
+ former = g_strndup (head, i - head);
+ out = g_strdup_printf ("%s%s%s", o, former, X11_DATADIR);
+ head = i + 2;
+ g_free (o);
+ g_free (former);
break;
- // escaped %
- case '%':
- *o++ = '%';
+ case '%': /* escaped % */
+ o = out;
+ former = g_strndup (head, i - head);
+ out = g_strdup_printf ("%s%s%s", o, former, "%");
+ head = i + 2;
+ g_free (o);
+ g_free (former);
break;
default:
g_warning ("while parsing XCompose include target %s, found "
@@ -290,11 +299,12 @@ expand_include_path (const gchar *include_path) {
"has been ignored", include_path, *(i+1));
goto fail;
}
- i += 2;
- } else {
- *o++ = *i++;
+ ++i;
}
}
+ o = out;
+ out = g_strdup_printf ("%s%s", o, head);
+ g_free (o);
return out;
fail:
g_free (out);
@@ -315,7 +325,7 @@ parse_compose_line (GList **compose_list,
g_assert (compose_len);
*compose_len = 0;
- // eat spaces at the start of the line
+ /* eat spaces at the start of the line */
while (*line && (*line == ' ' || *line == '\t')) line++;
if (line[0] == '\0' || line[0] == '#')
@@ -325,12 +335,12 @@ parse_compose_line (GList **compose_list,
const char *rest = line + sizeof ("include ") - 1;
while (*rest && *rest == ' ') rest++;
- // grabbed the path part of the line
+ /* grabbed the path part of the line */
char *rest2;
if (*rest == '"') {
rest++;
rest2 = g_strdup (rest);
- // eat the closing quote
+ /* eat the closing quote */
char *i = rest2;
while (*i && *i != '"') i++;
*i = '\0';
@@ -374,6 +384,23 @@ fail:
}
+static gchar *
+get_en_compose_file (void)
+{
+ gchar * const sys_langs[] = { "en_US.UTF-8", "en_US", "en.UTF-8",
+ "en", NULL };
+ gchar * const *sys_lang = NULL;
+ gchar *path = NULL;
+ for (sys_lang = sys_langs; *sys_lang; sys_lang++) {
+ path = g_build_filename (X11_DATADIR, *sys_lang, "Compose", NULL);
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ break;
+ g_free (path);
+ }
+ return path;
+}
+
+
static GList *
ibus_compose_list_parse_file (const gchar *compose_file,
int *max_compose_len)
@@ -399,6 +426,52 @@ ibus_compose_list_parse_file (const gchar *compose_file,
gchar *include = NULL;
for (i = 0; lines[i] != NULL; i++) {
parse_compose_line (&compose_list, lines[i], &compose_len, &include);
+ if (*max_compose_len < compose_len)
+ *max_compose_len = compose_len;
+ if (include && *include) {
+ GStatBuf buf_include = { 0, };
+ GStatBuf buf_parent = { 0, };
+ gchar *en_compose;
+ errno = 0;
+ if (g_stat (include, &buf_include)) {
+ g_warning ("Cannot access %s: %s",
+ include,
+ g_strerror (errno));
+ g_clear_pointer (&include, g_free);
+ continue;
+ }
+ errno = 0;
+ if (g_stat (compose_file, &buf_parent)) {
+ g_warning ("Cannot access %s: %s",
+ compose_file,
+ g_strerror (errno));
+ g_clear_pointer (&include, g_free);
+ continue;
+ }
+ if (buf_include.st_ino == buf_parent.st_ino) {
+ g_warning ("Found recursive nest same file %s", include);
+ g_clear_pointer (&include, g_free);
+ continue;
+ }
+ en_compose = get_en_compose_file ();
+ if (en_compose) {
+ errno = 0;
+ if (g_stat (en_compose, &buf_parent)) {
+ g_warning ("Cannot access %s: %s",
+ compose_file,
+ g_strerror (errno));
+ g_clear_pointer (&include, g_free);
+ g_free (en_compose);
+ continue;
+ }
+ }
+ g_free (en_compose);
+ if (buf_include.st_ino == buf_parent.st_ino) {
+ g_log ("System en_US Compose is already loaded %s\n", include);
+ g_clear_pointer (&include, g_free);
+ continue;
+ }
+ }
if (include && *include) {
GList *rest = ibus_compose_list_parse_file (include,
max_compose_len);
@@ -406,10 +479,7 @@ ibus_compose_list_parse_file (const gchar *compose_file,
compose_list = g_list_concat (compose_list, rest);
}
}
-
g_clear_pointer (&include, g_free);
- if (*max_compose_len < compose_len)
- *max_compose_len = compose_len;
}
g_strfreev (lines);
--
2.28.0
From 7f09379b3cb69c7de6d8d667ce398dcfc0000433 Mon Sep 17 00:00:00 2001
From: lf- <software@lfcode.ca>
Date: Thu, 24 Jun 2021 16:10:12 +0900
Subject: [PATCH] src/ibuscomposetable: Fix a buffer overflow in compose
handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
I believe this has no security impact but it is making my Valgrind sad.
Thanks to Omni for the help in finding the root cause of this.
~/.XCompose is:
```
<Multi_key> <g> <h> : "η"
<Multi_key> <g> <v> <t> <h> : "ϑ"
<Multi_key> <g> <h> : "ɣ"
```
BUG=https://github.com/ibus/ibus/pull/2297
---
src/ibuscomposetable.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
index 916fcae3..dd7cbf83 100644
--- a/src/ibuscomposetable.c
+++ b/src/ibuscomposetable.c
@@ -410,7 +410,6 @@ ibus_compose_list_parse_file (const gchar *compose_file,
gsize length = 0;
GError *error = NULL;
GList *compose_list = NULL;
- int compose_len = 0;
int i;
g_assert (max_compose_len);
@@ -423,8 +422,9 @@ ibus_compose_list_parse_file (const gchar *compose_file,
lines = g_strsplit (contents, "\n", -1);
g_free (contents);
- gchar *include = NULL;
for (i = 0; lines[i] != NULL; i++) {
+ int compose_len = 0;
+ gchar *include = NULL;
parse_compose_line (&compose_list, lines[i], &compose_len, &include);
if (*max_compose_len < compose_len)
*max_compose_len = compose_len;
@@ -467,7 +467,8 @@ ibus_compose_list_parse_file (const gchar *compose_file,
}
g_free (en_compose);
if (buf_include.st_ino == buf_parent.st_ino) {
- g_log ("System en_US Compose is already loaded %s\n", include);
+ g_message ("System en_US Compose is already loaded %s\n",
+ include);
g_clear_pointer (&include, g_free);
continue;
}
@@ -583,12 +584,20 @@ ibus_compose_data_compare (gpointer a,
IBusComposeData *compose_data_b = b;
int max_compose_len = GPOINTER_TO_INT (data);
int i;
+ /* The allocation length of compose_data_a->sequence[] is different from
+ * one of compose_data_b->sequence[] and max_compose_len indicates
+ * the sequence length only but not include the compose value length.
+ * So max_compose_len is greater than any allocation lengths of sequence[]
+ * and this API should return if code_a or code_b is 0.
+ */
for (i = 0; i < max_compose_len; i++) {
gunichar code_a = compose_data_a->sequence[i];
gunichar code_b = compose_data_b->sequence[i];
if (code_a != code_b)
return code_a - code_b;
+ if (code_a == 0 && code_b == 0)
+ return 0;
}
return 0;
}
--
2.28.0
From ab6b9587a497e9662a2936df3dabed4582eeabdb Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Tue, 29 Jun 2021 12:40:20 +0900
@ -2214,3 +2694,33 @@ index 54b7e0d7..0ef72c03 100755
--
2.28.0
From b952d30a1b7c741052c168fe1081ecb4d4b1c034 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 14 Jul 2021 22:31:47 +0900
Subject: [PATCH] Change default Emoji shortcut key
The shortcut key was Ctrl-Shit-e to follow Unicode code point
shortcut key but now the shorcut key is changed to Ctrl-period
to follow GTK.
BUG=https://github.com/ibus/ibus/issues/2325
---
data/dconf/org.freedesktop.ibus.gschema.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml
index a79e9296..099b9c60 100644
--- a/data/dconf/org.freedesktop.ibus.gschema.xml
+++ b/data/dconf/org.freedesktop.ibus.gschema.xml
@@ -183,7 +183,7 @@
<description>The shortcut keys for turning Unicode typing on or off</description>
</key>
<key name="hotkey" type="as">
- <default>[ '&lt;Control&gt;&lt;Shift&gt;e' ]</default>
+ <default>[ '&lt;Control&gt;period' ]</default>
<summary>Emoji shortcut keys for gtk_accelerator_parse</summary>
<description>The shortcut keys for turning emoji typing on or off</description>
</key>
--
2.28.0

View File

@ -38,7 +38,7 @@
Name: ibus
Version: 1.5.24
Release: 9%{?dist}
Release: 10%{?dist}
Summary: Intelligent Input Bus for Linux OS
License: LGPLv2+
URL: https://github.com/ibus/%name/wiki
@ -510,6 +510,10 @@ dconf update || :
%{_datadir}/installed-tests/ibus
%changelog
* Thu Jul 15 2021 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.24-10
- Support include directive in user compose file
- Set Ctrl-period to default Emoji shortcut key
* Tue Jun 29 2021 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.24-9
- Delete G_MESSAGES_DEBUG for gsettings output