Commit 1638409b22aef33d487863876ab214b949db4984

Ran Benita 2021-03-30T17:52:36

compose: add a limit of 65535 sequences Fits in uint16_t, which enables some future optimizations. But also a good idea to have some limit. Not aware of any compose files which come close. Signed-off-by: Ran Benita <ran@unusedvar.com>

diff --git a/src/compose/parser.c b/src/compose/parser.c
index 0f85a92..dea3d3b 100644
--- a/src/compose/parser.c
+++ b/src/compose/parser.c
@@ -327,7 +327,7 @@ struct production {
     xkb_mod_mask_t mods;
 };
 
-static uint32_t
+static uint16_t
 add_node(struct xkb_compose_table *table, xkb_keysym_t keysym)
 {
     struct compose_node new = {
@@ -344,9 +344,14 @@ add_production(struct xkb_compose_table *table, struct scanner *s,
                const struct production *production)
 {
     unsigned lhs_pos;
-    uint32_t curr;
+    uint16_t curr;
     struct compose_node *node;
 
+    if (darray_size(table->nodes) + 1 == MAX_COMPOSE_NODES)
+        scanner_warn(s, "too many sequences for one Compose file; will ignore further lines");
+    if (darray_size(table->nodes) >= MAX_COMPOSE_NODES)
+        return;
+
     curr = 0;
     node = &darray_item(table->nodes, curr);
 
@@ -363,7 +368,7 @@ add_production(struct xkb_compose_table *table, struct scanner *s,
     for (lhs_pos = 0; lhs_pos < production->len; lhs_pos++) {
         while (production->lhs[lhs_pos] != node->keysym) {
             if (node->next == 0) {
-                uint32_t next = add_node(table, production->lhs[lhs_pos]);
+                uint16_t next = add_node(table, production->lhs[lhs_pos]);
                 /* Refetch since add_node could have realloc()ed. */
                 node = &darray_item(table->nodes, curr);
                 node->next = next;
@@ -385,7 +390,7 @@ add_production(struct xkb_compose_table *table, struct scanner *s,
             }
 
             {
-                uint32_t successor = add_node(table, production->lhs[lhs_pos + 1]);
+                uint16_t successor = add_node(table, production->lhs[lhs_pos + 1]);
                 /* Refetch since add_node could have realloc()ed. */
                 node = &darray_item(table->nodes, curr);
                 node->is_leaf = false;
diff --git a/src/compose/state.c b/src/compose/state.c
index 9c64eb4..00c1abe 100644
--- a/src/compose/state.c
+++ b/src/compose/state.c
@@ -41,8 +41,8 @@ struct xkb_compose_state {
      * This is also sufficient for inferring the current status; see
      * xkb_compose_state_get_status().
      */
-    uint32_t prev_context;
-    uint32_t context;
+    uint16_t prev_context;
+    uint16_t context;
 };
 
 XKB_EXPORT struct xkb_compose_state *
@@ -91,7 +91,7 @@ xkb_compose_state_get_compose_table(struct xkb_compose_state *state)
 XKB_EXPORT enum xkb_compose_feed_result
 xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym)
 {
-    uint32_t context;
+    uint16_t context;
     const struct compose_node *node;
 
     /*
diff --git a/src/compose/table.h b/src/compose/table.h
index 05a415f..a051e1b 100644
--- a/src/compose/table.h
+++ b/src/compose/table.h
@@ -68,15 +68,18 @@
  * \0 is so offset 0 points to an empty string).
  */
 
+/* Fits in uint16_t, also a good idea to have some limit. */
+#define MAX_COMPOSE_NODES 65535
+
 struct compose_node {
     xkb_keysym_t keysym;
     /* Offset into xkb_compose_table::nodes. */
-    unsigned int next:31;
-    bool is_leaf:1;
+    uint16_t next;
+    bool is_leaf;
 
     union {
         /* Offset into xkb_compose_table::nodes. */
-        uint32_t successor;
+        uint16_t successor;
         struct {
             /* Offset into xkb_compose_table::utf8. */
             uint32_t utf8;