Make the IP address exceptions more detailed

This commit is contained in:
Matthias Einwag
2014-03-14 22:17:44 +01:00
parent 7b055388b7
commit 95e4ab99e7

View File

@@ -139,20 +139,21 @@ proc parseIPv4Address(address_str: string): TIpAddress =
for i in 0 .. high(address_str):
if address_str[i] in strutils.Digits: # Character is a number
currentByte = currentByte * 10 + cast[uint16](ord(address_str[i]) - ord('0'))
if currentByte > 255'u16: raise newException(EInvalidValue, "Invalid IP Address")
if currentByte > 255'u16:
raise newException(EInvalidValue, "Invalid IP Address. Value is out of range")
seperatorValid = true
elif address_str[i] == '.': # IPv4 address separator
if not seperatorValid or byteCount >= 3:
raise new EInvalidValue
raise newException(EInvalidValue, "Invalid IP Address. The address consists of too many groups")
result.address_v4[byteCount] = cast[uint8](currentByte)
currentByte = 0
byteCount.inc
seperatorValid = false
else:
raise newException(EInvalidValue, "Invalid IP Address") # Invalid character
raise newException(EInvalidValue, "Invalid IP Address. Address contains an invalid character")
if byteCount != 3 or not seperatorValid:
raise new EInvalidValue
raise newException(EInvalidValue, "Invalid IP Address")
result.address_v4[byteCount] = cast[uint8](currentByte)
proc parseIPv6Address(address_str: string): TIpAddress =
@@ -173,22 +174,24 @@ proc parseIPv6Address(address_str: string): TIpAddress =
for i,c in address_str:
if c == ':':
if not seperatorValid: raise newException(EInvalidValue, "Invalid IP Address")
if not seperatorValid: raise newException(EInvalidValue, "Invalid IP Address. Address contains an invalid seperator")
if lastWasColon:
if dualColonGroup != -1: raise newException(EInvalidValue, "Invalid IP Address")
if dualColonGroup != -1: raise newException(EInvalidValue, "Invalid IP Address. Address contains more than one \"::\" seperator")
dualColonGroup = groupCount
seperatorValid = false
elif i != 0 and i != high(address_str):
if groupCount >= 8: raise newException(EInvalidValue, "Invalid IP Address")
if groupCount >= 8: raise newException(EInvalidValue, "Invalid IP Address. The address consists of too many groups")
result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8)
result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF)
currentShort = 0
groupCount.inc()
if dualColonGroup != -1: seperatorValid = false
elif i == 0: # only valid if address starts with ::
if address_str[1] != ':': raise newException(EInvalidValue, "Invalid IP Address")
if address_str[1] != ':':
raise newException(EInvalidValue, "Invalid IP Address. Address may not start with \":\"")
else: # i == high(address_str) - only valid if address ends with ::
if address_str[high(address_str)-1] != ':': raise newException(EInvalidValue, "Invalid IP Address")
if address_str[high(address_str)-1] != ':':
raise newException(EInvalidValue, "Invalid IP Address. Address may not end with \":\"")
lastWasColon = true
currentGroupStart = i + 1
elif c == '.': # Switch to parse IPv4 mode
@@ -204,16 +207,17 @@ proc parseIPv6Address(address_str: string): TIpAddress =
currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('a')) + 10
else: # Upper case hex
currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('A')) + 10
if currentShort > 65535'u32: raise newException(EInvalidValue, "Invalid IP Address")
if currentShort > 65535'u32:
raise newException(EInvalidValue, "Invalid IP Address. Value is out of range")
lastWasColon = false
seperatorValid = true
else:
raise newException(EInvalidValue, "Invalid IP Address")
raise newException(EInvalidValue, "Invalid IP Address. Address contains an invalid character")
if v4StartPos == -1: # Don't parse v4. Copy the remaining v6 stuff
if seperatorValid: # Copy remaining data
if groupCount >= 8: raise newException(EInvalidValue, "Invalid IP Address")
if groupCount >= 8: raise newException(EInvalidValue, "Invalid IP Address. The address consists of too many groups")
result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8)
result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF)
groupCount.inc()
@@ -221,35 +225,36 @@ proc parseIPv6Address(address_str: string): TIpAddress =
for i,c in address_str[v4StartPos..high(address_str)]:
if c in strutils.Digits: # Character is a number
currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0'))
if currentShort > 255'u32: raise newException(EInvalidValue, "Invalid IP Address")
if currentShort > 255'u32:
raise newException(EInvalidValue, "Invalid IP Address. Value is out of range")
seperatorValid = true
elif c == '.': # IPv4 address separator
if not seperatorValid or byteCount >= 3:
raise new EInvalidValue
raise newException(EInvalidValue, "Invalid IP Address")
result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort)
currentShort = 0
byteCount.inc()
seperatorValid = false
else: # Invalid character
raise newException(EInvalidValue, "Invalid IP Address")
raise newException(EInvalidValue, "Invalid IP Address. Address contains an invalid character")
if byteCount != 3 or not seperatorValid:
raise new EInvalidValue
raise newException(EInvalidValue, "Invalid IP Address")
result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort)
groupCount += 2
# Shift and fill zeros in case of ::
if groupCount > 8:
raise newException(EInvalidValue, "Invalid IP Address")
raise newException(EInvalidValue, "Invalid IP Address. The address consists of too many groups")
elif groupCount < 8: # must fill
if dualColonGroup == -1: raise newException(EInvalidValue, "Invalid IP Address")
if dualColonGroup == -1: raise newException(EInvalidValue, "Invalid IP Address. The address consists of too few groups")
var toFill = 8 - groupCount # The number of groups to fill
var toShift = groupCount - dualColonGroup # Nr of known groups after ::
for i in 0..2*toShift-1: # shift
result.address_v6[15-i] = result.address_v6[groupCount*2-i-1]
for i in 0..2*toFill-1: # fill with 0s
result.address_v6[dualColonGroup*2+i] = 0
elif dualColonGroup != -1: raise newException(EInvalidValue, "Invalid IP Address")
elif dualColonGroup != -1: raise newException(EInvalidValue, "Invalid IP Address. The address consists of too many groups")
proc parseIpAddress*(address_str: string): TIpAddress =