summaryrefslogtreecommitdiff
path: root/src/ninep/pane.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/pane.zig')
-rw-r--r--src/ninep/pane.zig13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index d29c8b49..1148041a 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -458,8 +458,21 @@ fn writeBody(p: *Pardes, req: Req, id: usize, pane: *Pane) Reply {
return .{ .tag = req.tag, .written = @intCast(take) };
}
+/// Why `data` is no text a tag takes: a control character but a tab or a
+/// newline, DEL, a C1 control, or bytes that are not UTF-8 (a NUL in a tag
+/// made a Dump that wrote nothing).
+pub fn tagFault(data: []const u8) ?[]const u8 {
+ for (data) |c| if ((c < ' ' and c != '\t' and c != '\n') or c == 0x7f) return "invalid tag text: a control character";
+ if (!std.unicode.utf8ValidateSlice(data)) return "invalid tag text: not UTF-8";
+ var i: usize = 0;
+ while (std.mem.indexOfScalarPos(u8, data, i, 0xC2)) |at| : (i = at + 1)
+ if (at + 1 < data.len and data[at + 1] <= 0x9F) return "invalid tag text: a control character";
+ return null;
+}
+
fn writeTag(req: Req, pane: *Pane) Reply {
if (req.data.len == 0) return .{ .tag = req.tag, .written = 0 };
+ if (tagFault(req.data)) |why| return tree.failText(req.tag, E.INVAL, why);
// The tag's own text grows by what is written, newlines and all: a tag
// is a text like any other (acme's tag file appends the same way).
const pf = &pane.fs;