| // 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 net | 
 |  | 
 | // parsePort parses service as a decimal interger 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://github.com/golang/go/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 | 
 | } |