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.
master
Pierre Le Marre 2024-01-16 11:04:59 +01:00 committed by Wismill
parent 1034f272e4
commit 43c9752d44
2 changed files with 22 additions and 6 deletions

View File

@ -275,7 +275,6 @@ XKB_EXPORT struct xkb_compose_table_iterator *
xkb_compose_table_iterator_new(struct xkb_compose_table *table) xkb_compose_table_iterator_new(struct xkb_compose_table *table)
{ {
struct xkb_compose_table_iterator *iter; struct xkb_compose_table_iterator *iter;
struct xkb_compose_table_iterator_cursor cursor;
xkb_keysym_t *sequence; xkb_keysym_t *sequence;
iter = calloc(1, sizeof(*iter)); iter = calloc(1, sizeof(*iter));
@ -292,10 +291,15 @@ xkb_compose_table_iterator_new(struct xkb_compose_table *table)
iter->entry.sequence_length = 0; iter->entry.sequence_length = 0;
darray_init(iter->cursors); darray_init(iter->cursors);
cursor.direction = NODE_LEFT; /* Add first cursor only if there is at least one non-dummy node */
/* Offset 0 is a dummy null entry, skip it. */ if (darray_size(iter->table->nodes) > 1) {
cursor.node_offset = 1; const struct xkb_compose_table_iterator_cursor cursor = {
darray_append(iter->cursors, cursor); .direction = NODE_LEFT,
/* Offset 0 is a dummy null entry, skip it. */
.node_offset = 1
};
darray_append(iter->cursors, cursor);
}
return iter; return iter;
} }

View File

@ -708,7 +708,19 @@ static void
test_traverse(struct xkb_context *ctx) test_traverse(struct xkb_context *ctx)
{ {
struct xkb_compose_table *table; 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 = "<dead_circumflex> <dead_circumflex> : \"foo\" X\n" const char *buffer = "<dead_circumflex> <dead_circumflex> : \"foo\" X\n"
"<Ahook> <x> : \"foobar\"\n" "<Ahook> <x> : \"foobar\"\n"
"<Multi_key> <o> <e> : oe\n" "<Multi_key> <o> <e> : oe\n"
@ -725,7 +737,7 @@ test_traverse(struct xkb_context *ctx)
XKB_COMPOSE_COMPILE_NO_FLAGS); XKB_COMPOSE_COMPILE_NO_FLAGS);
assert(table); 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), test_eq_entry(xkb_compose_table_iterator_next(iter),
XKB_KEY_eacute, "é", XKB_KEY_eacute, "é",