summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ninep/addr.zig10
-rw-r--r--src/ninep/ctl.zig5
-rw-r--r--src/regexp.zig2
-rw-r--r--src/sam_edit.zig2
4 files changed, 16 insertions, 3 deletions
diff --git a/src/ninep/addr.zig b/src/ninep/addr.zig
index 09ef2b66..f60c07b1 100644
--- a/src/ninep/addr.zig
+++ b/src/ninep/addr.zig
@@ -377,6 +377,16 @@ test "an address is evaluated from the current one, as acme's are" {
try testing.expectEqualStrings(e_order, th.wr(q, qaddr, "/a/,/b/").reply.ename);
}
+test "a pattern with a newline and an anchor mvzr would misread is refused EINVAL, by addr and by Edit" {
+ const p = try th.withFile(testing.allocator, "a\nfoo\n");
+ defer p.deinit();
+ const r = th.wr(p, Node.of(th.serialOf(p), .addr), "/(^|\\n)foo/");
+ try testing.expectEqual(E.INVAL, r.errno());
+ try testing.expectEqualStrings(regexp_.Regex.e_anchor, r.reply.ename);
+ const e = th.wr(p, Node.of(th.serialOf(p), .ctl), "Edit ,x/(^|\\n)foo/d\n");
+ try testing.expectEqual(E.INVAL, e.errno());
+}
+
test "a row's range, L:C-L2:C2 or L:C-C2, is an address through its last character" {
const p = try th.withFile(testing.allocator, "one\ntwo three\nfour\n");
defer p.deinit();
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 978ce707..b79b1ab8 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -250,7 +250,10 @@ pub fn captured(p: *Pardes, req: Req, id: usize, exec: bool, text: []const u8, i
/// there (`no such`, `not found`, the words 9ns reads as ENOENT too), else
/// EIO.
fn failureErrno(failure: []const u8) u16 {
- return if (std.mem.indexOf(u8, failure, "no such") != null or std.mem.indexOf(u8, failure, "not found") != null) E.NOENT else E.IO;
+ if (std.mem.indexOf(u8, failure, "no such") != null or std.mem.indexOf(u8, failure, "not found") != null) return E.NOENT;
+ // A pattern refused (Edit's too) is malformed input, as 9ns reads it.
+ if (std.mem.indexOf(u8, failure, "bad regular expression") != null) return E.INVAL;
+ return E.IO;
}
pub fn resultsLen(p: *Pardes) u64 {
diff --git a/src/regexp.zig b/src/regexp.zig
index 64e1d75a..27b3c0ba 100644
--- a/src/regexp.zig
+++ b/src/regexp.zig
@@ -41,7 +41,7 @@ pub const Regex = struct {
/// patterns take 45-80 ms, and a Debug build is ten times slower.
pub const budget: u64 = if (builtin.mode == .Debug) 4_000_000 else 32_000_000;
- pub const e_anchor = "in a pattern with \\n, ^ can only come first and $ only just before a \\n";
+ pub const e_anchor = "bad regular expression: in a pattern with \\n, ^ can only come first and $ only just before a \\n";
/// `Anchor`: a pattern that names a newline has `^` other than first,
/// or `$` other than just before a `\n`, which mvzr would read as the
diff --git a/src/sam_edit.zig b/src/sam_edit.zig
index cd2998ef..a88728aa 100644
--- a/src/sam_edit.zig
+++ b/src/sam_edit.zig
@@ -735,7 +735,7 @@ test "an Edit that fails halfway changes nothing, and says why in acme's words"
.{ "w /tmp/x", "w is not supported in pardes" },
.{ ",s/(a)/\\1/", "no \\1: mvzr keeps no submatches" },
.{ "1 m 1,2", "move overlaps itself" },
- .{ ",x/(^|\\n)foo/d", "in a pattern with \\n, ^ can only come first and $ only just before a \\n" },
+ .{ ",x/(^|\\n)foo/d", "bad regular expression: in a pattern with \\n, ^ can only come first and $ only just before a \\n" },
}) |c| {
var why: Why = .{};
try std.testing.expectError(error.Edit, run(arena_state.allocator(), "foo a\nfoo\n", .{}, "t", c[0], &why));