Skip to content

Crash (SIGABRT) when mouse events are received (UTF8) #4

Description

@asessa

The application crashes with SIGABRT when terminal input contains mouse escape sequences (e.g. moving the mouse in a terminal that has mouse reporting enabled). The panic originates from std.unicode.utf8Decode in the standard library, triggered by event/input.zig passing a 32-byte slice where only a 1–4 byte slice is valid.

Zig Version: 0.15.2
OS: linux

Reproduce: Run any TUI app, move the mouse in the terminal > process aborts.

Cause: In src/event/input.zig, parseUtf8Char() receives the full stdin read buffer (e.g. 32 bytes). It calls std.unicode.utf8Decode(bytes), but Zig’s utf8Decode only accepts a slice of length 1–4 (one codepoint).
For any other length it hits else => unreachable and aborts.

Fix: Decode only the first codepoint: use utf8ByteSequenceLength(bytes[0]) to get seq_len, then call utf8Decode(bytes[0..seq_len]). On error or truncated input, return an unknown key event.

    fn parseUtf8Char(self: *InputReader, bytes: []const u8) ?Event {
        _ = self;
        if (bytes.len == 0) return null;

        // utf8Decode() only accepts a slice of exactly 1, 2, 3, or 4 bytes (one codepoint).
        // Passing a longer slice (e.g. 32 bytes from stdin) hits unreachable and aborts.
        const seq_len = std.unicode.utf8ByteSequenceLength(bytes[0]) catch {
            return Event{ .key = .{ .key = .{ .unknown = bytes[0] } } };
        };
        if (bytes.len < seq_len) {
            return Event{ .key = .{ .key = .{ .unknown = bytes[0] } } };
        }
        const cp = std.unicode.utf8Decode(bytes[0..seq_len]) catch {
            return Event{ .key = .{ .key = .{ .unknown = bytes[0] } } };
        };

        return Event{
            .key = .{ .key = .{ .char = cp } },
        };
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions