| author | |
| committer | |
| log | b905c65661bd0d47e6ac7d537649eef8e29e44fc |
| tree | fce02c822f5d74c6d57303a751fd7951eea1c6c5 |
| parent | e66b269333b5c400d76078318ac92354753bcf7b |
3 files changed, 48 insertions(+), 14 deletions(-)
lib/std/json/scanner_test.zig+17| ... | ... | @@ -517,3 +517,20 @@ test isNumberFormattedLikeAnInteger { |
| 517 | 517 | try std.testing.expect(!isNumberFormattedLikeAnInteger("1e10")); |
| 518 | 518 | try std.testing.expect(!isNumberFormattedLikeAnInteger("1E10")); |
| 519 | 519 | } |
| 520 | ||
| 521 | test "fuzz" { | |
| 522 | try std.testing.fuzz({}, fuzzTestOne, .{}); | |
| 523 | } | |
| 524 | ||
| 525 | fn fuzzTestOne(_: void, input: []const u8) !void { | |
| 526 | var buf: [16384]u8 = undefined; | |
| 527 | var fba: std.heap.FixedBufferAllocator = .init(&buf); | |
| 528 | ||
| 529 | var scanner = Scanner.initCompleteInput(fba.allocator(), input); | |
| 530 | // Property: There are at most input.len tokens | |
| 531 | var tokens: usize = 0; | |
| 532 | while ((scanner.next() catch return) != .end_of_document) { | |
| 533 | tokens += 1; | |
| 534 | if (tokens > input.len) return error.Overflow; | |
| 535 | } | |
| 536 | } |
lib/std/zig/parser_test.zig+16| ... | ... | @@ -6451,3 +6451,19 @@ fn testError(source: [:0]const u8, expected_errors: []const Error) !void { |
| 6451 | 6451 | try std.testing.expectEqual(expected, tree.errors[i].tag); |
| 6452 | 6452 | } |
| 6453 | 6453 | } |
| 6454 | ||
| 6455 | test "fuzz ast parse" { | |
| 6456 | try std.testing.fuzz({}, fuzzTestOneParse, .{}); | |
| 6457 | } | |
| 6458 | ||
| 6459 | fn fuzzTestOneParse(_: void, input: []const u8) !void { | |
| 6460 | // The first byte holds if zig / zon | |
| 6461 | if (input.len == 0) return; | |
| 6462 | const mode: std.zig.Ast.Mode = if (input[0] & 1 == 0) .zig else .zon; | |
| 6463 | const bytes = input[1..]; | |
| 6464 | ||
| 6465 | var fba: std.heap.FixedBufferAllocator = .init(&fixed_buffer_mem); | |
| 6466 | const allocator = fba.allocator(); | |
| 6467 | const source = allocator.dupeZ(u8, bytes) catch return; | |
| 6468 | _ = std.zig.Ast.parse(allocator, source, mode) catch return; | |
| 6469 | } |
lib/std/zig/tokenizer.zig+15-14| ... | ... | @@ -1721,10 +1721,14 @@ fn testTokenize(source: [:0]const u8, expected_token_tags: []const Token.Tag) !v |
| 1721 | 1721 | try std.testing.expectEqual(source.len, last_token.loc.end); |
| 1722 | 1722 | } |
| 1723 | 1723 | |
| 1724 | fn testPropertiesUpheld(context: void, source: []const u8) anyerror!void { | |
| 1725 | _ = context; | |
| 1726 | const source0 = try std.testing.allocator.dupeZ(u8, source); | |
| 1727 | defer std.testing.allocator.free(source0); | |
| 1724 | fn testPropertiesUpheld(_: void, source: []const u8) !void { | |
| 1725 | var source0_buf: [512]u8 = undefined; | |
| 1726 | if (source.len + 1 > source0_buf.len) | |
| 1727 | return; | |
| 1728 | @memcpy(source0_buf[0..source.len], source); | |
| 1729 | source0_buf[source.len] = 0; | |
| 1730 | const source0 = source0_buf[0..source.len :0]; | |
| 1731 | ||
| 1728 | 1732 | var tokenizer = Tokenizer.init(source0); |
| 1729 | 1733 | var tokenization_failed = false; |
| 1730 | 1734 | while (true) { |
| ... | ... | @@ -1750,18 +1754,15 @@ fn testPropertiesUpheld(context: void, source: []const u8) anyerror!void { |
| 1750 | 1754 | } |
| 1751 | 1755 | } |
| 1752 | 1756 | |
| 1753 | if (source0.len > 0) for (source0, source0[1..][0..source0.len]) |cur, next| { | |
| 1757 | if (tokenization_failed) return; | |
| 1758 | for (source0) |cur| { | |
| 1754 | 1759 | // Property: No null byte allowed except at end. |
| 1755 | 1760 | if (cur == 0) { |
| 1756 | try std.testing.expect(tokenization_failed); | |
| 1757 | } | |
| 1758 | // Property: No ASCII control characters other than \n and \t are allowed. | |
| 1759 | if (std.ascii.isControl(cur) and cur != '\n' and cur != '\t') { | |
| 1760 | try std.testing.expect(tokenization_failed); | |
| 1761 | return error.TestUnexpectedResult; | |
| 1761 | 1762 | } |
| 1762 | // Property: All '\r' must be followed by '\n'. | |
| 1763 | if (cur == '\r' and next != '\n') { | |
| 1764 | try std.testing.expect(tokenization_failed); | |
| 1763 | // Property: No ASCII control characters other than \n, \t, and \r are allowed. | |
| 1764 | if (std.ascii.isControl(cur) and cur != '\n' and cur != '\t' and cur != '\r') { | |
| 1765 | return error.TestUnexpectedResult; | |
| 1765 | 1766 | } |
| 1766 | }; | |
| 1767 | } | |
| 1767 | 1768 | } |