From 8cca3a7bfb185876994d6ec3d25cda88e5640a4d Mon Sep 17 00:00:00 2001 From: Pierre Le Marre Date: Tue, 5 Dec 2023 17:39:59 +0100 Subject: [PATCH] compose: Add XKB_COMPOSE_MAX_STRING_SIZE Define the maximum size of a compose sequence result string explicit as a constant and use it everywhere to improve the code readability. --- src/compose/parser.c | 8 +++++--- src/compose/parser.h | 2 ++ test/compose.c | 24 +++++++++++++++++++++++- tools/tools-common.c | 5 ++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/compose/parser.c b/src/compose/parser.c index a34d10b..7b67731 100644 --- a/src/compose/parser.c +++ b/src/compose/parser.c @@ -328,7 +328,7 @@ struct production { xkb_keysym_t lhs[MAX_LHS_LEN]; unsigned int len; xkb_keysym_t keysym; - char string[256]; + char string[XKB_COMPOSE_MAX_STRING_SIZE]; /* At least one of these is true. */ bool has_keysym; bool has_string; @@ -687,8 +687,10 @@ rhs: scanner_warn(s, "right-hand side string must not be empty; skipping line"); goto skip; } - if (val.string.len >= sizeof(production.string)) { - scanner_warn(s, "right-hand side string is too long; skipping line"); + if (val.string.len > sizeof(production.string)) { + scanner_warn(s, + "right-hand side string is too long: expected max: %d, got: %d; " + "skipping line", (int)sizeof(production.string) - 1, (int)val.string.len); goto skip; } strcpy(production.string, val.string.str); diff --git a/src/compose/parser.h b/src/compose/parser.h index 8651ee6..4303f3f 100644 --- a/src/compose/parser.h +++ b/src/compose/parser.h @@ -26,6 +26,8 @@ #define MAX_LHS_LEN 10 #define MAX_INCLUDE_DEPTH 5 +/** Maximum size of the string returned by xkb_compose_state_get_utf8() */ +#define XKB_COMPOSE_MAX_STRING_SIZE 256 char * parse_string_literal(struct xkb_context *ctx, const char *string); diff --git a/test/compose.c b/test/compose.c index 8508ea9..3da3c7d 100644 --- a/test/compose.c +++ b/test/compose.c @@ -74,7 +74,7 @@ test_compose_seq_va(struct xkb_compose_table *table, va_list ap) { int ret; struct xkb_compose_state *state; - char buffer[XKB_KEYSYM_NAME_MAX_SIZE]; + char buffer[MAX(XKB_COMPOSE_MAX_STRING_SIZE, XKB_KEYSYM_NAME_MAX_SIZE)]; state = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); assert(state); @@ -773,6 +773,27 @@ test_traverse(struct xkb_context *ctx) xkb_compose_table_unref(table); } +static void +test_string_length(struct xkb_context *ctx) +{ + // Invalid: empty string + const char table_string_1[] = " : \"\" X\n"; + assert(test_compose_seq_buffer(ctx, table_string_1, + XKB_KEY_a, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_b, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "", XKB_KEY_X, + XKB_KEY_NoSymbol)); + + char long_string[XKB_COMPOSE_MAX_STRING_SIZE] = { 0 }; + memset(long_string, 0x61, XKB_COMPOSE_MAX_STRING_SIZE - 1); + char table_string_2[XKB_COMPOSE_MAX_STRING_SIZE + sizeof(table_string_1) - 1]; + assert(snprintf_safe(table_string_2, sizeof(table_string_2), + " : \"%s\" X\n", long_string)); + assert(test_compose_seq_buffer(ctx, table_string_2, + XKB_KEY_a, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_b, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, long_string, XKB_KEY_X, + XKB_KEY_NoSymbol)); +} + static void test_decode_escape_sequences(struct xkb_context *ctx) { @@ -936,6 +957,7 @@ main(int argc, char *argv[]) test_include(ctx); test_override(ctx); test_traverse(ctx); + test_string_length(ctx); test_decode_escape_sequences(ctx); test_encode_escape_sequences(ctx); diff --git a/tools/tools-common.c b/tools/tools-common.c index 5113cba..0e63648 100644 --- a/tools/tools-common.c +++ b/tools/tools-common.c @@ -51,6 +51,7 @@ #include "tools-common.h" #include "src/utils.h" #include "src/keysym.h" +#include "src/compose/parser.h" static void print_keycode(struct xkb_keymap *keymap, const char* prefix, @@ -157,9 +158,7 @@ tools_print_keycode_state(char *prefix, xkb_keysym_t sym; const xkb_keysym_t *syms; int nsyms; - // FIXME: this buffer is used for xkb_compose_state_get_utf8, - // which can have a length up to 256. Need to import this constant from compose. - char s[MAX(16, XKB_KEYSYM_NAME_MAX_SIZE)]; + char s[MAX(XKB_COMPOSE_MAX_STRING_SIZE, XKB_KEYSYM_NAME_MAX_SIZE)]; xkb_layout_index_t layout; enum xkb_compose_status status;