Skip to content

Conversation

@0x4a61636f62
Copy link
Contributor

@0x4a61636f62 0x4a61636f62 commented Nov 12, 2025

This fixes a bug in HostName.expand that I found while working on my project.

When using std.http.Client to connect to a domain that uses a CNAME, my diagnostics caught an InvalidDnsCnameRecord error. I found that the issue was due to an off-by-one in the slice passed to HostName.validate. I fixed the bug and added a test with comments, mostly for my own learning. I know the porting to std.Io is underway, so take it for what it's worth.

Here is an example to reproduce with https://blog.github.com:

const std = @import("std");

pub fn main() anyerror!void {
    const allocator = std.heap.page_allocator;

    var threaded = std.Io.Threaded.init(allocator);
    defer std.Io.Threaded.deinit(&threaded);
    const io = std.Io.Threaded.io(&threaded);

    var client = std.http.Client{
        .allocator = allocator,
        .io = io,
    };
    defer client.deinit();

    const uri = try std.Uri.parse("https://blog.github.com");
    std.log.info("Connecting to: https://blog.github.com", .{});

    var req = client.request(.GET, uri, .{}) catch |err| {
        std.log.err("http.Client.request failed: {s}", .{@errorName(err)});
        return err;
    };
    defer req.deinit();

    std.log.info("Sending request", .{});
    try req.sendBodiless();

    var redirect_buffer: [1024]u8 = undefined;
    _ = try req.receiveHead(&redirect_buffer);
}

Output from zig build run:

info: Connecting to: https://blog.github.com
error: http.Client.request failed: InvalidDnsCnameRecord
error: InvalidDnsCnameRecord
/usr/lib/zig/std/Io/net/HostName.zig:246:13: 0x11bbf71 in connect (std.zig)
try end;
^
/usr/lib/zig/std/http/Client.zig:1447:18: 0x11a1214 in connectTcpOptions (std.zig)
var stream = try host.connect(io, port, .{ .mode = .stream });
^
/usr/lib/zig/std/http/Client.zig:1419:5: 0x119f8a7 in connectTcp (std.zig)
return connectTcpOptions(client, .{ .host = host, .port = port, .protocol = protocol });
^
/usr/lib/zig/std/http/Client.zig:1592:14: 0x1190b70 in connect (std.zig)
    } orelse return client.connectTcp(host, port, protocol);
^
/usr/lib/zig/std/http/Client.zig:1708:18: 0x117defc in request (std.zig)
break :c try client.connect(host_name, uriPort(uri, protocol), protocol);
^
/home/fox/Coding/apca/src/main.zig:21:9: 0x117b612 in main (main.zig)
return err;
^
run
└─ run exe standalone-test failure
error: process exited with error code 1
failed command: ./.zig-cache/o/74cbf6cff85e01ebc54a0b6c3c22ec9e/standalone-test

Build Summary: 2/4 steps succeeded (1 failed)
run transitive failure
└─ run exe standalone-test failure

error: the following build command failed with exit code 1:
.zig-cache/o/0ae7bf86e2ec25e2a707c43ae1c07691/build /usr/bin/zig /usr/lib/zig /home/fox/Coding/apca .zig-cache /home/fox/.cache/zig --seed 0x378e2bb -Zc330daa63d37b9c3 run

Output from dig blog.github.com:

; <<>> DiG 9.20.15 <<>> blog.github.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40590
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;blog.github.com.               IN      A

;; ANSWER SECTION:
blog.github.com.        2698    IN      CNAME   github.github.io.
github.github.io.       3342    IN      A       185.199.109.153
github.github.io.       3342    IN      A       185.199.111.153
github.github.io.       3342    IN      A       185.199.108.153
github.github.io.       3342    IN      A       185.199.110.153

;; ADDITIONAL SECTION:
github.github.io.       2698    IN      AAAA    2606:50c0:8001::153
github.github.io.       2698    IN      AAAA    2606:50c0:8000::153
github.github.io.       2698    IN      AAAA    2606:50c0:8003::153
github.github.io.       2698    IN      AAAA    2606:50c0:8002::153

;; Query time: 1 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Thu Nov 13 00:48:32 CET 2025
;; MSG SIZE  rcvd: 250

Closes #25811
Duplicate of #25845

@0x4a61636f62 0x4a61636f62 force-pushed the fix-dns-expand-off-by-one branch 3 times, most recently from 12982ab to 912bdd6 Compare November 13, 2025 00:19
@0x4a61636f62 0x4a61636f62 force-pushed the fix-dns-expand-off-by-one branch from 912bdd6 to c543abe Compare November 13, 2025 02:41
`HostName.expand` was including the null terminator in the slice passed to `HostName.init`, which caused `HostName.validate` to fail.
@0x4a61636f62 0x4a61636f62 force-pushed the fix-dns-expand-off-by-one branch from c543abe to 93f7f73 Compare November 13, 2025 07:05
@notcancername
Copy link
Contributor

Duplicate of: #25845 . Note that this PR removes the sentinel, while the linked PR preserves it but doesn't include it in the slice.

@0x4a61636f62
Copy link
Contributor Author

I apologize for the duplicate PR @notcancername. I completely missed #25845 (and the original issue #25811). I'll make sure to search for duplicates next time. However, it's reassuring to see that people are identifying the issues quickly. I have edited the description to link to the original issue and your PR as a duplicate, and updated the PR with the better solution suggested by @squeek502. It is up to you to decide which PR to merge.

@squeek502 squeek502 merged commit 2e6f7d3 into ziglang:master Nov 14, 2025
17 of 18 checks passed
@squeek502
Copy link
Member

Thanks!

@0x4a61636f62 0x4a61636f62 deleted the fix-dns-expand-off-by-one branch November 14, 2025 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DNS resolution fails for URIs with a www subdomain

3 participants