From 43c9752d441702011500e562c8bbc41ec0254772 Mon Sep 17 00:00:00 2001 From: Pierre Le Marre Date: Tue, 16 Jan 2024 11:04:59 +0100 Subject: [PATCH] compose: Fix iterator for empty tables The current `xkb_compose_table_iterator_next` segfaults when used with an empty table. Indeed, in this case we initialize cursors in `xkb_compose_table_iterator_new` with the dummy node and the direction `NODE_LEFT`, but the dummy node is a leaf! Fixed by initializing with no cursors when the table is has no non-dummy nodes. --- src/compose/table.c | 14 +++++++++----- test/compose.c | 14 +++++++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/compose/table.c b/src/compose/table.c index 04fa8cb..254db0b 100644 --- a/src/compose/table.c +++ b/src/compose/table.c @@ -275,7 +275,6 @@ XKB_EXPORT struct xkb_compose_table_iterator * xkb_compose_table_iterator_new(struct xkb_compose_table *table) { struct xkb_compose_table_iterator *iter; - struct xkb_compose_table_iterator_cursor cursor; xkb_keysym_t *sequence; iter = calloc(1, sizeof(*iter)); @@ -292,10 +291,15 @@ xkb_compose_table_iterator_new(struct xkb_compose_table *table) iter->entry.sequence_length = 0; darray_init(iter->cursors); - cursor.direction = NODE_LEFT; - /* Offset 0 is a dummy null entry, skip it. */ - cursor.node_offset = 1; - darray_append(iter->cursors, cursor); + /* Add first cursor only if there is at least one non-dummy node */ + if (darray_size(iter->table->nodes) > 1) { + const struct xkb_compose_table_iterator_cursor cursor = { + .direction = NODE_LEFT, + /* Offset 0 is a dummy null entry, skip it. */ + .node_offset = 1 + }; + darray_append(iter->cursors, cursor); + } return iter; } diff --git a/test/compose.c b/test/compose.c index 3da3c7d..50ac40a 100644 --- a/test/compose.c +++ b/test/compose.c @@ -708,7 +708,19 @@ static void test_traverse(struct xkb_context *ctx) { struct xkb_compose_table *table; + struct xkb_compose_table_iterator *iter; + /* Empty table */ + table = xkb_compose_table_new_from_buffer(ctx, "", 0, "", + XKB_COMPOSE_FORMAT_TEXT_V1, + XKB_COMPOSE_COMPILE_NO_FLAGS); + assert(table); + iter = xkb_compose_table_iterator_new(table); + assert (xkb_compose_table_iterator_next(iter) == NULL); + xkb_compose_table_iterator_free(iter); + xkb_compose_table_unref(table); + + /* Non-empty table */ const char *buffer = " : \"foo\" X\n" " : \"foobar\"\n" " : oe\n" @@ -725,7 +737,7 @@ test_traverse(struct xkb_context *ctx) XKB_COMPOSE_COMPILE_NO_FLAGS); assert(table); - struct xkb_compose_table_iterator *iter = xkb_compose_table_iterator_new(table); + iter = xkb_compose_table_iterator_new(table); test_eq_entry(xkb_compose_table_iterator_next(iter), XKB_KEY_eacute, "é",