Skip to content

Commit

Permalink
fix several newline problems (#15028) [backend]
Browse files Browse the repository at this point in the history
* prevent newlines where they shouldn't be
* 'contentLength' shouldn't be negative

(cherry picked from commit 5fafa2f)
  • Loading branch information
narimiran committed Jul 22, 2020
1 parent ddcbc1a commit e71395f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
4 changes: 4 additions & 0 deletions lib/pure/asyncftpclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,11 @@ proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} =
## Send a message to the server, and wait for a primary reply.
## ``\c\L`` is added for you.
##
## You need to make sure that the message ``m`` doesn't contain any newline
## characters. Failing to do so will raise ``AssertionDefect``.
##
## **Note:** The server may return multiple lines of coded replies.
doAssert(not m.contains({'\c', '\L'}), "message shouldn't contain any newline characters")
await ftp.csock.send(m & "\c\L")
return await ftp.expectReply()

Expand Down
8 changes: 7 additions & 1 deletion lib/pure/httpclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ proc contentLength*(response: Response | AsyncResponse): int =
##
## A ``ValueError`` exception will be raised if the value is not an integer.
var contentLengthHeader = response.headers.getOrDefault("Content-Length")
return contentLengthHeader.parseInt()
result = contentLengthHeader.parseInt()
doAssert(result >= 0 and result <= high(int32))

proc lastModified*(response: Response | AsyncResponse): DateTime =
## Retrieves the specified response's last modified time.
Expand Down Expand Up @@ -1018,6 +1019,11 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
##
## This procedure will follow redirects up to a maximum number of redirects
## specified in ``client.maxRedirects``.
##
## You need to make sure that the ``url`` doesn't contain any newline
## characters. Failing to do so will raise ``AssertionDefect``.
doAssert(not url.contains({'\c', '\L'}), "url shouldn't contain any newline characters")

result = await client.requestAux(url, httpMethod, body, headers, multipart)

var lastURL = url
Expand Down
39 changes: 37 additions & 2 deletions lib/pure/smtp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
## For SSL support this module relies on OpenSSL. If you want to
## enable SSL, compile with ``-d:ssl``.

import net, strutils, strtabs, base64, os
import net, strutils, strtabs, base64, os, strutils
import asyncnet, asyncdispatch

export Port
Expand All @@ -65,7 +65,22 @@ type
Smtp* = SmtpBase[Socket]
AsyncSmtp* = SmtpBase[AsyncSocket]

proc debugSend(smtp: Smtp | AsyncSmtp, cmd: string) {.multisync.} =
proc containsNewline(xs: seq[string]): bool =
for x in xs:
if x.contains({'\c', '\L'}):
return true

proc debugSend*(smtp: Smtp | AsyncSmtp, cmd: string) {.multisync.} =
## Sends ``cmd`` on the socket connected to the SMTP server.
##
## If the ``smtp`` object was created with ``debug`` enabled,
## debugSend will invoke ``echo("C:" & cmd)`` before sending.
##
## This is a lower level proc and not something that you typically
## would need to call when using this module. One exception to
## this is if you are implementing any
## `SMTP extensions<https://en.wikipedia.org/wiki/Extended_SMTP>`_.

if smtp.debug:
echo("C:" & cmd)
await smtp.sock.send(cmd)
Expand Down Expand Up @@ -95,6 +110,14 @@ else:
proc createMessage*(mSubject, mBody: string, mTo, mCc: seq[string],
otherHeaders: openarray[tuple[name, value: string]]): Message =
## Creates a new MIME compliant message.
##
## You need to make sure that ``mSubject``, ``mTo`` and ``mCc`` don't contain
## any newline characters. Failing to do so will raise ``AssertionDefect``.
doAssert(not mSubject.contains({'\c', '\L'}),
"'mSubject' shouldn't contain any newline characters")
doAssert(not (mTo.containsNewline() or mCc.containsNewline()),
"'mTo' and 'mCc' shouldn't contain any newline characters")

result.msgTo = mTo
result.msgCc = mCc
result.msgSubject = mSubject
Expand All @@ -106,6 +129,13 @@ proc createMessage*(mSubject, mBody: string, mTo, mCc: seq[string],
proc createMessage*(mSubject, mBody: string, mTo,
mCc: seq[string] = @[]): Message =
## Alternate version of the above.
##
## You need to make sure that ``mSubject``, ``mTo`` and ``mCc`` don't contain
## any newline characters. Failing to do so will raise ``AssertionDefect``.
doAssert(not mSubject.contains({'\c', '\L'}),
"'mSubject' shouldn't contain any newline characters")
doAssert(not (mTo.containsNewline() or mCc.containsNewline()),
"'mTo' and 'mCc' shouldn't contain any newline characters")
result.msgTo = mTo
result.msgCc = mCc
result.msgSubject = mSubject
Expand Down Expand Up @@ -213,6 +243,11 @@ proc sendMail*(smtp: Smtp | AsyncSmtp, fromAddr: string,
## Sends ``msg`` from ``fromAddr`` to the addresses specified in ``toAddrs``.
## Messages may be formed using ``createMessage`` by converting the
## Message into a string.
##
## You need to make sure that ``fromAddr`` and ``toAddrs`` don't contain
## any newline characters. Failing to do so will raise ``AssertionDefect``.
doAssert(not (toAddrs.containsNewline() or fromAddr.contains({'\c', '\L'})),
"'toAddrs' and 'fromAddr' shouldn't contain any newline characters")

await smtp.debugSend("MAIL FROM:<" & fromAddr & ">\c\L")
await smtp.checkReply("250")
Expand Down

0 comments on commit e71395f

Please sign in to comment.