@@ -149,7 +149,7 @@ package enum PeerAddress: Equatable {
149149 let addressType = addressUTF8View [ ..< firstColonIndex]
150150
151151 var addressWithoutType = addressUTF8View [ firstColonIndex... ]
152- _ = addressWithoutType. popFirst ( )
152+ addressWithoutType. removeFirst ( )
153153
154154 // Check what type the transport is...
155155 if addressType. elementsEqual ( " ipv4 " . utf8) {
@@ -160,9 +160,9 @@ package enum PeerAddress: Equatable {
160160
161161 let hostComponent = addressWithoutType [ ..< addressColon]
162162 var portComponent = addressWithoutType [ addressColon... ]
163- _ = portComponent. popFirst ( )
163+ portComponent. removeFirst ( )
164164
165- if let host = String ( hostComponent) , let port = Int ( utf8View : portComponent) {
165+ if let host = String ( hostComponent) , let port = Int ( ipAddressPortStringBytes : portComponent) {
166166 self = . ipv4( address: host, port: port)
167167 } else {
168168 return nil
@@ -175,11 +175,11 @@ package enum PeerAddress: Equatable {
175175
176176 var hostComponent = addressWithoutType [ ..< lastColonIndex]
177177 var portComponent = addressWithoutType [ lastColonIndex... ]
178- _ = portComponent. popFirst ( )
178+ portComponent. removeFirst ( )
179179
180180 if let firstBracket = hostComponent. popFirst ( ) , let lastBracket = hostComponent. popLast ( ) ,
181181 firstBracket == UInt8 ( ascii: " [ " ) , lastBracket == UInt8 ( ascii: " ] " ) ,
182- let host = String ( hostComponent) , let port = Int ( utf8View : portComponent)
182+ let host = String ( hostComponent) , let port = Int ( ipAddressPortStringBytes : portComponent)
183183 {
184184 self = . ipv6( address: host, port: port)
185185 } else {
@@ -197,17 +197,30 @@ package enum PeerAddress: Equatable {
197197}
198198
199199extension Int {
200- package init ? ( utf8View: Substring . UTF8View . SubSequence ) {
200+ package init ? ( ipAddressPortStringBytes: some Collection < UInt8 > ) {
201+ guard ( 1 ... 5 ) . contains ( ipAddressPortStringBytes. count) else {
202+ // Valid IP port values go up to 2^16-1 (65535), which is 5 digits long.
203+ // If the string we get is over 5 characters, we know for sure that this is an invalid port.
204+ // If it's empty, we also know it's invalid as we need at least one digit.
205+ return nil
206+ }
207+
201208 var value = 0
202- for utf8Element in utf8View {
209+ for utf8Char in ipAddressPortStringBytes {
203210 value &*= 10
204- let elementValue = Int ( utf8Element - 48 ) // ASCII code for 0 is 48
205- guard elementValue >= 0 , elementValue <= 9 else {
211+ guard ( UInt8 ( ascii: " 0 " ) ... UInt8 ( ascii: " 9 " ) ) . contains ( utf8Char) else {
206212 // non-digit character
207213 return nil
208214 }
209- value &+= elementValue
215+ value &+= Int ( utf8Char )
210216 }
217+
218+ guard value <= 65535 else {
219+ // Valid IP port values go up to 2^16-1 = 65535.
220+ // If a number greater than this was given, it can't be a valid port.
221+ return nil
222+ }
223+
211224 self = value
212225 }
213226}
0 commit comments