From c8214f3c8038a87a36bb5c92b2271ac1e551816c Mon Sep 17 00:00:00 2001 From: Altagos Date: Sat, 7 Jun 2025 22:40:20 +0200 Subject: [PATCH] error handling --- src/root.zig | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/root.zig b/src/root.zig index 15b4c2b..a1639ec 100644 --- a/src/root.zig +++ b/src/root.zig @@ -6,7 +6,10 @@ pub const BytePacketBuffer = struct { buf: [512]u8 = undefined, pos: usize = 0, - pub const ReadError = error{EndOfBuffer}; + pub const ReadError = error{ + EndOfBuffer, + JumpLimitExceeded, + }; pub const Reader = io.Reader(*BytePacketBuffer, ReadError, read); @@ -26,12 +29,12 @@ pub const BytePacketBuffer = struct { /// Read a single byte and move the position one step forward pub fn read(self: *BytePacketBuffer, dest: []u8) ReadError!usize { - const size = @min(dest.len, self.buf.len - self.pos); + if (self.pos + dest.len > self.buf.len) + return ReadError.EndOfBuffer; + const size = dest.len; const end = self.pos + size; - @memcpy(dest[0..size], self.buf[self.pos..end]); self.pos = end; - return size; } @@ -52,7 +55,7 @@ pub const BytePacketBuffer = struct { /// The tricky part: Reading domain names, taking labels into consideration. /// Will take something like [3]www[6]google[3]com and append /// www.google.com to outstr. - pub fn read_qname(self: *BytePacketBuffer, outstr: []u8) !void { + pub fn read_qname(self: *BytePacketBuffer, outstr: []u8) ReadError!void { // We might encounter jumps, therefore we need to keep thrack of our position locally var pos = self.pos; var out_pos: usize = 0; @@ -64,7 +67,7 @@ pub const BytePacketBuffer = struct { var delim: ?[]const u8 = null; while (true) { - if (jumps_performed > max_jumps) return error.JumpLimitExceeded; + if (jumps_performed > max_jumps) return ReadError.JumpLimitExceeded; // Each label starts with a length byte const len = try self.get(pos); @@ -139,18 +142,43 @@ test "BytePacketBuffer.read_u32" { try testing.expectEqual(0x1010101, try buf.reader().readInt(u32, .big)); } -test "BytePacketBuffer.read_qname" { +test "BytePacketBuffer.read last byte" { + const testing = std.testing; + var buf = BytePacketBuffer{}; + buf.buf[buf.buf.len - 1] = 0x1; + buf.pos = buf.buf.len - 1; + try testing.expectEqual(0x1, try buf.reader().readInt(u8, .big)); + try testing.expectError( + BytePacketBuffer.ReadError.EndOfBuffer, + buf.reader().readInt(u8, .big), + ); +} + +test "BytePacketBuffer.read_qname google.com" { const testing = std.testing; const allocator = testing.allocator; - const input = [_]u8{ 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00 }; - var buf = BytePacketBuffer{}; + const input = [_]u8{ + 0x06, // [6] + 0x67, // g + 0x6f, // o + 0x6f, // o + 0x67, // g + 0x6c, // l + 0x65, // e + 0x03, // [3] + 0x63, // c + 0x6f, // o + 0x6d, // m + 0x00, // [0] + }; + const expected = "google.com"; + var buf = BytePacketBuffer{}; for (input, 0..) |char, idx| { buf.buf[idx] = char; } - const expected = "google.com"; const outstr = try allocator.alloc(u8, expected.len); defer allocator.free(outstr); -- 2.51.2