This commit is contained in:
Dominik Picheta 2016-09-25 13:02:10 +02:00
commit 8a6343b5b6
4 changed files with 52 additions and 10 deletions

View file

@ -388,7 +388,7 @@ proc accept*(socket: AsyncSocket,
return retFut
proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
flags = {SocketFlag.SafeDisconn}) {.async.} =
flags = {SocketFlag.SafeDisconn}, maxLength = MaxLineLength) {.async.} =
## Reads a line of data from ``socket`` into ``resString``.
##
## If a full line is read ``\r\L`` is not
@ -401,13 +401,14 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
## is read) then line will be set to ``""``.
## The partial line **will be lost**.
##
## The ``maxLength`` parameter determines the maximum amount of characters
## that can be read before a ``ValueError`` is raised. This prevents Denial
## of Service (DOS) attacks.
##
## **Warning**: The ``Peek`` flag is not yet implemented.
##
## **Warning**: ``recvLineInto`` on unbuffered sockets assumes that the
## protocol uses ``\r\L`` to delimit a new line.
##
## **Warning**: ``recvLineInto`` currently uses a raw pointer to a string for
## performance reasons. This will likely change soon to use FutureVars.
assert SocketFlag.Peek notin flags ## TODO:
assert(not resString.mget.isNil(),
"String inside resString future needs to be initialised")
@ -454,6 +455,12 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
else:
resString.mget.add socket.buffer[socket.currPos]
socket.currPos.inc()
# Verify that this isn't a DOS attack: #3847.
if resString.mget.len > maxLength:
let msg = "recvLine received more than the specified `maxLength` " &
"allowed."
raise newException(ValueError, msg)
else:
var c = ""
while true:
@ -475,10 +482,17 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
resString.complete()
return
resString.mget.add c
# Verify that this isn't a DOS attack: #3847.
if resString.mget.len > maxLength:
let msg = "recvLine received more than the specified `maxLength` " &
"allowed."
raise newException(ValueError, msg)
resString.complete()
proc recvLine*(socket: AsyncSocket,
flags = {SocketFlag.SafeDisconn}): Future[string] {.async.} =
flags = {SocketFlag.SafeDisconn},
maxLength = MaxLineLength): Future[string] {.async.} =
## Reads a line of data from ``socket``. Returned future will complete once
## a full line is read or an error occurs.
##
@ -492,6 +506,10 @@ proc recvLine*(socket: AsyncSocket,
## is read) then line will be set to ``""``.
## The partial line **will be lost**.
##
## The ``maxLength`` parameter determines the maximum amount of characters
## that can be read before a ``ValueError`` is raised. This prevents Denial
## of Service (DOS) attacks.
##
## **Warning**: The ``Peek`` flag is not yet implemented.
##
## **Warning**: ``recvLine`` on unbuffered sockets assumes that the protocol
@ -501,7 +519,7 @@ proc recvLine*(socket: AsyncSocket,
# TODO: Optimise this
var resString = newFutureVar[string]("asyncnet.recvLine")
resString.mget() = ""
await socket.recvLineInto(resString, flags)
await socket.recvLineInto(resString, flags, maxLength)
result = resString.mget()
proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =