diff options
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/pane.zig | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index 30530c3b..de7f7cd4 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -845,6 +845,9 @@ fn nameFault(name: []const u8) ?[]const u8 { } if (name[0] == ' ') return e_name_char ++ ": a blank at its start"; if (name[name.len - 1] == ' ') return e_name_char ++ ": a blank at its end"; + // No file system takes a longer one (NAME_MAX): a Save would only fail. + var parts = std.mem.splitScalar(u8, name, '/'); + while (parts.next()) |part| if (part.len > 255) return "invalid file name: a component over 255 bytes"; return null; } @@ -1364,6 +1367,26 @@ test "a write of two lines to name is refused EINVAL, on a held open or not" { try testing.expectEqualStrings("/tmp/pardes-a", nameOf(p, p.panes[p.paneBySerial(serial).?].?)); } +test "a name with a component over 255 bytes is refused, and a long path's failed Save keeps its reason" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const serial = serialOf(p); + const refused = wr(p, Node.of(serial, .name), "/tmp/" ++ "c" ** 256 ++ "/f.txt\n"); + try testing.expectEqual(E.INVAL, refused.errno()); + try testing.expectEqualStrings("invalid file name: a component over 255 bytes", refused.reply.ename); + try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .name), "/tmp/" ++ "c" ** 255 ++ "\n").reply.status); + // A Save of a 3000-byte path the host refuses: the waiting write's + // reason is at the end, the path giving up its middle. + const long = "/nonexistent-pardes-root/" ++ ("d" ** 200 ++ "/") ** 15 ++ "f.txt"; + const id = p.paneBySerial(serial).?; + try nameBuffer(p, id, long, false); + p.fs.late_failure_len = 0; + p.saveFailed(@intCast(id), long, error.AccessDenied); + const late = p.fs.late_failure[0..p.fs.late_failure_len]; + try testing.expect(std.mem.startsWith(u8, late, "Save /nonexistent-pardes-root/")); + try testing.expect(std.mem.endsWith(u8, late, "/f.txt: no such directory")); +} + test "a name cut across writes is one name, applied once at its newline or its close" { const p = try withFile(testing.allocator, "x\n"); defer p.deinit(); |
