| author | |
| committer | |
| log | e054442e2371b0176c14ff740d78607d078ca9fb |
| tree | 5469c4564c8d4b0a020b3cc444affb64fdd66022 |
| parent | 203e8279539220db84823bb79671c5c6c7d1065f |
| signature |
Currently the grammar doesn't forbid chained compare ops, see the new
test case which now passes.3 files changed, 16 insertions(+), 13 deletions(-)
doc/langref/grammar.peg+1-1| ... | @@ -126,7 +126,7 @@ BoolOrExpr <- BoolAndExpr (OrOp BoolAndExpr)* !OrOp | ... | @@ -126,7 +126,7 @@ BoolOrExpr <- BoolAndExpr (OrOp BoolAndExpr)* !OrOp |
| 126 | 126 | ||
| 127 | BoolAndExpr <- CompareExpr (AndOp CompareExpr)* !AndOp | 127 | BoolAndExpr <- CompareExpr (AndOp CompareExpr)* !AndOp |
| 128 | 128 | ||
| 129 | CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr / !CompareOp) | 129 | CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)? !CompareOp |
| 130 | 130 | ||
| 131 | BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)* !BitwiseOp | 131 | BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)* !BitwiseOp |
| 132 | 132 |
lib/std/zig/parser_fuzz.zig+5| ... | @@ -140,6 +140,11 @@ test "bin op at end of file" { | ... | @@ -140,6 +140,11 @@ test "bin op at end of file" { |
| 140 | ); | 140 | ); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | // Found using AFL++ | ||
| 144 | test "resume block chained compare ops" { | ||
| 145 | try checkAgainstOracle("test{resume{0 > 0;} > 0 > 0;}"); | ||
| 146 | } | ||
| 147 | |||
| 143 | fn checkAgainstOracle(source: [:0]const u8) !void { | 148 | fn checkAgainstOracle(source: [:0]const u8) !void { |
| 144 | var fba_buf: [1 << 18]u8 = undefined; | 149 | var fba_buf: [1 << 18]u8 = undefined; |
| 145 | var fba: std.heap.FixedBufferAllocator = .init(&fba_buf); | 150 | var fba: std.heap.FixedBufferAllocator = .init(&fba_buf); |
lib/std/zig/parser_generated_oracle.zig+10-12| ... | @@ -639,18 +639,16 @@ const Parser = struct { | ... | @@ -639,18 +639,16 @@ const Parser = struct { |
| 639 | pub fn parseCompareExpr(p: *Parser) Error!bool { | 639 | pub fn parseCompareExpr(p: *Parser) Error!bool { |
| 640 | return blk_0: { | 640 | return blk_0: { |
| 641 | const pos_0 = p.i; | 641 | const pos_0 = p.i; |
| 642 | if (try p.parseBitwiseExpr() and blk_2: { | 642 | if (try p.parseBitwiseExpr() and (blk_3: { |
| 643 | const pos_2 = p.i; | 643 | const pos_3 = p.i; |
| 644 | if (try p.parseCompareOp() and try p.parseBitwiseExpr()) break :blk_2 true; | 644 | if (try p.parseCompareOp() and try p.parseBitwiseExpr()) break :blk_3 true; |
| 645 | p.i = pos_2; | 645 | p.i = pos_3; |
| 646 | if (blk_3: { | 646 | break :blk_3 false; |
| 647 | const pos_3 = p.i; | 647 | } or true) and blk_1: { |
| 648 | const match_3 = try p.parseCompareOp(); | 648 | const pos_1 = p.i; |
| 649 | p.i = pos_3; | 649 | const match_1 = try p.parseCompareOp(); |
| 650 | break :blk_3 !match_3; | 650 | p.i = pos_1; |
| 651 | }) break :blk_2 true; | 651 | break :blk_1 !match_1; |
| 652 | p.i = pos_2; | ||
| 653 | break :blk_2 false; | ||
| 654 | }) break :blk_0 true; | 652 | }) break :blk_0 true; |
| 655 | p.i = pos_0; | 653 | p.i = pos_0; |
| 656 | break :blk_0 false; | 654 | break :blk_0 false; |