From f5eaadb96fb94b2d3666e53a99495840a3099aec Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 2 Oct 2024 16:01:36 -0400 Subject: color: Fix an assertion failure with embedded NUL bytes Leading NUL bytes (e.g. `*\0.gz=...`) could cause us to insert a non-prefix-free set of strings into the case-insensitive extension trie, which would lead to crashes like bfs: trie_split@src/trie.c:538: Assertion failed: `key_nibble != rep_nibble` and OOB accesses to trie leaf keys. Fix it by ignoring those extensions, since filenames cannot contain NUL bytes. Fixes: 08030aea ("color: Delay the case_sensitive decision") --- src/color.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/color.c') diff --git a/src/color.c b/src/color.c index 37a22f9..0885726 100644 --- a/src/color.c +++ b/src/color.c @@ -237,6 +237,16 @@ static int insert_ext(struct trie *trie, struct ext_color *ext) { /** Set the color for an extension. */ static int set_ext(struct colors *colors, dchar *key, dchar *value) { size_t len = dstrlen(key); + + // Embedded NUL bytes in extensions can lead to a non-prefix-free + // set of strings, e.g. {".gz", "\0.gz"} would be transformed to + // {"zg.\0", "zg.\0\0"} (showing the implicit terminating NUL). + // Our trie implementation only supports prefix-free key sets, but + // luckily '\0' cannot appear in filenames so we can ignore them. + if (memchr(key, '\0', len)) { + return 0; + } + struct ext_color *ext = varena_alloc(&colors->ext_arena, len + 1); if (!ext) { return -1; -- cgit v1.2.3