mirror of
https://github.com/mjl-/mox.git
synced 2024-12-28 01:13:47 +03:00
63 lines
1.5 KiB
Go
63 lines
1.5 KiB
Go
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package adns
|
||
|
|
||
|
// parsePort parses service as a decimal integer and returns the
|
||
|
// corresponding value as port. It is the caller's responsibility to
|
||
|
// parse service as a non-decimal integer when needsLookup is true.
|
||
|
//
|
||
|
// Some system resolvers will return a valid port number when given a number
|
||
|
// over 65536 (see https://golang.org/issues/11715). Alas, the parser
|
||
|
// can't bail early on numbers > 65536. Therefore reasonably large/small
|
||
|
// numbers are parsed in full and rejected if invalid.
|
||
|
func parsePort(service string) (port int, needsLookup bool) {
|
||
|
if service == "" {
|
||
|
// Lock in the legacy behavior that an empty string
|
||
|
// means port 0. See golang.org/issue/13610.
|
||
|
return 0, false
|
||
|
}
|
||
|
const (
|
||
|
max = uint32(1<<32 - 1)
|
||
|
cutoff = uint32(1 << 30)
|
||
|
)
|
||
|
neg := false
|
||
|
if service[0] == '+' {
|
||
|
service = service[1:]
|
||
|
} else if service[0] == '-' {
|
||
|
neg = true
|
||
|
service = service[1:]
|
||
|
}
|
||
|
var n uint32
|
||
|
for _, d := range service {
|
||
|
if '0' <= d && d <= '9' {
|
||
|
d -= '0'
|
||
|
} else {
|
||
|
return 0, true
|
||
|
}
|
||
|
if n >= cutoff {
|
||
|
n = max
|
||
|
break
|
||
|
}
|
||
|
n *= 10
|
||
|
nn := n + uint32(d)
|
||
|
if nn < n || nn > max {
|
||
|
n = max
|
||
|
break
|
||
|
}
|
||
|
n = nn
|
||
|
}
|
||
|
if !neg && n >= cutoff {
|
||
|
port = int(cutoff - 1)
|
||
|
} else if neg && n > cutoff {
|
||
|
port = int(cutoff)
|
||
|
} else {
|
||
|
port = int(n)
|
||
|
}
|
||
|
if neg {
|
||
|
port = -port
|
||
|
}
|
||
|
return port, false
|
||
|
}
|