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

@ -112,6 +112,7 @@ else:
const
BufferSize*: int = 4000 ## size of a buffered socket's buffer
MaxLineLength* = 1_000_000
type
SocketImpl* = object ## socket type
@ -1006,7 +1007,7 @@ proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} =
result = recv(socket.fd, addr(c), 1, MSG_PEEK)
proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
flags = {SocketFlag.SafeDisconn}) {.
flags = {SocketFlag.SafeDisconn}, maxLength = MaxLineLength) {.
tags: [ReadIOEffect, TimeEffect].} =
## Reads a line of data from ``socket``.
##
@ -1021,6 +1022,10 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
## A timeout can be specified in milliseconds, if data is not received within
## the specified time an ETimeout exception will be raised.
##
## 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**: Only the ``SafeDisconn`` flag is currently supported.
template addNLIfEmpty() =
@ -1054,8 +1059,15 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
return
add(line.string, c)
# Verify that this isn't a DOS attack: #3847.
if line.string.len > maxLength:
let msg = "recvLine received more than the specified `maxLength` " &
"allowed."
raise newException(ValueError, msg)
proc recvLine*(socket: Socket, timeout = -1,
flags = {SocketFlag.SafeDisconn}): TaintedString =
flags = {SocketFlag.SafeDisconn},
maxLength = MaxLineLength): TaintedString =
## Reads a line of data from ``socket``.
##
## If a full line is read ``\r\L`` is not
@ -1069,9 +1081,13 @@ proc recvLine*(socket: Socket, timeout = -1,
## A timeout can be specified in milliseconds, if data is not received within
## the specified time an ETimeout exception will be raised.
##
## 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**: Only the ``SafeDisconn`` flag is currently supported.
result = ""
readLine(socket, result, timeout, flags)
readLine(socket, result, timeout, flags, maxLength)
proc recvFrom*(socket: Socket, data: var string, length: int,
address: var string, port: var Port, flags = 0'i32): int {.