authorgravatar for jastraberg@gmail.com0x4a61636f62 <jastraberg@gmail.com> 2025-11-12 23:49:42+01:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2025-11-13 21:04:21-08:00
log2e6f7d36b9292b2a88a28c3caab767cd9401175d
tree42d6ba92494bef5385b90997289cb1d941d2212e
parent813e8614bc2ecda414f308a1662be074e788e3f2

std.Io.net: fix off-by-one in HostName.expand

`HostName.expand` was including the null terminator in the slice passed to `HostName.init`, which caused `HostName.validate` to fail.

2 files changed, 50 insertions(+), 2 deletions(-)

lib/std/Io/net/HostName.zig-2
......@@ -136,8 +136,6 @@ pub fn expand(noalias packet: []const u8, start_i: usize, noalias dest_buffer: [
136136 dest_i += label_len;
137137 i += 1 + label_len;
138138 } else {
139 dest[dest_i] = 0;
140 dest_i += 1;
141139 return .{
142140 len orelse i - start_i + 1,
143141 try .init(dest[0..dest_i]),
lib/std/Io/net/test.zig+50
......@@ -343,3 +343,53 @@ test "non-blocking tcp server" {
343343 const msg = buf[0..len];
344344 try testing.expect(mem.eql(u8, msg, "hello from server\n"));
345345}
346
347test "decompress compressed DNS name" {
348 const packet = &[_]u8{
349 // Header section
350 // ----------------------------------------------------------
351 0x00, 0x00, // ID: 0
352 0x81, 0x80, // Flags (QR:1, RCODE:0, etc.)
353 0x00, 0x01, // QDCOUNT: 1 (Question Count)
354 0x00, 0x01, // ANCOUNT: 1 (Answer Count)
355 0x00, 0x00, // NSCOUNT: 0
356 0x00, 0x00, // ARCOUNT: 0
357 // ----------------------------------------------------------
358
359 // Question section (12 byte offset)
360 // ----------------------------------------------------------
361 // QNAME: "www.ziglang.org"
362 0x03, 'w', 'w', 'w', // label
363 0x07, 'z', 'i', 'g', 'l', 'a', 'n', 'g', // label
364 0x03, 'o', 'r', 'g', // label
365 0x00, // null label
366 0x00, 0x01, // QTYPE: A
367 0x00, 0x01, // QCLASS: IN
368 // ----------------------------------------------------------
369
370 // Resource Record (Answer) (33 byte offset)
371 // ----------------------------------------------------------
372 0xc0, 0x0c, // NAME: pointer to 0x0c ("www.ziglang.org")
373 0x00, 0x05, // TYPE: CNAME
374 0x00, 0x01, // CLASS: IN
375 0x00, 0x00, 0x01, 0x00, // TTL: 256 (seconds)
376 0x00, 0x06, // RDLENGTH: 6 bytes
377
378 // RDATA (45 byte offset): "target.ziglang.org" (compressed)
379 0x06, 't', 'a', 'r', 'g', 'e', 't', // 6, "target"
380 0xc0, 0x10, // pointer (0xc0 flag) to 0x10 byte offset ("ziglang.org")
381 // ----------------------------------------------------------
382 };
383
384 // The start index of the CNAME RDATA is 45
385 const cname_data_index = 45;
386 var dest_buffer: [net.HostName.max_len]u8 = undefined;
387
388 const n_consumed, const result = try net.HostName.expand(
389 packet,
390 cname_data_index,
391 &dest_buffer,
392 );
393 try testing.expectEqual(packet.len - cname_data_index, n_consumed);
394 try testing.expectEqualStrings("target.ziglang.org", result.bytes);
395}