Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate TaintedString #15423

Merged
merged 33 commits into from
Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8dc4f12
Clean out
juancarlospaco Sep 28, 2020
57ef87c
wtf that test
juancarlospaco Sep 28, 2020
2158fc7
clean clean clean out
juancarlospaco Sep 28, 2020
c508471
clean out more
juancarlospaco Sep 28, 2020
bba7c39
Merge branch 'devel' of https://github.com/nim-lang/Nim into no-taint
juancarlospaco Oct 29, 2020
a5b708e
ReSync again and again
juancarlospaco Nov 19, 2020
e7f39fd
Merge branch 'no-taint' of https://github.com/juancarlospaco/Nim into…
juancarlospaco Nov 19, 2020
69687bd
We reach end of year and this is not merged
juancarlospaco Jan 1, 2021
ba8a496
ReSync
juancarlospaco Jan 15, 2021
c4d6198
ReSync
juancarlospaco Jan 15, 2021
f57e10a
ReSync
juancarlospaco Jan 15, 2021
bc158f0
ReSync
juancarlospaco Jan 15, 2021
14a4eea
Update compiler/commands.nim
juancarlospaco Jan 15, 2021
ff27b8c
Update compiler/commands.nim
juancarlospaco Jan 15, 2021
50e424b
ReSync
juancarlospaco Jan 15, 2021
886f6fe
Merge branch 'devel' of https://github.com/nim-lang/Nim into no-taint
juancarlospaco Jan 15, 2021
33584fe
Merge branch 'no-taint' of https://github.com/juancarlospaco/Nim into…
juancarlospaco Jan 15, 2021
6c1d533
ReSync
juancarlospaco Jan 15, 2021
7df8653
Update lib/pure/asyncftpclient.nim
juancarlospaco Jan 15, 2021
43eb6ea
Update lib/pure/asyncftpclient.nim
juancarlospaco Jan 15, 2021
f304473
Update lib/pure/asyncftpclient.nim
juancarlospaco Jan 15, 2021
9e28c19
Update lib/impure/rdstdin.nim
juancarlospaco Jan 15, 2021
ccd0051
Update lib/impure/rdstdin.nim
juancarlospaco Jan 15, 2021
a0de47e
Update lib/impure/rdstdin.nim
juancarlospaco Jan 15, 2021
7eb8f09
ReSync
juancarlospaco Jan 15, 2021
2a5cc45
Update compiler/commands.nim
juancarlospaco Jan 15, 2021
4ae6b49
ReSync
juancarlospaco Jan 15, 2021
eb839c1
Update compiler/commands.nim
juancarlospaco Jan 15, 2021
8e70d1e
Update compiler/commands.nim
juancarlospaco Jan 15, 2021
b15056f
ReSync
juancarlospaco Jan 15, 2021
54899ab
Merge branch 'no-taint' of https://github.com/juancarlospaco/Nim into…
juancarlospaco Jan 15, 2021
2dccfd3
ReSync
juancarlospaco Jan 16, 2021
63b3546
ReSync
juancarlospaco Jan 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@

- Added `--declaredlocs` to show symbol declaration location in messages.

- Added a ``.noalias`` pragma. It is mapped to C's ``restrict`` keyword for the increased
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
performance this keyword can enable.
- Deprecated `TaintedString` and Taint mode.
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
- Source+Edit links now appear on top of every docgen'd page when
`nim doc --git.url:url ...` is given.

Expand Down
2 changes: 0 additions & 2 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
of "symbolfiles": result = conf.symbolFiles != disabledSf
of "genscript": result = contains(conf.globalOptions, optGenScript)
of "threads": result = contains(conf.globalOptions, optThreads)
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
of "taintmode": result = contains(conf.globalOptions, optTaintMode)
of "tlsemulation": result = contains(conf.globalOptions, optTlsEmulation)
of "implicitstatic": result = contains(conf.options, optImplicitStatic)
of "patterns", "trmacros": result = contains(conf.options, optTrMacros)
Expand Down Expand Up @@ -667,7 +666,6 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
processOnOffSwitchG(conf, {optThreads}, arg, pass, info)
#if optThreads in conf.globalOptions: conf.setNote(warnGcUnsafe)
of "tlsemulation": processOnOffSwitchG(conf, {optTlsEmulation}, arg, pass, info)
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
of "taintmode": processOnOffSwitchG(conf, {optTaintMode}, arg, pass, info)
of "implicitstatic":
processOnOffSwitch(conf, {optImplicitStatic}, arg, pass, info)
of "patterns", "trmacros":
Expand Down
1 change: 0 additions & 1 deletion compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ type # please make sure we have under 32 options
optThreads, # support for multi-threading
optStdout, # output to stdout
optThreadAnalysis, # thread analysis pass
optTaintMode, # taint mode turned on
optTlsEmulation, # thread var emulation turned on
optGenIndex # generate index file for documentation;
optEmbedOrigSrc # embed the original source in the generated code
Expand Down
1 change: 0 additions & 1 deletion doc/advopt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ Advanced options:
in the generated output
--threadanalysis:on|off turn thread analysis on|off
--tlsEmulation:on|off turn thread local storage emulation on|off
--taintMode:on|off turn taint mode on|off
--implicitStatic:on|off turn implicit compile time evaluation on|off
--trmacros:on|off turn term rewriting macros on|off
--multimethods:on|off turn multi-methods on|off
Expand Down
2 changes: 1 addition & 1 deletion doc/idetools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ skLet
let
text = "some text"
--> col 2: $MODULE.text
col 3: TaintedString
col 3: string
col 7: ""


Expand Down
22 changes: 0 additions & 22 deletions doc/manual_experimental.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1718,28 +1718,6 @@ e.g. with given example ``echo("ab")`` will be rewritten just once:
``noRewrite`` pragma can be useful to control term-rewriting macros recursion.


Taint mode
==========

The Nim compiler and most parts of the standard library support
a taint mode. Input strings are declared with the `TaintedString`:idx:
string type declared in the ``system`` module.

If the taint mode is turned on (via the ``--taintMode:on`` command line
option) it is a distinct string type which helps to detect input
validation errors:

.. code-block:: nim
echo "your name: "
var name: TaintedString = stdin.readline
# it is safe here to output the name without any input validation, so
# we simply convert `name` to string to make the compiler happy:
echo "hi, ", name.string

If the taint mode is turned off, ``TaintedString`` is simply an alias for
``string``.


Aliasing restrictions in parameter passing
==========================================

Expand Down
8 changes: 4 additions & 4 deletions lib/deprecated/pure/parseopt2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type
pos: int
remainingShortOptions: string
kind*: CmdLineKind ## the detected command line token
key*, val*: TaintedString ## key and value pair; ``key`` is the option
key*, val*: string ## key and value pair; ``key`` is the option
## or the argument, ``value`` is not "" if
## the option was given a value

Expand Down Expand Up @@ -80,7 +80,7 @@ proc nextOption(p: var OptParser, token: string, allowEmpty: bool) =
proc next(p: var OptParser) =
if p.remainingShortOptions.len != 0:
p.kind = cmdShortOption
p.key = TaintedString(p.remainingShortOptions[0..0])
p.key = p.remainingShortOptions[0..0]
p.val = ""
p.remainingShortOptions = p.remainingShortOptions[1..p.remainingShortOptions.len-1]
return
Expand All @@ -103,13 +103,13 @@ proc next(p: var OptParser) =
p.key = token
p.val = ""

proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo2$1".} =
proc cmdLineRest*(p: OptParser): string {.rtl, extern: "npo2$1".} =
## Returns the part of command line string that has not been parsed yet,
## properly quoted.
return p.cmd[p.pos..p.cmd.len-1].quoteShellCommand

type
GetoptResult* = tuple[kind: CmdLineKind, key, val: TaintedString]
GetoptResult* = tuple[kind: CmdLineKind, key, val: string]

iterator getopt*(p: var OptParser): GetoptResult =
## This is an convenience iterator for iterating over the given OptParser object.
Expand Down
16 changes: 8 additions & 8 deletions lib/impure/rdstdin.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
## echo userResponse

when defined(Windows):
proc readLineFromStdin*(prompt: string): TaintedString {.
proc readLineFromStdin*(prompt: string): string {.
tags: [ReadIOEffect, WriteIOEffect].} =
## Reads a line from stdin.
stdout.write(prompt)
result = readLine(stdin)

proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {.
proc readLineFromStdin*(prompt: string, line: var string): bool {.
tags: [ReadIOEffect, WriteIOEffect].} =
## Reads a `line` from stdin. `line` must not be
## ``nil``! May throw an IO exception.
Expand All @@ -40,34 +40,34 @@ when defined(Windows):
result = readLine(stdin, line)

elif defined(genode):
proc readLineFromStdin*(prompt: string): TaintedString {.
proc readLineFromStdin*(prompt: string): string {.
tags: [ReadIOEffect, WriteIOEffect].} =
stdin.readLine()

proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {.
proc readLineFromStdin*(prompt: string, line: var string): bool {.
tags: [ReadIOEffect, WriteIOEffect].} =
stdin.readLine(line)

else:
import linenoise

proc readLineFromStdin*(prompt: string): TaintedString {.
proc readLineFromStdin*(prompt: string): string {.
tags: [ReadIOEffect, WriteIOEffect].} =
var buffer = linenoise.readLine(prompt)
if isNil(buffer):
raise newException(IOError, "Linenoise returned nil")
result = TaintedString($buffer)
result = $buffer
if result.string.len > 0:
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
historyAdd(buffer)
linenoise.free(buffer)

proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {.
proc readLineFromStdin*(prompt: string, line: var string): bool {.
tags: [ReadIOEffect, WriteIOEffect].} =
var buffer = linenoise.readLine(prompt)
if isNil(buffer):
line.string.setLen(0)
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
return false
line = TaintedString($buffer)
line = $buffer
if line.string.len > 0:
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
historyAdd(buffer)
linenoise.free(buffer)
Expand Down
16 changes: 8 additions & 8 deletions lib/pure/asyncftpclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ type

const multiLineLimit = 10000

proc expectReply(ftp: AsyncFtpClient): Future[TaintedString] {.async.} =
proc expectReply(ftp: AsyncFtpClient): Future[string] {.async.} =
var line = await ftp.csock.recvLine()
result = TaintedString(line)
result = line
var count = 0
while line.len > 3 and line[3] == '-':
## Multi-line reply.
Expand All @@ -146,7 +146,7 @@ proc expectReply(ftp: AsyncFtpClient): Future[TaintedString] {.async.} =
if count >= multiLineLimit:
raise newException(ReplyError, "Reached maximum multi-line reply count.")

proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} =
proc send*(ftp: AsyncFtpClient, m: string): Future[string] {.async.} =
## Send a message to the server, and wait for a primary reply.
## ``\c\L`` is added for you.
##
Expand All @@ -158,7 +158,7 @@ proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} =
await ftp.csock.send(m & "\c\L")
return await ftp.expectReply()

proc assertReply(received: TaintedString, expected: varargs[string]) =
proc assertReply(received: string, expected: varargs[string]) =
for i in items(expected):
if received.string.startsWith(i): return
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
raise newException(ReplyError,
Expand All @@ -169,7 +169,7 @@ proc pasv(ftp: AsyncFtpClient) {.async.} =
## Negotiate a data connection.
ftp.dsock = newAsyncSocket()

var pasvMsg = (await ftp.send("PASV")).string.strip.TaintedString
var pasvMsg = (await ftp.send("PASV")).string.strip
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
assertReply(pasvMsg, "227")
var betweenParens = captureBetween(pasvMsg.string, '(', ')')
var nums = betweenParens.split(',')
Expand Down Expand Up @@ -201,11 +201,11 @@ proc connect*(ftp: AsyncFtpClient) {.async.} =
if ftp.pass != "":
assertReply(await(ftp.send("PASS " & ftp.pass)), "230")

proc pwd*(ftp: AsyncFtpClient): Future[TaintedString] {.async.} =
proc pwd*(ftp: AsyncFtpClient): Future[string] {.async.} =
## Returns the current working directory.
let wd = await ftp.send("PWD")
assertReply wd, "257"
return wd.string.captureBetween('"').TaintedString # "
return wd.string.captureBetween('"') # "
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved

proc cd*(ftp: AsyncFtpClient, dir: string) {.async.} =
## Changes the current directory on the remote FTP server to ``dir``.
Expand Down Expand Up @@ -253,7 +253,7 @@ proc createDir*(ftp: AsyncFtpClient, dir: string, recursive = false){.async.} =
if not recursive:
assertReply(await(ftp.send("MKD " & dir.normalizePathSep)), "257")
else:
var reply = TaintedString""
var reply = ""
var previousDirs = ""
for p in split(dir, {os.DirSep, os.AltSep}):
if p != "":
Expand Down
8 changes: 4 additions & 4 deletions lib/pure/cgi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ proc getEncodedData(allowedMethods: set[RequestMethod]): string =
if methodNone notin allowedMethods:
cgiError("'REQUEST_METHOD' must be 'POST' or 'GET'")

iterator decodeData*(data: string): tuple[key, value: TaintedString] =
iterator decodeData*(data: string): tuple[key, value: string] =
## Reads and decodes CGI data and yields the (name, value) pairs the
## data consists of.
try:
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -91,7 +91,7 @@ iterator decodeData*(data: string): tuple[key, value: TaintedString] =
cgiError(e.msg)

iterator decodeData*(allowedMethods: set[RequestMethod] =
{methodNone, methodPost, methodGet}): tuple[key, value: TaintedString] =
{methodNone, methodPost, methodGet}): tuple[key, value: string] =
## Reads and decodes CGI data and yields the (name, value) pairs the
## data consists of. If the client does not use a method listed in the
## `allowedMethods` set, a `CgiError` exception is raised.
Expand Down Expand Up @@ -307,10 +307,10 @@ proc setCookie*(name, value: string) =
var
gcookies {.threadvar.}: StringTableRef

proc getCookie*(name: string): TaintedString =
proc getCookie*(name: string): string =
## Gets a cookie. If no cookie of `name` exists, "" is returned.
if gcookies == nil: gcookies = parseCookies(getHttpCookie())
result = TaintedString(gcookies.getOrDefault(name))
result = gcookies.getOrDefault(name)

proc existsCookie*(name: string): bool =
## Checks if a cookie of `name` exists.
Expand Down
18 changes: 9 additions & 9 deletions lib/pure/includes/osenv.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ when not declared(os) and not declared(ospaths):
{.error: "This is an include file for os.nim!".}

when defined(nodejs):
proc getEnv*(key: string, default = ""): TaintedString {.tags: [ReadEnvEffect].} =
proc getEnv*(key: string, default = ""): string {.tags: [ReadEnvEffect].} =
var ret: cstring
let key2 = key.cstring
{.emit: "`ret` = process.env[`key2`];".}
Expand All @@ -25,7 +25,7 @@ when defined(nodejs):
var key2 = key.cstring
{.emit: "delete process.env[`key2`];".}

iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].} =
iterator envPairs*(): tuple[key, value: string] {.tags: [ReadEnvEffect].} =
var num: int
var keys: RootObj
{.emit: "`keys` = Object.keys(process.env); `num` = `keys`.length;".}
Expand Down Expand Up @@ -144,7 +144,7 @@ else:
if startsWith(environment[i], temp): return i
return -1

proc getEnv*(key: string, default = ""): TaintedString {.tags: [ReadEnvEffect].} =
proc getEnv*(key: string, default = ""): string {.tags: [ReadEnvEffect].} =
## Returns the value of the `environment variable`:idx: named `key`.
##
## If the variable does not exist, `""` is returned. To distinguish
Expand All @@ -165,11 +165,11 @@ else:
else:
var i = findEnvVar(key)
if i >= 0:
return TaintedString(substr(environment[i], find(environment[i], '=')+1))
return $(substr(environment[i], find(environment[i], '=')+1))
else:
var env = c_getenv(key)
if env == nil: return TaintedString(default)
result = TaintedString($env)
if env == nil: return default
result = $env

proc existsEnv*(key: string): bool {.tags: [ReadEnvEffect].} =
## Checks whether the environment variable named `key` exists.
Expand Down Expand Up @@ -248,7 +248,7 @@ else:
raiseOSError(osLastError())
environment.delete(indx)

iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].} =
iterator envPairs*(): tuple[key, value: string] {.tags: [ReadEnvEffect].} =
## Iterate over all `environments variables`:idx:.
##
## In the first component of the tuple is the name of the current variable stored,
Expand All @@ -262,5 +262,5 @@ else:
getEnvVarsC()
for i in 0..high(environment):
var p = find(environment[i], '=')
yield (TaintedString(substr(environment[i], 0, p-1)),
TaintedString(substr(environment[i], p+1)))
yield ($(substr(environment[i], 0, p-1)),
juancarlospaco marked this conversation as resolved.
Show resolved Hide resolved
$(substr(environment[i], p+1)))
12 changes: 6 additions & 6 deletions lib/pure/memfiles.nim
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,17 @@ iterator memSlices*(mfile: MemFile, delim = '\l', eat = '\r'): MemSlice {.inline
ms.data = cast[pointer](cast[int](ending) +% 1) # skip delim
remaining = mfile.size - (ms.data -! mfile.mem)

iterator lines*(mfile: MemFile, buf: var TaintedString, delim = '\l',
eat = '\r'): TaintedString {.inline.} =
iterator lines*(mfile: MemFile, buf: var string, delim = '\l',
eat = '\r'): string {.inline.} =
## Replace contents of passed buffer with each new line, like
## `readLine(File) <io.html#readLine,File,TaintedString>`_.
## `readLine(File) <io.html#readLine,File,string>`_.
## `delim`, `eat`, and delimiting logic is exactly as for `memSlices
## <#memSlices.i,MemFile,char,char>`_, but Nim strings are returned.
##
## Example:
##
## .. code-block:: nim
## var buffer: TaintedString = ""
## var buffer: string = ""
## for line in lines(memfiles.open("foo"), buffer):
## echo line

Expand All @@ -448,7 +448,7 @@ iterator lines*(mfile: MemFile, buf: var TaintedString, delim = '\l',
copyMem(addr string(buf)[0], ms.data, ms.size)
yield buf

iterator lines*(mfile: MemFile, delim = '\l', eat = '\r'): TaintedString {.inline.} =
iterator lines*(mfile: MemFile, delim = '\l', eat = '\r'): string {.inline.} =
## Return each line in a file as a Nim string, like
## `lines(File) <io.html#lines.i,File>`_.
## `delim`, `eat`, and delimiting logic is exactly as for `memSlices
Expand All @@ -460,7 +460,7 @@ iterator lines*(mfile: MemFile, delim = '\l', eat = '\r'): TaintedString {.inlin
## for line in lines(memfiles.open("foo")):
## echo line

var buf = TaintedString(newStringOfCap(80))
var buf = newStringOfCap(80)
for line in lines(mfile, buf, delim, eat):
yield buf

Expand Down
8 changes: 4 additions & 4 deletions lib/pure/net.nim
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ when defineSsl:
if sidCtx.len > 32:
raiseSSLError("sessionIdContext must be shorter than 32 characters")
SSL_CTX_set_session_id_context(ctx.context, sidCtx, sidCtx.len)

proc getSocketError*(socket: Socket): OSErrorCode =
## Checks ``osLastError`` for a valid error. If it has been reset it uses
## the last error stored in the socket object.
Expand Down Expand Up @@ -1490,7 +1490,7 @@ proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} =
return
result = recv(socket.fd, addr(c), 1, MSG_PEEK)

proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
proc readLine*(socket: Socket, line: var string, timeout = -1,
flags = {SocketFlag.SafeDisconn}, maxLength = MaxLineLength) {.
tags: [ReadIOEffect, TimeEffect].} =
## Reads a line of data from ``socket``.
Expand Down Expand Up @@ -1548,7 +1548,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,

proc recvLine*(socket: Socket, timeout = -1,
flags = {SocketFlag.SafeDisconn},
maxLength = MaxLineLength): TaintedString =
maxLength = MaxLineLength): string =
## Reads a line of data from ``socket``.
##
## If a full line is read ``\r\L`` is not
Expand All @@ -1566,7 +1566,7 @@ proc recvLine*(socket: Socket, timeout = -1,
## that can be read. The result is truncated after that.
##
## **Warning**: Only the ``SafeDisconn`` flag is currently supported.
result = "".TaintedString
result = ""
readLine(socket, result, timeout, flags, maxLength)

proc recvFrom*(socket: Socket, data: var string, length: int,
Expand Down
Loading