WIP: disallow 'nil' for strings and seqs

This commit is contained in:
Andreas Rumpf 2018-08-13 11:41:33 +02:00
commit dae5450947
43 changed files with 207 additions and 173 deletions

View file

@ -231,7 +231,7 @@ proc newSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
raiseOSError(osLastError())
result = newSocket(fd, domain, sockType, protocol, buffered)
proc parseIPv4Address(address_str: string): IpAddress =
proc parseIPv4Address(addressStr: string): IpAddress =
## Parses IPv4 adresses
## Raises EInvalidValue on errors
var
@ -241,15 +241,15 @@ proc parseIPv4Address(address_str: string): IpAddress =
result.family = IpAddressFamily.IPv4
for i in 0 .. high(address_str):
if address_str[i] in strutils.Digits: # Character is a number
for i in 0 .. high(addressStr):
if addressStr[i] in strutils.Digits: # Character is a number
currentByte = currentByte * 10 +
cast[uint16](ord(address_str[i]) - ord('0'))
cast[uint16](ord(addressStr[i]) - ord('0'))
if currentByte > 255'u16:
raise newException(ValueError,
"Invalid IP Address. Value is out of range")
seperatorValid = true
elif address_str[i] == '.': # IPv4 address separator
elif addressStr[i] == '.': # IPv4 address separator
if not seperatorValid or byteCount >= 3:
raise newException(ValueError,
"Invalid IP Address. The address consists of too many groups")
@ -265,11 +265,11 @@ proc parseIPv4Address(address_str: string): IpAddress =
raise newException(ValueError, "Invalid IP Address")
result.address_v4[byteCount] = cast[uint8](currentByte)
proc parseIPv6Address(address_str: string): IpAddress =
proc parseIPv6Address(addressStr: string): IpAddress =
## Parses IPv6 adresses
## Raises EInvalidValue on errors
result.family = IpAddressFamily.IPv6
if address_str.len < 2:
if addressStr.len < 2:
raise newException(ValueError, "Invalid IP Address")
var
@ -282,7 +282,7 @@ proc parseIPv6Address(address_str: string): IpAddress =
v4StartPos = -1
byteCount = 0
for i,c in address_str:
for i,c in addressStr:
if c == ':':
if not seperatorValid:
raise newException(ValueError,
@ -293,7 +293,7 @@ proc parseIPv6Address(address_str: string): IpAddress =
"Invalid IP Address. Address contains more than one \"::\" seperator")
dualColonGroup = groupCount
seperatorValid = false
elif i != 0 and i != high(address_str):
elif i != 0 and i != high(addressStr):
if groupCount >= 8:
raise newException(ValueError,
"Invalid IP Address. The address consists of too many groups")
@ -303,11 +303,11 @@ proc parseIPv6Address(address_str: string): IpAddress =
groupCount.inc()
if dualColonGroup != -1: seperatorValid = false
elif i == 0: # only valid if address starts with ::
if address_str[1] != ':':
if addressStr[1] != ':':
raise newException(ValueError,
"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] != ':':
else: # i == high(addressStr) - only valid if address ends with ::
if addressStr[high(addressStr)-1] != ':':
raise newException(ValueError,
"Invalid IP Address. Address may not end with \":\"")
lastWasColon = true
@ -345,7 +345,7 @@ proc parseIPv6Address(address_str: string): IpAddress =
result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF)
groupCount.inc()
else: # Must parse IPv4 address
for i,c in address_str[v4StartPos..high(address_str)]:
for i,c in addressStr[v4StartPos..high(addressStr)]:
if c in strutils.Digits: # Character is a number
currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0'))
if currentShort > 255'u32:
@ -386,21 +386,21 @@ proc parseIPv6Address(address_str: string): IpAddress =
raise newException(ValueError,
"Invalid IP Address. The address consists of too many groups")
proc parseIpAddress*(address_str: string): IpAddress =
proc parseIpAddress*(addressStr: string): IpAddress =
## Parses an IP address
## Raises EInvalidValue on error
if address_str == nil:
raise newException(ValueError, "IP Address string is nil")
if address_str.contains(':'):
return parseIPv6Address(address_str)
if addressStr.len == 0:
raise newException(ValueError, "IP Address string is empty")
if addressStr.contains(':'):
return parseIPv6Address(addressStr)
else:
return parseIPv4Address(address_str)
return parseIPv4Address(addressStr)
proc isIpAddress*(address_str: string): bool {.tags: [].} =
proc isIpAddress*(addressStr: string): bool {.tags: [].} =
## Checks if a string is an IP address
## Returns true if it is, false otherwise
try:
discard parseIpAddress(address_str)
discard parseIpAddress(addressStr)
except ValueError:
return false
return true
@ -587,7 +587,7 @@ when defineSsl:
proc pskClientCallback(ssl: SslPtr; hint: cstring; identity: cstring; max_identity_len: cuint; psk: ptr cuchar;
max_psk_len: cuint): cuint {.cdecl.} =
let ctx = SSLContext(context: ssl.SSL_get_SSL_CTX)
let hintString = if hint == nil: nil else: $hint
let hintString = if hint == nil: "" else: $hint
let (identityString, pskString) = (ctx.clientGetPskFunc)(hintString)
if psk.len.cuint > max_psk_len:
return 0
@ -657,7 +657,7 @@ when defineSsl:
proc wrapConnectedSocket*(ctx: SSLContext, socket: Socket,
handshake: SslHandshakeType,
hostname: string = nil) =
hostname: string = "") =
## Wraps a connected socket in an SSL context. This function effectively
## turns ``socket`` into an SSL socket.
## ``hostname`` should be specified so that the client knows which hostname
@ -671,7 +671,7 @@ when defineSsl:
wrapSocket(ctx, socket)
case handshake
of handshakeAsClient:
if not hostname.isNil and not isIpAddress(hostname):
if hostname.len > 0 and not isIpAddress(hostname):
# Discard result in case OpenSSL version doesn't support SNI, or we're
# not using TLSv1+
discard SSL_set_tlsext_host_name(socket.sslHandle, hostname)