fix: overflow in find_in_files on large input

This commit is contained in:
CJ van den Berg 2024-12-17 17:04:33 +01:00
parent cbc8df69d3
commit 3be04c0303
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9

View file

@ -15,10 +15,12 @@ const name = "󰥨 find";
const Commands = command.Collection(cmds); const Commands = command.Collection(cmds);
const max_query_size = 1024;
allocator: Allocator, allocator: Allocator,
buf: [1024]u8 = undefined, buf: [max_query_size]u8 = undefined,
input: []u8 = "", input: []u8 = "",
last_buf: [1024]u8 = undefined, last_buf: [max_query_size]u8 = undefined,
last_input: []u8 = "", last_input: []u8 = "",
commands: Commands = undefined, commands: Commands = undefined,
@ -49,7 +51,7 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
defer self.update_mini_mode_text(); defer self.update_mini_mode_text();
if (try m.match(.{"F"})) { if (try m.match(.{"F"})) {
self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); self.start_query() catch |e| return tp.exit_error(e, @errorReturnTrace());
} else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) {
self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace()); self.insert_bytes(text) catch |e| return tp.exit_error(e, @errorReturnTrace());
} }
@ -57,28 +59,25 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
} }
fn insert_code_point(self: *Self, c: u32) !void { fn insert_code_point(self: *Self, c: u32) !void {
if (self.input.len + 16 > self.buf.len) if (self.input.len + 6 >= self.buf.len)
try self.flush_input(); return;
const bytes = try input.ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]); const bytes = try input.ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]);
self.input = self.buf[0 .. self.input.len + bytes]; self.input = self.buf[0 .. self.input.len + bytes];
} }
fn insert_bytes(self: *Self, bytes: []const u8) !void { fn insert_bytes(self: *Self, bytes_: []const u8) !void {
if (self.input.len + 16 > self.buf.len) const bytes = bytes_[0..@min(self.buf.len - self.input.len, bytes_.len)];
try self.flush_input();
const newlen = self.input.len + bytes.len; const newlen = self.input.len + bytes.len;
@memcpy(self.buf[self.input.len..newlen], bytes); @memcpy(self.buf[self.input.len..newlen], bytes);
self.input = self.buf[0..newlen]; self.input = self.buf[0..newlen];
} }
fn flush_input(self: *Self) !void { fn start_query(self: *Self) !void {
if (self.input.len > 2) { if (self.input.len < 1 or eql(u8, self.input, self.last_input))
if (eql(u8, self.input, self.last_input)) return;
return; @memcpy(self.last_buf[0..self.input.len], self.input);
@memcpy(self.last_buf[0..self.input.len], self.input); self.last_input = self.last_buf[0..self.input.len];
self.last_input = self.last_buf[0..self.input.len]; try command.executeName("find_in_files_query", command.fmt(.{self.input}));
try command.executeName("find_in_files_query", command.fmt(.{self.input}));
}
} }
fn update_mini_mode_text(self: *Self) void { fn update_mini_mode_text(self: *Self) void {
@ -94,7 +93,6 @@ const cmds = struct {
const Result = command.Result; const Result = command.Result;
pub fn mini_mode_reset(self: *Self, _: Ctx) Result { pub fn mini_mode_reset(self: *Self, _: Ctx) Result {
self.flush_input() catch {};
self.input = ""; self.input = "";
self.update_mini_mode_text(); self.update_mini_mode_text();
} }