Deprecate TaintedString (#15423)

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>
This commit is contained in:
Juan Carlos
2021-01-15 23:56:38 -03:00
committed by GitHub
parent 7b632f9ccb
commit 78a99587a4
36 changed files with 184 additions and 229 deletions

View File

@@ -122,6 +122,8 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior.
- Added `--declaredlocs` to show symbol declaration location in messages.
- Deprecated `TaintedString` and `--taintmode`.
- Source+Edit links now appear on top of every docgen'd page when
`nim doc --git.url:url ...` is given.

View File

@@ -312,7 +312,7 @@ 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)
of "taintmode": result = contains(conf.globalOptions, optTaintMode)
of "taintmode": result = false # pending https://github.com/nim-lang/Nim/issues/16731
of "tlsemulation": result = contains(conf.globalOptions, optTlsEmulation)
of "implicitstatic": result = contains(conf.options, optImplicitStatic)
of "patterns", "trmacros": result = contains(conf.options, optTrMacros)
@@ -670,7 +670,7 @@ 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)
of "taintmode": processOnOffSwitchG(conf, {optTaintMode}, arg, pass, info)
of "taintmode": discard # pending https://github.com/nim-lang/Nim/issues/16731
of "implicitstatic":
processOnOffSwitch(conf, {optImplicitStatic}, arg, pass, info)
of "patterns", "trmacros":

View File

@@ -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

View File

@@ -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

View File

@@ -329,7 +329,7 @@ skLet
let
text = "some text"
--> col 2: $MODULE.text
col 3: TaintedString
col 3: string
col 7: ""

View File

@@ -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
==========================================

View File

@@ -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
@@ -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
@@ -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.

View File

@@ -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.
@@ -40,35 +40,35 @@ 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)
if result.string.len > 0:
result = $buffer
if result.len > 0:
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)
line.setLen(0)
return false
line = TaintedString($buffer)
if line.string.len > 0:
line = $buffer
if line.len > 0:
historyAdd(buffer)
linenoise.free(buffer)
result = true

View File

@@ -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.
@@ -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.
##
@@ -158,9 +158,9 @@ 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
if received.startsWith(i): return
raise newException(ReplyError,
"Expected reply '$1' got: $2" %
[expected.join("' or '"), received.string])
@@ -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")).strip
assertReply(pasvMsg, "227")
var betweenParens = captureBetween(pasvMsg.string, '(', ')')
var nums = betweenParens.split(',')
@@ -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.captureBetween('"') # "
proc cd*(ftp: AsyncFtpClient, dir: string) {.async.} =
## Changes the current directory on the remote FTP server to ``dir``.
@@ -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 != "":

View File

@@ -81,14 +81,14 @@ 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.
for (key, value) in uri.decodeQuery(data):
yield (key, value)
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.
@@ -301,10 +301,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.

View File

@@ -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`];".}
@@ -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;".}
@@ -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
@@ -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.
@@ -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,
@@ -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),
substr(environment[i], p+1))

View File

@@ -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
@@ -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
@@ -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

View File

@@ -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.
@@ -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``.
@@ -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
@@ -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,

View File

@@ -2670,7 +2670,7 @@ when defined(nimdoc):
## else:
## # Do something else!
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
proc paramStr*(i: int): string {.tags: [ReadIOEffect].} =
## Returns the `i`-th `command line argument`:idx: given to the application.
##
## `i` should be in the range `1..paramCount()`, the `IndexDefect`
@@ -2704,7 +2704,7 @@ when defined(nimdoc):
elif defined(nimscript): discard
elif defined(nintendoswitch) or weirdTarget:
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
proc paramStr*(i: int): string {.tags: [ReadIOEffect].} =
raise newException(OSError, "paramStr is not implemented on Nintendo Switch")
proc paramCount*(): int {.tags: [ReadIOEffect].} =
@@ -2727,17 +2727,17 @@ elif defined(windows):
ownParsedArgv = true
result = ownArgv.len-1
proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1",
proc paramStr*(i: int): string {.rtl, extern: "nos$1",
tags: [ReadIOEffect].} =
# Docstring in nimdoc block.
if not ownParsedArgv:
ownArgv = parseCmdLine($getCommandLine())
ownParsedArgv = true
if i < ownArgv.len and i >= 0: return TaintedString(ownArgv[i])
if i < ownArgv.len and i >= 0: return ownArgv[i]
raise newException(IndexDefect, formatErrorIndexBound(i, ownArgv.len-1))
elif defined(genode):
proc paramStr*(i: int): TaintedString =
proc paramStr*(i: int): string =
raise newException(OSError, "paramStr is not implemented on Genode")
proc paramCount*(): int =
@@ -2750,9 +2750,9 @@ elif not defined(createNimRtl) and
cmdCount {.importc: "cmdCount".}: cint
cmdLine {.importc: "cmdLine".}: cstringArray
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
proc paramStr*(i: int): string {.tags: [ReadIOEffect].} =
# Docstring in nimdoc block.
if i < cmdCount and i >= 0: return TaintedString($cmdLine[i])
if i < cmdCount and i >= 0: return $cmdLine[i]
raise newException(IndexDefect, formatErrorIndexBound(i, cmdCount-1))
proc paramCount*(): int {.tags: [ReadIOEffect].} =
@@ -2760,7 +2760,7 @@ elif not defined(createNimRtl) and
result = cmdCount-1
when declared(paramCount) or defined(nimdoc):
proc commandLineParams*(): seq[TaintedString] =
proc commandLineParams*(): seq[string] =
## Convenience proc which returns the command line parameters.
##
## This returns **only** the parameters. If you want to get the application
@@ -2789,7 +2789,7 @@ when declared(paramCount) or defined(nimdoc):
for i in 1..paramCount():
result.add(paramStr(i))
else:
proc commandLineParams*(): seq[TaintedString] {.error:
proc commandLineParams*(): seq[string] {.error:
"commandLineParams() unsupported by dynamic libraries".} =
discard

View File

@@ -75,7 +75,7 @@ const poDemon* {.deprecated.} = poDaemon ## Nim versions before 0.20
proc execProcess*(command: string, workingDir: string = "",
args: openArray[string] = [], env: StringTableRef = nil,
options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}):
TaintedString {.rtl, extern: "nosp$1",
string {.rtl, extern: "nosp$1",
tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
## A convenience procedure that executes ``command`` with ``startProcess``
## and returns its output as a string.
@@ -504,13 +504,13 @@ when not defined(useNimRtl):
args: openArray[string] = [], env: StringTableRef = nil,
options: set[ProcessOption] = {poStdErrToStdOut, poUsePath,
poEvalCommand}):
TaintedString =
string =
var p = startProcess(command, workingDir = workingDir, args = args,
env = env, options = options)
var outp = outputStream(p)
result = TaintedString""
var line = newStringOfCap(120).TaintedString
result = ""
var line = newStringOfCap(120)
while true:
# FIXME: converts CR-LF to LF.
if outp.readLine(line):
@@ -1572,7 +1572,7 @@ elif not defined(useNimRtl):
proc execCmdEx*(command: string, options: set[ProcessOption] = {
poStdErrToStdOut, poUsePath}, env: StringTableRef = nil,
workingDir = "", input = ""): tuple[
output: TaintedString,
output: string,
exitCode: int] {.tags:
[ExecIOEffect, ReadIOEffect, RootEffect], gcsafe.} =
## A convenience proc that runs the `command`, and returns its `output` and
@@ -1619,8 +1619,8 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = {
inputStream(p).write(input)
close inputStream(p)
result = (TaintedString"", -1)
var line = newStringOfCap(120).TaintedString
result = ("", -1)
var line = newStringOfCap(120)
while true:
if outp.readLine(line):
result[0].string.add(line.string)

View File

@@ -172,7 +172,7 @@ type
cmds: seq[string]
idx: int
kind*: CmdLineKind ## The detected command line token
key*, val*: TaintedString ## Key and value pair; the key is the option
key*, val*: string ## Key and value pair; the key is the option
## or the argument, and the value is not "" if
## the option was given a value
@@ -231,10 +231,10 @@ when declared(os.paramCount):
result.cmds[i-1] = os.paramStr(i).string
result.kind = cmdEnd
result.key = TaintedString""
result.val = TaintedString""
result.key = ""
result.val = ""
proc initOptParser*(cmdline: seq[TaintedString], shortNoVal: set[char] = {},
proc initOptParser*(cmdline: seq[string], shortNoVal: set[char] = {},
longNoVal: seq[string] = @[];
allowWhitespaceAfterColon = true): OptParser =
## Initializes the command line parser.
@@ -245,7 +245,7 @@ when declared(os.paramCount):
## <#initOptParser,string,set[char],seq[string]>`_.
##
## See also:
## * `getopt iterator<#getopt.i,seq[TaintedString],set[char],seq[string]>`_
## * `getopt iterator<#getopt.i,seq[string],set[char],seq[string]>`_
runnableExamples:
var p = initOptParser()
p = initOptParser(@["--left", "--debug:3", "-l", "-r:2"])
@@ -267,8 +267,8 @@ when declared(os.paramCount):
for i in countup(1, os.paramCount()):
result.cmds[i-1] = os.paramStr(i).string
result.kind = cmdEnd
result.key = TaintedString""
result.val = TaintedString""
result.key = ""
result.val = ""
proc handleShortOption(p: var OptParser; cmd: string) =
var i = p.pos
@@ -286,7 +286,7 @@ proc handleShortOption(p: var OptParser; cmd: string) =
inc(i)
p.inShortState = false
while i < cmd.len and cmd[i] in {'\t', ' '}: inc(i)
p.val = TaintedString substr(cmd, i)
p.val = substr(cmd, i)
p.pos = 0
inc p.idx
else:
@@ -349,12 +349,12 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
inc p.idx
i = 0
if p.idx < p.cmds.len:
p.val = TaintedString p.cmds[p.idx].substr(i)
p.val = p.cmds[p.idx].substr(i)
elif len(p.longNoVal) > 0 and p.key.string notin p.longNoVal and p.idx+1 < p.cmds.len:
p.val = TaintedString p.cmds[p.idx+1]
p.val = p.cmds[p.idx+1]
inc p.idx
else:
p.val = TaintedString""
p.val = ""
inc p.idx
p.pos = 0
else:
@@ -362,11 +362,11 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
handleShortOption(p, p.cmds[p.idx])
else:
p.kind = cmdArgument
p.key = TaintedString p.cmds[p.idx]
p.key = p.cmds[p.idx]
inc p.idx
p.pos = 0
proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} =
proc cmdLineRest*(p: OptParser): string {.rtl, extern: "npo$1".} =
## Retrieves the rest of the command line that has not been parsed yet.
##
## See also:
@@ -382,9 +382,9 @@ proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} =
## break
## else: continue
## doAssert p.cmdLineRest == "foo.txt bar.txt"
result = p.cmds[p.idx .. ^1].quoteShellCommand.TaintedString
result = p.cmds[p.idx .. ^1].quoteShellCommand
proc remainingArgs*(p: OptParser): seq[TaintedString] {.rtl, extern: "npo$1".} =
proc remainingArgs*(p: OptParser): seq[string] {.rtl, extern: "npo$1".} =
## Retrieves a sequence of the arguments that have not been parsed yet.
##
## See also:
@@ -401,10 +401,10 @@ proc remainingArgs*(p: OptParser): seq[TaintedString] {.rtl, extern: "npo$1".} =
## else: continue
## doAssert p.remainingArgs == @["foo.txt", "bar.txt"]
result = @[]
for i in p.idx..<p.cmds.len: result.add TaintedString(p.cmds[i])
for i in p.idx..<p.cmds.len: result.add p.cmds[i]
iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key,
val: TaintedString] =
val: string] =
## Convenience iterator for iterating over the given
## `OptParser<#OptParser>`_.
##
@@ -443,9 +443,9 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key,
yield (p.kind, p.key, p.val)
when declared(initOptParser):
iterator getopt*(cmdline: seq[TaintedString] = commandLineParams(),
iterator getopt*(cmdline: seq[string] = commandLineParams(),
shortNoVal: set[char] = {}, longNoVal: seq[string] = @[]):
tuple[kind: CmdLineKind, key, val: TaintedString] =
tuple[kind: CmdLineKind, key, val: string] =
## Convenience iterator for iterating over command line arguments.
##
## This creates a new `OptParser<#OptParser>`_. If no command line
@@ -460,7 +460,7 @@ when declared(initOptParser):
## There is no need to check for ``cmdEnd`` while iterating.
##
## See also:
## * `initOptParser proc<#initOptParser,seq[TaintedString],set[char],seq[string]>`_
## * `initOptParser proc<#initOptParser,seq[string],set[char],seq[string]>`_
##
## **Examples:**
##

View File

@@ -86,7 +86,7 @@ proc debugSend*(smtp: Smtp | AsyncSmtp, cmd: string) {.multisync.} =
echo("C:" & cmd)
await smtp.sock.send(cmd)
proc debugRecv*(smtp: Smtp | AsyncSmtp): Future[TaintedString] {.multisync.} =
proc debugRecv*(smtp: Smtp | AsyncSmtp): Future[string] {.multisync.} =
## Receives a line of data from the socket connected to the
## SMTP server.
##

View File

@@ -96,8 +96,6 @@
import std/private/since
const taintMode = compileOption("taintmode")
proc newEIO(msg: string): owned(ref IOError) =
new(result)
result.msg = msg
@@ -124,7 +122,7 @@ type
readDataStrImpl*: proc (s: Stream, buffer: var string, slice: Slice[int]): int
{.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
readLineImpl*: proc(s: Stream, line: var TaintedString): bool
readLineImpl*: proc(s: Stream, line: var string): bool
{.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
readDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int
@@ -216,7 +214,7 @@ proc getPosition*(s: Stream): int =
proc readData*(s: Stream, buffer: pointer, bufLen: int): int =
## Low level proc that reads data into an untyped `buffer` of `bufLen` size.
##
##
## **JS note:** `buffer` is treated as a ``ptr string`` and written to between
## ``0..<bufLen``.
runnableExamples:
@@ -293,7 +291,7 @@ when (NimMajor, NimMinor) >= (1, 3) or not defined(js):
proc peekData*(s: Stream, buffer: pointer, bufLen: int): int =
## Low level proc that reads data into an untyped `buffer` of `bufLen` size
## without moving stream position.
##
##
## **JS note:** `buffer` is treated as a ``ptr string`` and written to between
## ``0..<bufLen``.
runnableExamples:
@@ -309,7 +307,7 @@ proc peekData*(s: Stream, buffer: pointer, bufLen: int): int =
proc writeData*(s: Stream, buffer: pointer, bufLen: int) =
## Low level proc that writes an untyped `buffer` of `bufLen` size
## to the stream `s`.
##
##
## **JS note:** `buffer` is treated as a ``ptr string`` and read between
## ``0..<bufLen``.
runnableExamples:
@@ -921,26 +919,20 @@ proc peekFloat64*(s: Stream): float64 =
peek(s, result)
template untaint(s: var TaintedString): var string =
when taintMode: # for VM, bug #12282
s.string
else:
s
proc readStrPrivate(s: Stream, length: int, str: var TaintedString) =
if length > len(str): setLen(str.untaint, length)
proc readStrPrivate(s: Stream, length: int, str: var string) =
if length > len(str): setLen(str, length)
when defined(js):
let L = readData(s, addr(str), length)
else:
let L = readData(s, cstring(str.string), length)
if L != len(str): setLen(str.untaint, L)
if L != len(str): setLen(str, L)
proc readStr*(s: Stream, length: int, str: var TaintedString) {.since: (1, 3).} =
proc readStr*(s: Stream, length: int, str: var string) {.since: (1, 3).} =
## Reads a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
readStrPrivate(s, length, str)
proc readStr*(s: Stream, length: int): TaintedString =
proc readStr*(s: Stream, length: int): string =
## Reads a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
runnableExamples:
@@ -950,23 +942,23 @@ proc readStr*(s: Stream, length: int): TaintedString =
doAssert strm.readStr(2) == "e"
doAssert strm.readStr(2) == ""
strm.close()
result = newString(length).TaintedString
result = newString(length)
readStrPrivate(s, length, result)
proc peekStrPrivate(s: Stream, length: int, str: var TaintedString) =
if length > len(str): setLen(str.untaint, length)
proc peekStrPrivate(s: Stream, length: int, str: var string) =
if length > len(str): setLen(str, length)
when defined(js):
let L = peekData(s, addr(str), length)
else:
let L = peekData(s, cstring(str.string), length)
if L != len(str): setLen(str.untaint, L)
if L != len(str): setLen(str, L)
proc peekStr*(s: Stream, length: int, str: var TaintedString) {.since: (1, 3).} =
proc peekStr*(s: Stream, length: int, str: var string) {.since: (1, 3).} =
## Peeks a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
peekStrPrivate(s, length, str)
proc peekStr*(s: Stream, length: int): TaintedString =
proc peekStr*(s: Stream, length: int): string =
## Peeks a string of length `length` from the stream `s`. Raises `IOError` if
## an error occurred.
runnableExamples:
@@ -977,10 +969,10 @@ proc peekStr*(s: Stream, length: int): TaintedString =
doAssert strm.readStr(2) == "ab"
doAssert strm.peekStr(2) == "cd"
strm.close()
result = newString(length).TaintedString
result = newString(length)
peekStrPrivate(s, length, result)
proc readLine*(s: Stream, line: var TaintedString): bool =
proc readLine*(s: Stream, line: var string): bool =
## Reads a line of text from the stream `s` into `line`. `line` must not be
## ``nil``! May throw an IO exception.
##
@@ -992,7 +984,7 @@ proc readLine*(s: Stream, line: var TaintedString): bool =
## See also:
## * `readLine(Stream) proc <#readLine,Stream>`_
## * `peekLine(Stream) proc <#peekLine,Stream>`_
## * `peekLine(Stream, TaintedString) proc <#peekLine,Stream,TaintedString>`_
## * `peekLine(Stream, string) proc <#peekLine,Stream,string>`_
runnableExamples:
var strm = newStringStream("The first line\nthe second line\nthe third line")
var line = ""
@@ -1010,7 +1002,7 @@ proc readLine*(s: Stream, line: var TaintedString): bool =
result = s.readLineImpl(s, line)
else:
# fallback
line.untaint.setLen(0)
line.setLen(0)
while true:
var c = readChar(s)
if c == '\c':
@@ -1020,10 +1012,10 @@ proc readLine*(s: Stream, line: var TaintedString): bool =
elif c == '\0':
if line.len > 0: break
else: return false
line.untaint.add(c)
line.add(c)
result = true
proc peekLine*(s: Stream, line: var TaintedString): bool =
proc peekLine*(s: Stream, line: var string): bool =
## Peeks a line of text from the stream `s` into `line`. `line` must not be
## ``nil``! May throw an IO exception.
##
@@ -1034,7 +1026,7 @@ proc peekLine*(s: Stream, line: var TaintedString): bool =
##
## See also:
## * `readLine(Stream) proc <#readLine,Stream>`_
## * `readLine(Stream, TaintedString) proc <#readLine,Stream,TaintedString>`_
## * `readLine(Stream, string) proc <#readLine,Stream,string>`_
## * `peekLine(Stream) proc <#peekLine,Stream>`_
runnableExamples:
var strm = newStringStream("The first line\nthe second line\nthe third line")
@@ -1054,15 +1046,15 @@ proc peekLine*(s: Stream, line: var TaintedString): bool =
defer: setPosition(s, pos)
result = readLine(s, line)
proc readLine*(s: Stream): TaintedString =
proc readLine*(s: Stream): string =
## Reads a line from a stream `s`. Raises `IOError` if an error occurred.
##
## **Note:** This is not very efficient.
##
## See also:
## * `readLine(Stream, TaintedString) proc <#readLine,Stream,TaintedString>`_
## * `readLine(Stream, string) proc <#readLine,Stream,string>`_
## * `peekLine(Stream) proc <#peekLine,Stream>`_
## * `peekLine(Stream, TaintedString) proc <#peekLine,Stream,TaintedString>`_
## * `peekLine(Stream, string) proc <#peekLine,Stream,string>`_
runnableExamples:
var strm = newStringStream("The first line\nthe second line\nthe third line")
doAssert strm.readLine() == "The first line"
@@ -1071,7 +1063,7 @@ proc readLine*(s: Stream): TaintedString =
doAssertRaises(IOError): discard strm.readLine()
strm.close()
result = TaintedString""
result = ""
if s.atEnd:
raise newEIO("cannot read from stream")
while true:
@@ -1082,17 +1074,17 @@ proc readLine*(s: Stream): TaintedString =
if c == '\L' or c == '\0':
break
else:
result.untaint.add(c)
result.add(c)
proc peekLine*(s: Stream): TaintedString =
proc peekLine*(s: Stream): string =
## Peeks a line from a stream `s`. Raises `IOError` if an error occurred.
##
## **Note:** This is not very efficient.
##
## See also:
## * `readLine(Stream) proc <#readLine,Stream>`_
## * `readLine(Stream, TaintedString) proc <#readLine,Stream,TaintedString>`_
## * `peekLine(Stream, TaintedString) proc <#peekLine,Stream,TaintedString>`_
## * `readLine(Stream, string) proc <#readLine,Stream,string>`_
## * `peekLine(Stream, string) proc <#peekLine,Stream,string>`_
runnableExamples:
var strm = newStringStream("The first line\nthe second line\nthe third line")
doAssert strm.peekLine() == "The first line"
@@ -1106,13 +1098,13 @@ proc peekLine*(s: Stream): TaintedString =
defer: setPosition(s, pos)
result = readLine(s)
iterator lines*(s: Stream): TaintedString =
iterator lines*(s: Stream): string =
## Iterates over every line in the stream.
## The iteration is based on ``readLine``.
##
## See also:
## * `readLine(Stream) proc <#readLine,Stream>`_
## * `readLine(Stream, TaintedString) proc <#readLine,Stream,TaintedString>`_
## * `readLine(Stream, string) proc <#readLine,Stream,string>`_
runnableExamples:
var strm = newStringStream("The first line\nthe second line\nthe third line")
var lines: seq[string]
@@ -1121,7 +1113,7 @@ iterator lines*(s: Stream): TaintedString =
doAssert lines == @["The first line", "the second line", "the third line"]
strm.close()
var line: TaintedString
var line: string
while s.readLine(line):
yield line
@@ -1187,7 +1179,7 @@ when (NimMajor, NimMinor) < (1, 3) and defined(js):
if readBytes < bufferSize:
break
else: # after 1.3 or JS not defined
else: # after 1.3 or JS not defined
proc ssAtEnd(s: Stream): bool =
var s = StringStream(s)
return s.pos >= s.data.len
@@ -1333,7 +1325,7 @@ proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) =
if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen:
raise newEIO("cannot write to stream")
proc fsReadLine(s: Stream, line: var TaintedString): bool =
proc fsReadLine(s: Stream, line: var string): bool =
result = readLine(FileStream(s).f, line)
proc newFileStream*(f: File): owned FileStream =

View File

@@ -26,7 +26,7 @@ type
baseReadLineImpl: typeof(StreamObj.readLineImpl)
baseReadDataImpl: typeof(StreamObj.readDataImpl)
proc posReadLine[T](s: Stream, line: var TaintedString): bool =
proc posReadLine[T](s: Stream, line: var string): bool =
var s = PipeOutStream[T](s)
assert s.baseReadLineImpl != nil

View File

@@ -771,7 +771,7 @@ proc getch*(): char =
when defined(windows):
from unicode import toUTF8, Rune, runeLenAt
proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
proc readPasswordFromStdin*(prompt: string, password: var string):
bool {.tags: [ReadIOEffect, WriteIOEffect].} =
## Reads a `password` from stdin without printing it. `password` must not
## be ``nil``! Returns ``false`` if the end of the file has been reached,
@@ -797,7 +797,7 @@ when defined(windows):
else:
import termios
proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
proc readPasswordFromStdin*(prompt: string, password: var string):
bool {.tags: [ReadIOEffect, WriteIOEffect].} =
password.string.setLen(0)
let fd = stdin.getFileHandle()
@@ -811,9 +811,9 @@ else:
stdout.write "\n"
discard fd.tcSetAttr(TCSADRAIN, old.addr)
proc readPasswordFromStdin*(prompt = "password: "): TaintedString =
proc readPasswordFromStdin*(prompt = "password: "): string =
## Reads a password from stdin without printing it.
result = TaintedString("")
result = ""
discard readPasswordFromStdin(prompt, result)

View File

@@ -160,7 +160,7 @@ func encodeQuery*(query: openArray[(string, string)], usePlus = true,
result.add('=')
result.add(encodeUrl(val, usePlus))
iterator decodeQuery*(data: string): tuple[key, value: TaintedString] =
iterator decodeQuery*(data: string): tuple[key, value: string] =
## Reads and decodes query string `data` and yields the `(key, value)` pairs
## the data consists of. If compiled with `-d:nimLegacyParseQueryStrict`, an
## error is raised when there is an unencoded `=` character in a decoded
@@ -197,7 +197,7 @@ iterator decodeQuery*(data: string): tuple[key, value: TaintedString] =
i = parseData(data, i, value, '=')
else:
i = parseData(data, i, value, '&')
yield (name.TaintedString, value.TaintedString)
yield (name, value)
if i < data.len:
when defined(nimLegacyParseQueryStrict):
if data[i] != '&':

View File

@@ -1084,7 +1084,6 @@ const
const
hasThreadSupport = compileOption("threads") and not defined(nimscript)
hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own
taintMode = compileOption("taintmode")
nimEnableCovariance* = defined(nimEnableCovariance) # or true
when hasThreadSupport and defined(tcc) and not compileOption("tlsEmulation"):
@@ -1107,22 +1106,8 @@ when defined(boehmgc):
const boehmLib = "libgc.so.1"
{.pragma: boehmGC, noconv, dynlib: boehmLib.}
when taintMode:
type TaintedString* = distinct string ## A distinct string type that
## is `tainted`:idx:, see `taint mode
## <manual_experimental.html#taint-mode>`_
## for details. It is an alias for
## ``string`` if the taint mode is not
## turned on.
type TaintedString* {.deprecated: "Deprecated since 1.5".} = string
proc len*(s: TaintedString): int {.borrow.}
else:
type TaintedString* = string ## A distinct string type that
## is `tainted`:idx:, see `taint mode
## <manual_experimental.html#taint-mode>`_
## for details. It is an alias for
## ``string`` if the taint mode is not
## turned on.
when defined(profiler) and not defined(nimscript):
proc nimProfile() {.compilerproc, noinline.}

View File

@@ -358,7 +358,7 @@ when defined(nimdoc) or (defined(posix) and not defined(nimscript)) or defined(w
result = setHandleInformation(cast[IoHandle](f), HANDLE_FLAG_INHERIT,
inheritable.WinDWORD) != 0
proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
benign.} =
## reads a line of text from the file `f` into `line`. May throw an IO
## exception.
@@ -420,15 +420,15 @@ proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
if buffer[i].uint16 == 26: #Ctrl+Z
close(f) #has the same effect as setting EOF
if i == 0:
line = TaintedString("")
line = ""
return false
numberOfCharsRead = i
break
buffer[numberOfCharsRead] = 0.Utf16Char
when defined(nimv2):
line = TaintedString($toWideCString(buffer))
line = $toWideCString(buffer)
else:
line = TaintedString($buffer)
line = $buffer
return(true)
var pos = 0
@@ -479,11 +479,11 @@ proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
sp = 128 # read in 128 bytes at a time
line.string.setLen(pos+sp)
proc readLine*(f: File): TaintedString {.tags: [ReadIOEffect], benign.} =
proc readLine*(f: File): string {.tags: [ReadIOEffect], benign.} =
## reads a line of text from the file `f`. May throw an IO exception.
## A line of text may be delimited by ``LF`` or ``CRLF``. The newline
## character(s) are not part of the returned string.
result = TaintedString(newStringOfCap(80))
result = newStringOfCap(80)
if not readLine(f, result): raiseEOF()
proc write*(f: File, i: int) {.tags: [WriteIOEffect], benign.} =
@@ -563,7 +563,7 @@ proc readAllFile(file: File): string =
var len = rawFileSize(file)
result = readAllFile(file, len)
proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], benign.} =
proc readAll*(file: File): string {.tags: [ReadIOEffect], benign.} =
## Reads all data from the stream `file`.
##
## Raises an IO exception in case of an error. It is an error if the
@@ -576,9 +576,9 @@ proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], benign.} =
else:
let len = rawFileSize(file)
if len > 0:
result = readAllFile(file, len).TaintedString
result = readAllFile(file, len)
else:
result = readAllBuffer(file).TaintedString
result = readAllBuffer(file)
proc writeLine*[Ty](f: File, x: varargs[Ty, `$`]) {.inline,
tags: [WriteIOEffect], benign.} =
@@ -841,7 +841,7 @@ when defined(windows) and appType == "console" and
discard setConsoleOutputCP(Utf8codepage)
discard setConsoleCP(Utf8codepage)
proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.} =
proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.} =
## Opens a file named `filename` for reading, calls `readAll
## <#readAll,File>`_ and closes the file afterwards. Returns the string.
## Raises an IO exception in case of an error. If you need to call
@@ -882,7 +882,7 @@ proc writeFile*(filename: string, content: openArray[byte]) {.since: (1, 1).} =
else:
raise newException(IOError, "cannot open: " & filename)
proc readLines*(filename: string, n: Natural): seq[TaintedString] =
proc readLines*(filename: string, n: Natural): seq[string] =
## read `n` lines from the file named `filename`. Raises an IO exception
## in case of an error. Raises EOF if file does not contain at least `n` lines.
## Available at compile time. A line of text may be delimited by ``LF`` or ``CRLF``.
@@ -890,7 +890,7 @@ proc readLines*(filename: string, n: Natural): seq[TaintedString] =
var f: File = nil
if open(f, filename):
try:
result = newSeq[TaintedString](n)
result = newSeq[string](n)
for i in 0 .. n - 1:
if not readLine(f, result[i]):
raiseEOF()
@@ -899,10 +899,10 @@ proc readLines*(filename: string, n: Natural): seq[TaintedString] =
else:
sysFatal(IOError, "cannot open: " & filename)
template readLines*(filename: string): seq[TaintedString] {.deprecated: "use readLines with two arguments".} =
template readLines*(filename: string): seq[string] {.deprecated: "use readLines with two arguments".} =
readLines(filename, 1)
iterator lines*(filename: string): TaintedString {.tags: [ReadIOEffect].} =
iterator lines*(filename: string): string {.tags: [ReadIOEffect].} =
## Iterates over any line in the file named `filename`.
##
## If the file does not exist `IOError` is raised. The trailing newline
@@ -918,12 +918,12 @@ iterator lines*(filename: string): TaintedString {.tags: [ReadIOEffect].} =
## writeFile(filename, buffer)
var f = open(filename, bufSize=8000)
try:
var res = TaintedString(newStringOfCap(80))
var res = newStringOfCap(80)
while f.readLine(res): yield res
finally:
close(f)
iterator lines*(f: File): TaintedString {.tags: [ReadIOEffect].} =
iterator lines*(f: File): string {.tags: [ReadIOEffect].} =
## Iterate over any line in the file `f`.
##
## The trailing newline character(s) are removed from the iterated lines.
@@ -936,5 +936,5 @@ iterator lines*(f: File): TaintedString {.tags: [ReadIOEffect].} =
## if letter == '0':
## result.zeros += 1
## result.lines += 1
var res = TaintedString(newStringOfCap(80))
var res = newStringOfCap(80)
while f.readLine(res): yield res

View File

@@ -360,21 +360,21 @@ proc cppDefine*(define: string) =
## needs to be mangled.
builtin
proc stdinReadLine(): TaintedString {.
proc stdinReadLine(): string {.
tags: [ReadIOEffect], raises: [IOError].} =
builtin
proc stdinReadAll(): TaintedString {.
proc stdinReadAll(): string {.
tags: [ReadIOEffect], raises: [IOError].} =
builtin
proc readLineFromStdin*(): TaintedString {.raises: [IOError].} =
proc readLineFromStdin*(): string {.raises: [IOError].} =
## Reads a line of data from stdin - blocks until \n or EOF which happens when stdin is closed
log "readLineFromStdin":
result = stdinReadLine()
checkError(EOFError)
proc readAllFromStdin*(): TaintedString {.raises: [IOError].} =
proc readAllFromStdin*(): string {.raises: [IOError].} =
## Reads all data from stdin - blocks until EOF which happens when stdin is closed
log "readAllFromStdin":
result = stdinReadAll()

View File

@@ -319,7 +319,7 @@ proc replTcp(x: ThreadParams) {.thread.} =
else:
server.bindAddr(x.port, x.address)
server.listen()
var inp = "".TaintedString
var inp = ""
var stdoutSocket: Socket
while true:
accept(server, stdoutSocket)

View File

@@ -62,7 +62,7 @@ proc doCaasCommand(session: var NimSession, command: string): string =
result = ""
while true:
var line = TaintedString("")
var line = ""
if session.nim.outputStream.readLine(line):
if line.string == "": break
result.add(line.string & "\n")
@@ -78,7 +78,7 @@ proc doProcCommand(session: var NimSession, command: string): string =
var
process = startProcess(NimBin, args = session.replaceVars(command).split)
stream = outputStream(process)
line = TaintedString("")
line = ""
result = ""
while stream.readLine(line):
@@ -113,12 +113,12 @@ proc doScenario(script: string, output: Stream, mode: TRunMode, verbose: bool):
result = true
var f = open(script)
var project = TaintedString("")
var project = ""
if f.readLine(project):
var
s = startNimSession(script.parentDir / project.string, script, mode)
tline = TaintedString("")
tline = ""
ln = 1
while f.readLine(tline):

View File

@@ -102,7 +102,7 @@ proc getFileDir(filename: string): string =
proc execCmdEx2(command: string, args: openArray[string]; workingDir, input: string = ""): tuple[
cmdLine: string,
output: TaintedString,
output: string,
exitCode: int] {.tags:
[ExecIOEffect, ReadIOEffect, RootEffect], gcsafe.} =
@@ -122,7 +122,7 @@ proc execCmdEx2(command: string, args: openArray[string]; workingDir, input: str
close instream
result.exitCode = -1
var line = newStringOfCap(120).TaintedString
var line = newStringOfCap(120)
while true:
if outp.readLine(line):
result.output.string.add(line.string)
@@ -161,7 +161,7 @@ proc callCompiler(cmdTemplate, filename, options, nimcache: string,
var x = newStringOfCap(120)
result.nimout = ""
while true:
if outp.readLine(x.TaintedString):
if outp.readLine(x):
result.nimout.add(x & "\n")
if x =~ pegOfInterest:
# `err` should contain the last error/warning message
@@ -210,7 +210,7 @@ proc callCCompiler(cmdTemplate, filename, options: string,
result.output = ""
result.line = -1
while true:
if outp.readLine(x.TaintedString):
if outp.readLine(x):
result.nimout.add(x & "\n")
elif not running(p):
break

View File

@@ -28,7 +28,7 @@ block :tmp:
try:
var res
try:
res = TaintedString(newStringOfCap(80))
res = newStringOfCap(80)
block :tmp_1:
while readLine(f, res):
x_cursor = res

View File

@@ -774,13 +774,13 @@ block: # issue #9458
Option[T] = object
val: T
has: bool
Bar = object
proc none(T: typedesc): Option[T] =
discard
proc foo[T](self: T; x: Option[Bar] = Bar.none) =
proc foo[T](self: T; x: Option[Bar] = Bar.none) =
discard
foo(1)
@@ -834,7 +834,7 @@ proc getBar(x: string): Bar =
Bar(foo: none[seq[Foo]](),
s: "")
proc fakeReadLine(): TaintedString = "hey"
proc fakeReadLine(): string = "hey"
echo getBar(fakeReadLine()) # causes error

View File

@@ -98,7 +98,7 @@ proc unused =
iterator lineIter2*(filename: string): string {.closure.} =
var f = open(filename, bufSize=8000)
defer: close(f) # <-- commenting defer "solves" the problem
var res = TaintedString(newStringOfCap(80))
var res = newStringOfCap(80)
while f.readLine(res): yield res
proc unusedB =

View File

@@ -225,7 +225,7 @@ template raise_or_quit(exception, message: untyped) =
template run_custom_proc(parsed_parameter: Tparsed_parameter,
custom_validator: Tparameter_callback,
parameter: TaintedString) =
parameter: string) =
## Runs the custom validator if it is not nil.
##
## Pass in the string of the parameter triggering the call. If the
@@ -318,7 +318,7 @@ proc echo_help*(expected: seq[Tparameter_specification] = @[],
proc parse*(expected: seq[Tparameter_specification] = @[],
type_of_positional_parameters = PK_STRING, args: seq[TaintedString] = @[],
type_of_positional_parameters = PK_STRING, args: seq[string] = @[],
bad_prefixes = @["-", "--"], end_of_options = "--",
quit_on_failure = true): Tcommandline_results =
## Parses parameters and returns results.

View File

@@ -1,7 +1,7 @@
import streams
from strutils import repeat
proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): TaintedString =
proc readPaddedStr*(s: PStream, length: int, padChar = '\0'): string =
var lastChr = length
result = s.readStr(length)
while lastChr >= 0 and result[lastChr - 1] == padChar: dec(lastChr)
@@ -16,7 +16,7 @@ proc writePaddedStr*(s: PStream, str: string, length: int, padChar = '\0') =
else:
s.write(str)
proc readLEStr*(s: PStream): TaintedString =
proc readLEStr*(s: PStream): string =
var len = s.readInt16()
result = s.readStr(len)

View File

@@ -5,7 +5,7 @@ disabled: "appveyor"
import memfiles
var inp = memfiles.open("tests/stdlib/tmemlinesBuf.nim")
var buffer: TaintedString = ""
var buffer: string = ""
var lineCount = 0
for line in lines(inp, buffer):
lineCount += 1

View File

@@ -195,15 +195,15 @@ else: # main driver
# bugfix: windows stdin.close was a noop and led to blocking reads
proc startProcessTest(command: string, options: set[ProcessOption] = {
poStdErrToStdOut, poUsePath}, input = ""): tuple[
output: TaintedString,
output: string,
exitCode: int] {.tags:
[ExecIOEffect, ReadIOEffect, RootEffect], gcsafe.} =
var p = startProcess(command, options = options + {poEvalCommand})
var outp = outputStream(p)
if input.len > 0: inputStream(p).write(input)
close inputStream(p)
result = (TaintedString"", -1)
var line = newStringOfCap(120).TaintedString
result = ("", -1)
var line = newStringOfCap(120)
while true:
if outp.readLine(line):
result[0].string.add(line.string)
@@ -223,7 +223,7 @@ else: # main driver
p.inputStream.flush()
var line = ""
var s: seq[string]
while p.outputStream.readLine(line.TaintedString):
while p.outputStream.readLine(line):
s.add line
doAssert s == @["10"]
@@ -235,15 +235,15 @@ else: # main driver
deferScoped: p.close()
do:
var sout: seq[string]
while p.outputStream.readLine(x.TaintedString): sout.add x
while p.outputStream.readLine(x): sout.add x
doAssert sout == @["start ta_out", "to stdout", "to stdout", "to stderr", "to stderr", "to stdout", "to stdout", "end ta_out"]
block: # startProcess stderr (replaces old test `tstderr` + `ta_out`)
var p = startProcess(output, dir, options={})
deferScoped: p.close()
do:
var serr, sout: seq[string]
while p.errorStream.readLine(x.TaintedString): serr.add x
while p.outputStream.readLine(x.TaintedString): sout.add x
while p.errorStream.readLine(x): serr.add x
while p.outputStream.readLine(x): sout.add x
doAssert serr == @["to stderr", "to stderr"]
doAssert sout == @["start ta_out", "to stdout", "to stdout", "to stdout", "to stdout", "end ta_out"]

View File

@@ -5,7 +5,7 @@ proc exec(cmd: string) =
let status = execShellCmd(cmd)
doAssert status == 0, cmd
proc execEx(cmd: string): tuple[output: TaintedString, exitCode: int] =
proc execEx(cmd: string): tuple[output: string, exitCode: int] =
echo "deps.cmd: " & cmd
execCmdEx(cmd, {poStdErrToStdOut, poUsePath, poEvalCommand})

View File

@@ -93,7 +93,7 @@ Options:
--sdktype:<type> Specify the SDK flavor to use. Defaults to the Desktop SDK.
<type>: {empty} | store | uwp | onecore
--sdkversion:<v> Use a specific Windows SDK version:
<v> is either the full Windows 10 SDK version number or
<v> is either the full Windows 10 SDK version number or
"8.1" to use the windows 8.1 SDK
--verbose Echoes the command line for loading the Developer Command Prompt
and the command line passed on to the secondary command.
@@ -104,12 +104,12 @@ Microsoft (R) C/C++ Optimizing Compiler if no secondary
command was specified
"""
proc parseVccexeCmdLine(argseq: seq[TaintedString],
proc parseVccexeCmdLine(argseq: seq[string],
vccversionArg: var seq[string], printPathArg: var bool,
vcvarsallArg: var string, commandArg: var string, noCommandArg: var bool,
platformArg: var VccArch, sdkTypeArg: var VccPlatformType,
sdkVersionArg: var string, verboseArg: var bool,
clArgs: var seq[TaintedString]) =
clArgs: var seq[string]) =
## Cannot use usual command-line argument parser here
## Since vccexe command-line arguments are intermingled
## with the secondary command-line arguments which have
@@ -160,7 +160,7 @@ when isMainModule:
var sdkVersionArg: string
var verboseArg: bool = false
var clArgs: seq[TaintedString] = @[]
var clArgs: seq[string] = @[]
let wrapperArgs = commandLineParams()
parseVccexeCmdLine(wrapperArgs, vccversionArg, printPathArg, vcvarsallArg,