Add visible v1 diagnostics guardrails

This commit is contained in:
slhx agent
2026-06-21 05:38:52 +02:00
parent a1600e511a
commit 8658f7cc95
7 changed files with 180 additions and 7 deletions
+28 -3
View File
@@ -1,5 +1,6 @@
const std = @import("std");
const context_mod = @import("context.zig");
const diagnostics_mod = @import("diagnostics.zig");
const input = @import("input.zig");
const job_mod = @import("job.zig");
const leader_mod = @import("leader.zig");
@@ -327,8 +328,20 @@ pub const Client = struct {
}
fn addRepoFile(self: *Client, payload: []const u8) !void {
const separator = std.mem.indexOfScalar(u8, payload, '=') orelse return repo_mod.Error.InvalidPath;
try self.repo.addFile(payload[0..separator], payload[separator + 1 ..]);
const separator = std.mem.indexOfScalar(u8, payload, '=') orelse {
self.message = "diagnostic:unsupported_file:invalid_repo_file_payload";
return repo_mod.Error.InvalidPath;
};
const file_bytes = payload[separator + 1 ..];
if (file_bytes.len > diagnostics_mod.max_file_bytes) {
self.message = "diagnostic:file_too_large";
return Error.ProtocolRejected;
}
self.repo.addFile(payload[0..separator], file_bytes) catch |err| {
self.message = "diagnostic:unsupported_file";
return err;
};
self.message = null;
}
fn openRepoList(self: *Client, title: []const u8, tree: bool, include_ignored: bool) !void {
@@ -355,8 +368,9 @@ pub const Client = struct {
for (rows) |row| self.allocator.free(row);
self.allocator.free(rows);
}
const truncated = rowsContain(rows, "diagnostic:search_truncated");
try self.session.openListPanel("search", rows);
self.message = null;
self.message = if (truncated) "diagnostic:search_truncated" else null;
}
fn openSelectedSearchResult(self: *Client) !void {
@@ -669,6 +683,10 @@ pub const Client = struct {
fn save(self: *Client) !void {
const snap = try self.session.snapshot();
if (snap.bytes.len > diagnostics_mod.max_file_bytes) {
self.message = "diagnostic:save_failed:file_too_large";
return Error.ProtocolRejected;
}
const copy = try self.allocator.dupe(u8, snap.bytes);
if (self.saved_bytes) |old| self.allocator.free(old);
self.saved_bytes = copy;
@@ -807,6 +825,13 @@ fn assertLinesFit(frame: []const u8, width: usize) !void {
}
}
fn rowsContain(rows: []const []const u8, needle: []const u8) bool {
for (rows) |row| {
if (std.mem.indexOf(u8, row, needle) != null) return true;
}
return false;
}
fn freeOwnedRows(allocator: std.mem.Allocator, rows: []const []const u8) void {
for (rows) |row| allocator.free(row);
allocator.free(rows);