update with changes from go1.20.5 to go1.21.4

This commit is contained in:
Scott Feldman
2023-11-13 23:28:14 -08:00
committed by deadprogram
parent be25e1a28e
commit 7c11b88ce6
32 changed files with 139 additions and 347 deletions
+31 -248
View File
@@ -1,4 +1,4 @@
// TINYGO: The following is copied from Go 1.20.5 official implementation.
// TINYGO: The following is copied from Go 1.21.4 official implementation.
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -17,6 +17,7 @@ package net
import (
"internal/bytealg"
"internal/itoa"
"net/netip"
)
// IP address lengths (bytes).
@@ -287,25 +288,6 @@ func (ip IP) Mask(mask IPMask) IP {
return out
}
// ubtoa encodes the string form of the integer v to dst[start:] and
// returns the number of bytes written to dst. The caller must ensure
// that dst has sufficient length.
func ubtoa(dst []byte, start int, v byte) int {
if v < 10 {
dst[start] = v + '0'
return 1
} else if v < 100 {
dst[start+1] = v%10 + '0'
dst[start] = v/10 + '0'
return 2
}
dst[start+2] = v%10 + '0'
dst[start+1] = (v/10)%10 + '0'
dst[start] = v/100 + '0'
return 3
}
// String returns the string form of the IP address ip.
// It returns one of 4 forms:
// - "<nil>", if ip has length 0
@@ -313,73 +295,18 @@ func ubtoa(dst []byte, start int, v byte) int {
// - IPv6 conforming to RFC 5952 ("2001:db8::1"), if ip is a valid IPv6 address
// - the hexadecimal form of ip, without punctuation, if no other cases apply
func (ip IP) String() string {
p := ip
if len(ip) == 0 {
return "<nil>"
}
// If IPv4, use dotted notation.
if p4 := p.To4(); len(p4) == IPv4len {
const maxIPv4StringLen = len("255.255.255.255")
b := make([]byte, maxIPv4StringLen)
n := ubtoa(b, 0, p4[0])
b[n] = '.'
n++
n += ubtoa(b, n, p4[1])
b[n] = '.'
n++
n += ubtoa(b, n, p4[2])
b[n] = '.'
n++
n += ubtoa(b, n, p4[3])
return string(b[:n])
}
if len(p) != IPv6len {
if len(ip) != IPv4len && len(ip) != IPv6len {
return "?" + hexString(ip)
}
// Find longest run of zeros.
e0 := -1
e1 := -1
for i := 0; i < IPv6len; i += 2 {
j := i
for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
j += 2
}
if j > i && j-i > e1-e0 {
e0 = i
e1 = j
i = j
}
// If IPv4, use dotted notation.
if p4 := ip.To4(); len(p4) == IPv4len {
return netip.AddrFrom4([4]byte(p4)).String()
}
// The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
if e1-e0 <= 2 {
e0 = -1
e1 = -1
}
const maxLen = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
b := make([]byte, 0, maxLen)
// Print with possible :: in place of run of zeros
for i := 0; i < IPv6len; i += 2 {
if i == e0 {
b = append(b, ':', ':')
i = e1
if i >= IPv6len {
break
}
} else if i > 0 {
b = append(b, ':')
}
b = appendHex(b, (uint32(p[i])<<8)|uint32(p[i+1]))
}
return string(b)
return netip.AddrFrom16([16]byte(ip)).String()
}
func hexString(b []byte) string {
@@ -561,175 +488,24 @@ func (n *IPNet) String() string {
return nn.String() + "/" + itoa.Uitoa(uint(l))
}
// Parse IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
var p [IPv4len]byte
for i := 0; i < IPv4len; i++ {
if len(s) == 0 {
// Missing octets.
return nil
}
if i > 0 {
if s[0] != '.' {
return nil
}
s = s[1:]
}
n, c, ok := dtoi(s)
if !ok || n > 0xFF {
return nil
}
if c > 1 && s[0] == '0' {
// Reject non-zero components with leading zeroes.
return nil
}
s = s[c:]
p[i] = byte(n)
}
if len(s) != 0 {
return nil
}
return IPv4(p[0], p[1], p[2], p[3])
}
// parseIPv6Zone parses s as a literal IPv6 address and its associated zone
// identifier which is described in RFC 4007.
func parseIPv6Zone(s string) (IP, string) {
s, zone := splitHostZone(s)
return parseIPv6(s), zone
}
// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
// and RFC 5952.
func parseIPv6(s string) (ip IP) {
ip = make(IP, IPv6len)
ellipsis := -1 // position of ellipsis in ip
// Might have leading ellipsis
if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
ellipsis = 0
s = s[2:]
// Might be only ellipsis
if len(s) == 0 {
return ip
}
}
// Loop, parsing hex numbers followed by colon.
i := 0
for i < IPv6len {
// Hex number.
n, c, ok := xtoi(s)
if !ok || n > 0xFFFF {
return nil
}
// If followed by dot, might be in trailing IPv4.
if c < len(s) && s[c] == '.' {
if ellipsis < 0 && i != IPv6len-IPv4len {
// Not the right place.
return nil
}
if i+IPv4len > IPv6len {
// Not enough room.
return nil
}
ip4 := parseIPv4(s)
if ip4 == nil {
return nil
}
ip[i] = ip4[12]
ip[i+1] = ip4[13]
ip[i+2] = ip4[14]
ip[i+3] = ip4[15]
s = ""
i += IPv4len
break
}
// Save this 16-bit chunk.
ip[i] = byte(n >> 8)
ip[i+1] = byte(n)
i += 2
// Stop at end of string.
s = s[c:]
if len(s) == 0 {
break
}
// Otherwise must be followed by colon and more.
if s[0] != ':' || len(s) == 1 {
return nil
}
s = s[1:]
// Look for ellipsis.
if s[0] == ':' {
if ellipsis >= 0 { // already have one
return nil
}
ellipsis = i
s = s[1:]
if len(s) == 0 { // can be at end
break
}
}
}
// Must have used entire string.
if len(s) != 0 {
return nil
}
// If didn't parse enough, expand ellipsis.
if i < IPv6len {
if ellipsis < 0 {
return nil
}
n := IPv6len - i
for j := i - 1; j >= ellipsis; j-- {
ip[j+n] = ip[j]
}
for j := ellipsis + n - 1; j >= ellipsis; j-- {
ip[j] = 0
}
} else if ellipsis >= 0 {
// Ellipsis must represent at least one 0 group.
return nil
}
return ip
}
// ParseIP parses s as an IP address, returning the result.
// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
// If s is not a valid textual representation of an IP address,
// ParseIP returns nil.
func ParseIP(s string) IP {
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return parseIPv4(s)
case ':':
return parseIPv6(s)
}
if addr, valid := parseIP(s); valid {
return IP(addr[:])
}
return nil
}
// parseIPZone parses s as an IP address, return it and its associated zone
// identifier (IPv6 only).
func parseIPZone(s string) (IP, string) {
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return parseIPv4(s), ""
case ':':
return parseIPv6Zone(s)
}
func parseIP(s string) ([16]byte, bool) {
ip, err := netip.ParseAddr(s)
if err != nil || ip.Zone() != "" {
return [16]byte{}, false
}
return nil, ""
return ip.As16(), true
}
// ParseCIDR parses s as a CIDR notation IP address and prefix length,
@@ -746,16 +522,23 @@ func ParseCIDR(s string) (IP, *IPNet, error) {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
addr, mask := s[:i], s[i+1:]
iplen := IPv4len
ip := parseIPv4(addr)
if ip == nil {
iplen = IPv6len
ip = parseIPv6(addr)
}
n, i, ok := dtoi(mask)
if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
ipAddr, err := netip.ParseAddr(addr)
if err != nil || ipAddr.Zone() != "" {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
m := CIDRMask(n, 8*iplen)
return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
n, i, ok := dtoi(mask)
if !ok || i != len(mask) || n < 0 || n > ipAddr.BitLen() {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
m := CIDRMask(n, ipAddr.BitLen())
addr16 := ipAddr.As16()
return IP(addr16[:]), &IPNet{IP: IP(addr16[:]).Mask(m), Mask: m}, nil
}
func copyIP(x IP) IP {
y := make(IP, len(x))
copy(y, x)
return y
}