diff --git a/lib/std/net.zig b/lib/std/net.zig index 8fa6e4432d..f4464b46c6 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -32,6 +32,7 @@ pub const IpAddress = extern union { error.InvalidEnd, error.InvalidCharacter, error.Incomplete, + error.InvalidIpv4Mapping, => {}, } @@ -103,6 +104,24 @@ pub const IpAddress = extern union { } scope_id = true; saw_any_digits = false; + } else if (c == '.') { + if (!abbrv or ip_slice[0] != 0xff or ip_slice[1] != 0xff) { + // must start with '::ffff:' + return error.InvalidIpv4Mapping; + } + const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1; + const addr = (parseIp4(buf[start_index..], 0) catch { + return error.InvalidIpv4Mapping; + }).in.addr; + ip_slice = result.in6.addr[0..]; + ip_slice[10] = 0xff; + ip_slice[11] = 0xff; + + ip_slice[12] = @truncate(u8, addr >> 24 & 0xff); + ip_slice[13] = @truncate(u8, addr >> 16 & 0xff); + ip_slice[14] = @truncate(u8, addr >> 8 & 0xff); + ip_slice[15] = @truncate(u8, addr & 0xff); + return result; } else { const digit = try std.fmt.charToDigit(c, 16); if (@mulWithOverflow(u16, x, 16, &x)) { @@ -783,6 +802,7 @@ fn linuxLookupNameFromHosts( error.InvalidCharacter, error.Incomplete, error.InvalidIPAddressFormat, + error.InvalidIpv4Mapping, => continue, }; try addrs.append(LookupAddr{ .addr = addr }); diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig index ae3c62d7f0..178ca9d148 100644 --- a/lib/std/net/test.zig +++ b/lib/std/net/test.zig @@ -14,6 +14,7 @@ test "parse and render IPv6 addresses" { "::1234:5678", "2001:db8::1234:5678", "FF01::FB%1234", + "::ffff:123.123.123.123", }; const printed = [_][]const u8{ "ff01::fb", @@ -23,7 +24,8 @@ test "parse and render IPv6 addresses" { "2001:db8::", "::1234:5678", "2001:db8::1234:5678", - "ff01::fb" + "ff01::fb", + "::ffff:7b7b:7b7b", }; for (ips) |ip, i| { var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable; @@ -36,6 +38,7 @@ test "parse and render IPv6 addresses" { testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0)); testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0)); testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0)); + testing.expectError(error.InvalidIpv4Mapping, net.IpAddress.parseIp6("::123.123.123.123", 0)); } test "parse and render IPv4 addresses" {