Skip to content

Commit

Permalink
compose: Fix iterator for empty tables
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wismill committed Jan 16, 2024
1 parent 1034f27 commit 2a7e89e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
14 changes: 9 additions & 5 deletions src/compose/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
}
Expand Down
12 changes: 11 additions & 1 deletion test/compose.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,17 @@ 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);

/* Non-empty table */
const char *buffer = "<dead_circumflex> <dead_circumflex> : \"foo\" X\n"
"<Ahook> <x> : \"foobar\"\n"
"<Multi_key> <o> <e> : oe\n"
Expand All @@ -725,7 +735,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, "é",
Expand Down

0 comments on commit 2a7e89e

Please sign in to comment.