| ... | ... | @@ -70,7 +70,7 @@ pub const IpAddress = union(enum) { |
| 70 | 70 | pub fn parseLiteral(text: []const u8) ParseLiteralError!IpAddress { |
| 71 | 71 | if (text.len == 0) return error.InvalidAddress; |
| 72 | 72 | if (text[0] == '[') { |
| 73 | | const addr_end = std.mem.indexOfScalar(u8, text, ']') orelse |
| 73 | const addr_end = std.mem.findScalar(u8, text, ']') orelse |
| 74 | 74 | return error.InvalidAddress; |
| 75 | 75 | const addr_text = text[1..addr_end]; |
| 76 | 76 | const port: u16 = p: { |
| ... | ... | @@ -80,7 +80,7 @@ pub const IpAddress = union(enum) { |
| 80 | 80 | }; |
| 81 | 81 | return parseIp6(addr_text, port) catch error.InvalidAddress; |
| 82 | 82 | } |
| 83 | | if (std.mem.indexOfScalar(u8, text, ':')) |i| { |
| 83 | if (std.mem.findScalar(u8, text, ':')) |i| { |
| 84 | 84 | const addr = Ip4Address.parse(text[0..i], 0) catch return error.InvalidAddress; |
| 85 | 85 | return .{ .ip4 = .{ |
| 86 | 86 | .bytes = addr.bytes, |
| ... | ... | @@ -431,17 +431,22 @@ pub const Ip6Address = struct { |
| 431 | 431 | pub const Parsed = union(enum) { |
| 432 | 432 | success: Unresolved, |
| 433 | 433 | invalid_byte: usize, |
| 434 | | unexpected_end, |
| 434 | incomplete, |
| 435 | 435 | junk_after_end: usize, |
| 436 | 436 | interface_name_oversized: usize, |
| 437 | invalid_ip4_mapping: usize, |
| 438 | overflow: usize, |
| 437 | 439 | }; |
| 438 | 440 | |
| 439 | 441 | pub fn parse(text: []const u8) Parsed { |
| 440 | | if (text.len < 2) return .unexpected_end; |
| 441 | | if (std.ascii.startsWithIgnoreCase(text, "::ffff:")) ip4_mapped: { |
| 442 | | const a4 = (Ip4Address.parse(text["::ffff:".len..], 0) catch break :ip4_mapped).bytes; |
| 442 | if (text.len < 2) return .incomplete; |
| 443 | const ip4_prefix = "::ffff:"; |
| 444 | if (std.ascii.startsWithIgnoreCase(text, ip4_prefix)) { |
| 445 | const parsed = Ip4Address.parse(text[ip4_prefix.len..], 0) catch |
| 446 | return .{ .invalid_ip4_mapping = ip4_prefix.len }; |
| 447 | const b = parsed.bytes; |
| 443 | 448 | return .{ .success = .{ |
| 444 | | .bytes = .{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a4[0], a4[1], a4[2], a4[3] }, |
| 449 | .bytes = .{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, b[0], b[1], b[2], b[3] }, |
| 445 | 450 | .interface_name = null, |
| 446 | 451 | } }; |
| 447 | 452 | } |
| ... | ... | @@ -457,7 +462,9 @@ pub const Ip6Address = struct { |
| 457 | 462 | .digit => c: switch (text[text_i]) { |
| 458 | 463 | 'a'...'f' => |c| { |
| 459 | 464 | const digit = c - 'a' + 10; |
| 460 | | parts[parts_i] = parts[parts_i] * 16 + digit; |
| 465 | parts[parts_i] = (std.math.mul(u16, parts[parts_i], 16) catch return .{ |
| 466 | .overflow = text_i, |
| 467 | }) + digit; |
| 461 | 468 | if (digit_i == 4) return .{ .invalid_byte = text_i }; |
| 462 | 469 | digit_i += 1; |
| 463 | 470 | text_i += 1; |
| ... | ... | @@ -470,7 +477,9 @@ pub const Ip6Address = struct { |
| 470 | 477 | 'A'...'F' => |c| continue :c c - 'A' + 'a', |
| 471 | 478 | '0'...'9' => |c| { |
| 472 | 479 | const digit = c - '0'; |
| 473 | | parts[parts_i] = parts[parts_i] * 16 + digit; |
| 480 | parts[parts_i] = (std.math.mul(u16, parts[parts_i], 16) catch return .{ |
| 481 | .overflow = text_i, |
| 482 | }) + digit; |
| 474 | 483 | if (digit_i == 4) return .{ .invalid_byte = text_i }; |
| 475 | 484 | digit_i += 1; |
| 476 | 485 | text_i += 1; |
| ... | ... | @@ -497,7 +506,7 @@ pub const Ip6Address = struct { |
| 497 | 506 | if (parts.len - parts_i == 0) continue :state .end; |
| 498 | 507 | digit_i = 0; |
| 499 | 508 | text_i += 1; |
| 500 | | if (text.len - text_i == 0) return .unexpected_end; |
| 509 | if (text.len - text_i == 0) return .incomplete; |
| 501 | 510 | continue :c text[text_i]; |
| 502 | 511 | } |
| 503 | 512 | }, |
| ... | ... | @@ -507,6 +516,7 @@ pub const Ip6Address = struct { |
| 507 | 516 | text_i += 1; |
| 508 | 517 | const name = text[text_i..]; |
| 509 | 518 | if (name.len > Interface.Name.max_len) return .{ .interface_name_oversized = text_i }; |
| 519 | if (name.len == 0) return .incomplete; |
| 510 | 520 | interface_name_text = name; |
| 511 | 521 | text_i = @intCast(text.len); |
| 512 | 522 | continue :state .end; |
| ... | ... | @@ -521,7 +531,7 @@ pub const Ip6Address = struct { |
| 521 | 531 | @memmove(parts[parts.len - src.len ..], src); |
| 522 | 532 | @memset(parts[s..][0..remaining], 0); |
| 523 | 533 | } else { |
| 524 | | if (remaining != 0) return .unexpected_end; |
| 534 | if (remaining != 0) return .incomplete; |
| 525 | 535 | } |
| 526 | 536 | |
| 527 | 537 | // Workaround that can be removed when this proposal is |