summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/regexp.zig11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/regexp.zig b/src/regexp.zig
index fe68585d..f6d540c4 100644
--- a/src/regexp.zig
+++ b/src/regexp.zig
@@ -62,6 +62,10 @@ pub const Regex = struct {
i += 1;
piece = pat[i - 1 .. i + 1];
if (pat[i] == 'n') spans = true;
+ // mvzr slices two hex digits after `\x` without looking,
+ // so a short one panics it: refuse it here.
+ if (pat[i] == 'x' and (i + 2 >= pat.len or
+ !std.ascii.isHex(pat[i + 1]) or !std.ascii.isHex(pat[i + 2]))) return error.Bad;
} else if (in_class) {
in_class = c != ']';
} else if (c == '[') {
@@ -185,3 +189,10 @@ test "the match is the leftmost, however long the line" {
try std.testing.expectEqual(@as(usize, 2), f.start);
try std.testing.expectEqual(@as(usize, 7), f.end);
}
+
+test "a \\x without two hex digits is refused, not handed to mvzr to panic on" {
+ for ([_][]const u8{ "\\x", "a\\x1", "\\x1b[\\x", "[\\x]", "\\xg1" }) |pat|
+ try std.testing.expectError(error.Bad, Regex.compile(pat));
+ var rx = try Regex.compile("\\x41");
+ try std.testing.expectEqual(@as(usize, 1), (try rx.find("xA", 0, 1, 2)).?.start);
+}