Skip to content

explore: searchInContent integer overflow when query is longer than file content (SIGBUS in ReleaseFast) #431

@justrach

Description

@justrach

Problem

searchInContent in src/explore.zig:3881 computes:

const end = content.len - query.len + 1;

without checking that query.len <= content.len. When the query is longer than an indexed file's content, the subtraction underflows in usize and the binary aborts with an integer-overflow panic (Debug) or SIGBUS (ReleaseFast).

This is reachable from any code path that calls searchContent/searchInContent with an arbitrary user query, including the public CLI codedb search command and the codedb_search MCP tool. A user submitting any query longer than the smallest indexed file (which can be a stub __init__.py of one byte, or a near-empty Zig file) crashes the daemon.

Reproducer:

echo "fn x() void {}" > /tmp/tiny/a.zig
codedb /tmp/tiny search "$(python3 -c "print('a'*256)")"
# → SIGBUS (exit 138) in ReleaseFast, or integer-overflow panic in Debug

The eval surfaced this at 128+ chars on the real codedb repo (where the smallest indexed file is shorter than 128 bytes).

Failing Test

test "issue-431: searchContent does not crash when query is longer than content" {
    var arena = std.heap.ArenaAllocator.init(testing.allocator);
    defer arena.deinit();
    var explorer = Explorer.init(arena.allocator());

    try explorer.indexFile("a.zig", "fn x() void {}\n");

    var q_buf: [256]u8 = undefined;
    @memset(&q_buf, 'a');
    const q = q_buf[0..256];

    const results = try explorer.searchContent(q, testing.allocator, 5);
    // ...defer free...
    try testing.expect(results.len == 0);
}

Branch issue-431-failing-test (commit 13bbd36).

$ zig build test 2>&1 | rg "issue-431"
error: 'tests.test.issue-431: searchContent does not crash when query is longer than content' terminated with signal ABRT
       thread X panic: integer overflow
       .../src/explore.zig:3881:29: in searchInContent
           const end = content.len - query.len + 1;
                                   ^

Expected

A query longer than the indexed file's content yields no matches for that file (correct, harmless), and the function returns without crashing.

Fix

One-line guard at the top of searchInContent (src/explore.zig:3874-3875):

fn searchInContent(...) !void {
    if (query.len == 0 or content.len == 0) return;
+   if (query.len > content.len) return;
    ...
}

Effort: trivial.

Eval context

Surfaced by the issue-429-fix validation run (Sonnet 4.6 agent against the codedb codebase). Pre-existing on main; same crash on the deployed 0.2.5805 binary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p0Highest priority

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions