atproto utils for zig zat.dev
atproto sdk zig

feat: add size limits to CAR parser

reject CAR data > 2MB and block count > 10,000, matching indigo's
safety limits. removes the last correctness asymmetry in the benchmarks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+10
+10
src/internal/repo/car.zig
··· 32 UnexpectedEof, 33 OutOfMemory, 34 BadBlockHash, 35 }; 36 37 pub const ReadOptions = struct { 38 /// verify that each block's content hashes to its CID. ··· 48 49 /// parse a CAR v1 file from raw bytes with options 50 pub fn readWithOptions(allocator: Allocator, data: []const u8, options: ReadOptions) CarError!Car { 51 var pos: usize = 0; 52 53 // read header length (unsigned varint) ··· 96 if (options.verify_block_hashes) { 97 try verifyBlockHash(cid_bytes, content); 98 } 99 100 try blocks.append(allocator, .{ 101 .cid_raw = cid_bytes,
··· 32 UnexpectedEof, 33 OutOfMemory, 34 BadBlockHash, 35 + BlocksTooLarge, 36 + TooManyBlocks, 37 }; 38 + 39 + /// match indigo's safety limits 40 + const max_blocks_size: usize = 2 * 1024 * 1024; // 2 MB 41 + const max_block_count: usize = 10_000; 42 43 pub const ReadOptions = struct { 44 /// verify that each block's content hashes to its CID. ··· 54 55 /// parse a CAR v1 file from raw bytes with options 56 pub fn readWithOptions(allocator: Allocator, data: []const u8, options: ReadOptions) CarError!Car { 57 + if (data.len > max_blocks_size) return error.BlocksTooLarge; 58 + 59 var pos: usize = 0; 60 61 // read header length (unsigned varint) ··· 104 if (options.verify_block_hashes) { 105 try verifyBlockHash(cid_bytes, content); 106 } 107 + 108 + if (blocks.items.len >= max_block_count) return error.TooManyBlocks; 109 110 try blocks.append(allocator, .{ 111 .cid_raw = cid_bytes,