port.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package net
  5. // parsePort parses service as a decimal integer and returns the
  6. // corresponding value as port. It is the caller's responsibility to
  7. // parse service as a non-decimal integer when needsLookup is true.
  8. //
  9. // Some system resolvers will return a valid port number when given a number
  10. // over 65536 (see https://golang.org/issues/11715). Alas, the parser
  11. // can't bail early on numbers > 65536. Therefore reasonably large/small
  12. // numbers are parsed in full and rejected if invalid.
  13. func parsePort(service string) (port int, needsLookup bool) {
  14. if service == "" {
  15. // Lock in the legacy behavior that an empty string
  16. // means port 0. See golang.org/issue/13610.
  17. return 0, false
  18. }
  19. const (
  20. max = uint32(1<<32 - 1)
  21. cutoff = uint32(1 << 30)
  22. )
  23. neg := false
  24. if service[0] == '+' {
  25. service = service[1:]
  26. } else if service[0] == '-' {
  27. neg = true
  28. service = service[1:]
  29. }
  30. var n uint32
  31. for _, d := range service {
  32. if '0' <= d && d <= '9' {
  33. d -= '0'
  34. } else {
  35. return 0, true
  36. }
  37. if n >= cutoff {
  38. n = max
  39. break
  40. }
  41. n *= 10
  42. nn := n + uint32(d)
  43. if nn < n || nn > max {
  44. n = max
  45. break
  46. }
  47. n = nn
  48. }
  49. if !neg && n >= cutoff {
  50. port = int(cutoff - 1)
  51. } else if neg && n > cutoff {
  52. port = int(cutoff)
  53. } else {
  54. port = int(n)
  55. }
  56. if neg {
  57. port = -port
  58. }
  59. return port, false
  60. }