From 0038c866078a409b40d4d194f597768284d7ff32 Mon Sep 17 00:00:00 2001 From: Pierre Le Marre Date: Tue, 26 Sep 2023 17:05:14 +0200 Subject: [PATCH] Prevent overflow of octal escape sequences The octal parser accepts the range `\1..\777`. The result is cast to `char` which will silently overflow. This commit prevents overlow and will treat `\400..\777` as invalid escape sequences. --- src/scanner-utils.h | 9 ++++++++- test/compose.c | 6 +++++- test/data/keymaps/invalid-escape-sequence.xkb | 4 +++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/scanner-utils.h b/src/scanner-utils.h index f4c799eeb..674ecaa0e 100644 --- a/src/scanner-utils.h +++ b/src/scanner-utils.h @@ -188,7 +188,14 @@ scanner_oct(struct scanner *s, uint8_t *out) { int i; for (i = 0, *out = 0; scanner_peek(s) >= '0' && scanner_peek(s) <= '7' && i < 3; i++) - *out = *out * 8 + scanner_next(s) - '0'; + /* Test overflow */ + if (*out < 040) { + *out = *out * 8 + scanner_next(s) - '0'; + } else { + /* Consume valid digit, but mark result as invalid */ + scanner_next(s); + return false; + } return i > 0; } diff --git a/test/compose.c b/test/compose.c index 3d4580503..8c633d704 100644 --- a/test/compose.c +++ b/test/compose.c @@ -687,7 +687,11 @@ test_traverse(struct xkb_context *ctx) static void test_escape_sequences(struct xkb_context *ctx) { - const char *table_string = " : \"f\\x0o\\0o\" X\n"; + /* The following escape sequences should be ignored: + * • \401 overflows + * • \0 and \x0 produce NULL + */ + const char *table_string = " : \"\\401f\\x0o\\0o\" X\n"; assert(test_compose_seq_buffer(ctx, table_string, XKB_KEY_o, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, diff --git a/test/data/keymaps/invalid-escape-sequence.xkb b/test/data/keymaps/invalid-escape-sequence.xkb index 99349ec78..5e66f8b50 100644 --- a/test/data/keymaps/invalid-escape-sequence.xkb +++ b/test/data/keymaps/invalid-escape-sequence.xkb @@ -3,7 +3,9 @@ xkb_keymap { // must be ignored. Else it would insert a NULL character and thus // truncates the string to "evde", while we expect "evdev+aliases(qwerty)". xkb_keycodes { include "evde\0v+aliases(qwerty)" }; - xkb_types { include "complete" }; + // The following include statement has two octal escape sequences that + // should be ignored, else they would overflow. + xkb_types { include "com\401ple\777te" }; xkb_compat { include "complete" }; xkb_symbols { include "pc+us" }; };