cantino / mcfly

Fly through your shell history. Great Scott!
MIT License
6.9k stars 178 forks source link

Panic when search starts with underscore #441

Open ragne opened 1 month ago

ragne commented 1 month ago

Hi, I'm running mcfly on

and simply invoking it with zsh binding (ctrl+r) and searching for anything that starts with underscore _ panics with thread 'main' panicked at src/interface.rs:1008:51:

Sorry I don't have much time right now to look at the what exactly causes that, I can look in a week if no one pics that up.

The best backtrace i could get is this one:

thread 'main' panicked at src/interface.rs:1008:51: byte index 1 is not a char boundary; it is inside '│' (bytes 0..3) of `││\`
stack backtrace:
       0: _rust_begin_unwind
       1: core::panicking::panic_fmt
       2: core::str::slice_error_fail_rt
       3: core::str::slice_error_fail
       4: mcfly::interface::Interface::results
       5: mcfly::interface::Interface::display
       6: mcfly::main
      note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

This is reformatted, so i hope i didn't butcher it while doing so

cantino commented 1 month ago

Hey @ragne, thanks for reporting this issue. Are you seeing it when you type on the command line and hit ctrl-r, or when you're in the mcfly UI? I can't reproduce on either in fuzzy and non-fuzzy mode on my Mac.

ragne commented 1 month ago

Hey @cantino, thanks for the response. I've tried to dig down and added code before this line https://github.com/cantino/mcfly/blob/master/src/interface.rs#L1002

                let mut file = std::fs::File::create("/tmp/mcflylog.txt").unwrap();
                write!(file, "***\n");
                write!(file, "Cmd: {:?}, start: {}, end: {}", &command.cmd.as_bytes(), start, end);
                write!(file, "***\n");

And got this output:

***
Cmd: [226, 148, 130, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 226, 148, 130, 92], start: 0, end: 1***

The start of the array is a valid utf-8 codepoint (U+2502) which is yet another way to represent the vertical bar | and the whole command is just two "Box Drawings Light Vertical" with a lot of spaces in-between.

I think (but I might be wrong) that the problem comes from this method. If I put some prints around

        println!("{:?}, cmd: {:?}", &self.matches, &self.input.command);
        self.matches = ...
        println!("after: {:?}", &self.matches);

it then would output:

[], cmd: "_"
            after: [Command { id: 300, cmd: "│                                                                                                                                                                                                                                │\\", cmd_tpl: "│ ", session_id: "IMPORTED", rank: 0.9990856813311875, when_run: Some(1717154363), last_run: Some(1717154363), exit_code: Some(0), selected: false, dir: None, features: Features { age_factor: 1.0, length_factor: 0.01931586113002042, exit_factor: 1.0, recent_failure_factor: 0.0, selected_dir_factor: 0.0, dir_factor: 0.0, overlap_factor: 0.0, immediate_overlap_factor: 0.0, selected_occurrences_factor: 0.0, occurrences_factor: 1.0 }, match_bounds: [(0, 1)] }, Command { id: 224, cmd: "git s", cmd_tpl: "git s", session_id: "IMPORTED", rank: 0.9964779581820393, when_run: Some(1717154363), last_run: Some(1726224725), exit_code: Some(0), selected: false, dir: None,  %

So if you have time you can probably create an empty db and use that string with "Box Drawings Light Vertical" symbol to replicate that. For freshly cloned master branch the repro is simple as cargo run -- search _ in my case.

Sorry, I don't have time yet to produce a fresh history db to easy the reproduction. For me the bug isn't that impactful, so please don't focus too hard on it. I believe it's unique to my history/set-up, so it might be rarely (if ever) encountered "in the wild".

P.S. I have no idea if it's possible to force GH not to use horizontal scroll bar for code blocks :\