summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-10-02 16:01:36 -0400
committerTavian Barnes <tavianator@tavianator.com>2024-10-02 16:08:44 -0400
commitf5eaadb96fb94b2d3666e53a99495840a3099aec (patch)
tree92343f68c9b8391e9feb158e87169de32c29b98e /src
parent9c9dc01f38c808948c6ea508503f913fa800bb9a (diff)
downloadbfs-f5eaadb96fb94b2d3666e53a99495840a3099aec.tar.xz
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")
Diffstat (limited to 'src')
-rw-r--r--src/color.c10
1 files changed, 10 insertions, 0 deletions
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;