mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-17 14:31:15 +00:00
beginning of a taint mode; type system enhancements
This commit is contained in:
@@ -36,15 +36,18 @@ type
|
||||
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
|
||||
nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt,
|
||||
nnkAsmStmt, nnkPragma, nnkIfStmt, nnkWhenStmt,
|
||||
nnkForStmt, nnkWhileStmt, nnkCaseStmt, nnkVarSection,
|
||||
nnkConstSection, nnkConstDef, nnkTypeSection, nnkTypeDef,
|
||||
nnkForStmt, nnkWhileStmt, nnkCaseStmt,
|
||||
nnkVarSection, nnkLetSection, nnkConstSection,
|
||||
nnkConstDef, nnkTypeSection, nnkTypeDef,
|
||||
nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt,
|
||||
nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt,
|
||||
nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt,
|
||||
nnkIncludeStmt, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr,
|
||||
nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy,
|
||||
nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen,
|
||||
nnkRefTy, nnkPtrTy, nnkVarTy, nnkDistinctTy,
|
||||
nnkRefTy, nnkPtrTy, nnkVarTy,
|
||||
nnkConstTy, nnkMutableTy,
|
||||
nnkDistinctTy,
|
||||
nnkProcTy, nnkEnumTy, nnkEnumFieldDef, nnkReturnToken
|
||||
TNimNodeKinds* = set[TNimrodNodeKind]
|
||||
TNimrodTypeKind* = enum
|
||||
@@ -184,7 +187,7 @@ proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
## in a string literal node
|
||||
return newStrLitNode(repr(n))
|
||||
|
||||
proc prettyPrint*(n: PNimrodNode): string {.compileTime.} =
|
||||
proc toLisp*(n: PNimrodNode): string {.compileTime.} =
|
||||
## Convert the AST `n` to a human-readable string
|
||||
##
|
||||
## You can use this as a tool to explore the Nimrod's abstract syntax
|
||||
@@ -204,10 +207,10 @@ proc prettyPrint*(n: PNimrodNode): string {.compileTime.} =
|
||||
of nnkIdent: add(result, $n.ident)
|
||||
of nnkSym, nnkNone: assert false
|
||||
else:
|
||||
add(result, prettyPrint(n[0]))
|
||||
add(result, toLisp(n[0]))
|
||||
for j in 1..n.len-1:
|
||||
add(result, ", ")
|
||||
add(result, prettyPrint(n[j]))
|
||||
add(result, toLisp(n[j]))
|
||||
|
||||
add(result, ")")
|
||||
|
||||
@@ -215,7 +218,7 @@ proc toYaml*(n: PNimrodNode): string {.magic: "AstToYaml".}
|
||||
## Converts the AST `n` to an YAML string
|
||||
##
|
||||
## Provides more detailed, potentially harder to digest information
|
||||
## than `prettyPrint`
|
||||
## than `toLisp`
|
||||
|
||||
proc parseExpr*(s: string) : expr {.magic: "ParseExprToAst".}
|
||||
## Compiles the passed string to its AST representation
|
||||
@@ -226,10 +229,13 @@ proc parseStmt*(s: string) : stmt {.magic: "ParseStmtToAst".}
|
||||
## Expects one or more statements
|
||||
|
||||
proc getAst*(macroOrTemplate: expr): expr {.magic: "ExpandMacroToAst".}
|
||||
## Obtains the AST nodes returned from a macro or template invocation
|
||||
## example:
|
||||
## macro FooMacro() =
|
||||
## var ast = getAst(BarTemplate())
|
||||
## Obtains the AST nodes returned from a macro or template invocation.
|
||||
## Example:
|
||||
##
|
||||
## .. code-block:: nimrod
|
||||
##
|
||||
## macro FooMacro() =
|
||||
## var ast = getAst(BarTemplate())
|
||||
|
||||
proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
|
||||
## checks that `n` is of kind `k`. If this is not the case,
|
||||
|
||||
@@ -107,7 +107,7 @@ proc cgiError*(msg: string) {.noreturn.} =
|
||||
raise e
|
||||
|
||||
proc getEncodedData(allowedMethods: set[TRequestMethod]): string =
|
||||
case getenv("REQUEST_METHOD")
|
||||
case getenv("REQUEST_METHOD").string
|
||||
of "POST":
|
||||
if methodPost notin allowedMethods:
|
||||
cgiError("'REQUEST_METHOD' 'POST' is not supported")
|
||||
@@ -192,131 +192,131 @@ proc validateData*(data: PStringTable, validKeys: openarray[string]) =
|
||||
|
||||
proc getContentLength*(): string =
|
||||
## returns contents of the ``CONTENT_LENGTH`` environment variable
|
||||
return getenv("CONTENT_LENGTH")
|
||||
return getenv("CONTENT_LENGTH").string
|
||||
|
||||
proc getContentType*(): string =
|
||||
## returns contents of the ``CONTENT_TYPE`` environment variable
|
||||
return getenv("CONTENT_Type")
|
||||
return getenv("CONTENT_Type").string
|
||||
|
||||
proc getDocumentRoot*(): string =
|
||||
## returns contents of the ``DOCUMENT_ROOT`` environment variable
|
||||
return getenv("DOCUMENT_ROOT")
|
||||
return getenv("DOCUMENT_ROOT").string
|
||||
|
||||
proc getGatewayInterface*(): string =
|
||||
## returns contents of the ``GATEWAY_INTERFACE`` environment variable
|
||||
return getenv("GATEWAY_INTERFACE")
|
||||
return getenv("GATEWAY_INTERFACE").string
|
||||
|
||||
proc getHttpAccept*(): string =
|
||||
## returns contents of the ``HTTP_ACCEPT`` environment variable
|
||||
return getenv("HTTP_ACCEPT")
|
||||
return getenv("HTTP_ACCEPT").string
|
||||
|
||||
proc getHttpAcceptCharset*(): string =
|
||||
## returns contents of the ``HTTP_ACCEPT_CHARSET`` environment variable
|
||||
return getenv("HTTP_ACCEPT_CHARSET")
|
||||
return getenv("HTTP_ACCEPT_CHARSET").string
|
||||
|
||||
proc getHttpAcceptEncoding*(): string =
|
||||
## returns contents of the ``HTTP_ACCEPT_ENCODING`` environment variable
|
||||
return getenv("HTTP_ACCEPT_ENCODING")
|
||||
return getenv("HTTP_ACCEPT_ENCODING").string
|
||||
|
||||
proc getHttpAcceptLanguage*(): string =
|
||||
## returns contents of the ``HTTP_ACCEPT_LANGUAGE`` environment variable
|
||||
return getenv("HTTP_ACCEPT_LANGUAGE")
|
||||
return getenv("HTTP_ACCEPT_LANGUAGE").string
|
||||
|
||||
proc getHttpConnection*(): string =
|
||||
## returns contents of the ``HTTP_CONNECTION`` environment variable
|
||||
return getenv("HTTP_CONNECTION")
|
||||
return getenv("HTTP_CONNECTION").string
|
||||
|
||||
proc getHttpCookie*(): string =
|
||||
## returns contents of the ``HTTP_COOKIE`` environment variable
|
||||
return getenv("HTTP_COOKIE")
|
||||
return getenv("HTTP_COOKIE").string
|
||||
|
||||
proc getHttpHost*(): string =
|
||||
## returns contents of the ``HTTP_HOST`` environment variable
|
||||
return getenv("HTTP_HOST")
|
||||
return getenv("HTTP_HOST").string
|
||||
|
||||
proc getHttpReferer*(): string =
|
||||
## returns contents of the ``HTTP_REFERER`` environment variable
|
||||
return getenv("HTTP_REFERER")
|
||||
return getenv("HTTP_REFERER").string
|
||||
|
||||
proc getHttpUserAgent*(): string =
|
||||
## returns contents of the ``HTTP_USER_AGENT`` environment variable
|
||||
return getenv("HTTP_USER_AGENT")
|
||||
return getenv("HTTP_USER_AGENT").string
|
||||
|
||||
proc getPathInfo*(): string =
|
||||
## returns contents of the ``PATH_INFO`` environment variable
|
||||
return getenv("PATH_INFO")
|
||||
return getenv("PATH_INFO").string
|
||||
|
||||
proc getPathTranslated*(): string =
|
||||
## returns contents of the ``PATH_TRANSLATED`` environment variable
|
||||
return getenv("PATH_TRANSLATED")
|
||||
return getenv("PATH_TRANSLATED").string
|
||||
|
||||
proc getQueryString*(): string =
|
||||
## returns contents of the ``QUERY_STRING`` environment variable
|
||||
return getenv("QUERY_STRING")
|
||||
return getenv("QUERY_STRING").string
|
||||
|
||||
proc getRemoteAddr*(): string =
|
||||
## returns contents of the ``REMOTE_ADDR`` environment variable
|
||||
return getenv("REMOTE_ADDR")
|
||||
return getenv("REMOTE_ADDR").string
|
||||
|
||||
proc getRemoteHost*(): string =
|
||||
## returns contents of the ``REMOTE_HOST`` environment variable
|
||||
return getenv("REMOTE_HOST")
|
||||
return getenv("REMOTE_HOST").string
|
||||
|
||||
proc getRemoteIdent*(): string =
|
||||
## returns contents of the ``REMOTE_IDENT`` environment variable
|
||||
return getenv("REMOTE_IDENT")
|
||||
return getenv("REMOTE_IDENT").string
|
||||
|
||||
proc getRemotePort*(): string =
|
||||
## returns contents of the ``REMOTE_PORT`` environment variable
|
||||
return getenv("REMOTE_PORT")
|
||||
return getenv("REMOTE_PORT").string
|
||||
|
||||
proc getRemoteUser*(): string =
|
||||
## returns contents of the ``REMOTE_USER`` environment variable
|
||||
return getenv("REMOTE_USER")
|
||||
return getenv("REMOTE_USER").string
|
||||
|
||||
proc getRequestMethod*(): string =
|
||||
## returns contents of the ``REQUEST_METHOD`` environment variable
|
||||
return getenv("REQUEST_METHOD")
|
||||
return getenv("REQUEST_METHOD").string
|
||||
|
||||
proc getRequestURI*(): string =
|
||||
## returns contents of the ``REQUEST_URI`` environment variable
|
||||
return getenv("REQUEST_URI")
|
||||
return getenv("REQUEST_URI").string
|
||||
|
||||
proc getScriptFilename*(): string =
|
||||
## returns contents of the ``SCRIPT_FILENAME`` environment variable
|
||||
return getenv("SCRIPT_FILENAME")
|
||||
return getenv("SCRIPT_FILENAME").string
|
||||
|
||||
proc getScriptName*(): string =
|
||||
## returns contents of the ``SCRIPT_NAME`` environment variable
|
||||
return getenv("SCRIPT_NAME")
|
||||
return getenv("SCRIPT_NAME").string
|
||||
|
||||
proc getServerAddr*(): string =
|
||||
## returns contents of the ``SERVER_ADDR`` environment variable
|
||||
return getenv("SERVER_ADDR")
|
||||
return getenv("SERVER_ADDR").string
|
||||
|
||||
proc getServerAdmin*(): string =
|
||||
## returns contents of the ``SERVER_ADMIN`` environment variable
|
||||
return getenv("SERVER_ADMIN")
|
||||
return getenv("SERVER_ADMIN").string
|
||||
|
||||
proc getServerName*(): string =
|
||||
## returns contents of the ``SERVER_NAME`` environment variable
|
||||
return getenv("SERVER_NAME")
|
||||
return getenv("SERVER_NAME").string
|
||||
|
||||
proc getServerPort*(): string =
|
||||
## returns contents of the ``SERVER_PORT`` environment variable
|
||||
return getenv("SERVER_PORT")
|
||||
return getenv("SERVER_PORT").string
|
||||
|
||||
proc getServerProtocol*(): string =
|
||||
## returns contents of the ``SERVER_PROTOCOL`` environment variable
|
||||
return getenv("SERVER_PROTOCOL")
|
||||
return getenv("SERVER_PROTOCOL").string
|
||||
|
||||
proc getServerSignature*(): string =
|
||||
## returns contents of the ``SERVER_SIGNATURE`` environment variable
|
||||
return getenv("SERVER_SIGNATURE")
|
||||
return getenv("SERVER_SIGNATURE").string
|
||||
|
||||
proc getServerSoftware*(): string =
|
||||
## returns contents of the ``SERVER_SOFTWARE`` environment variable
|
||||
return getenv("SERVER_SOFTWARE")
|
||||
return getenv("SERVER_SOFTWARE").string
|
||||
|
||||
proc setTestData*(keysvalues: openarray[string]) =
|
||||
## fills the appropriate environment variables to test your CGI application.
|
||||
@@ -360,10 +360,10 @@ proc setCookie*(name, value: string) =
|
||||
var
|
||||
gcookies: PStringTable = nil
|
||||
|
||||
proc getCookie*(name: string): string =
|
||||
proc getCookie*(name: string): TaintedString =
|
||||
## Gets a cookie. If no cookie of `name` exists, "" is returned.
|
||||
if gcookies == nil: gcookies = parseCookies(getHttpCookie())
|
||||
result = gcookies[name]
|
||||
result = TaintedString(gcookies[name])
|
||||
|
||||
proc existsCookie*(name: string): bool =
|
||||
## Checks if a cookie of `name` exists.
|
||||
|
||||
@@ -692,7 +692,7 @@ proc findEnvVar(key: string): int =
|
||||
if startsWith(environment[i], temp): return i
|
||||
return -1
|
||||
|
||||
proc getEnv*(key: string): string =
|
||||
proc getEnv*(key: string): TaintedString =
|
||||
## Returns the value of the `environment variable`:idx: named `key`.
|
||||
##
|
||||
## If the variable does not exist, "" is returned. To distinguish
|
||||
@@ -700,11 +700,11 @@ proc getEnv*(key: string): string =
|
||||
## `existsEnv(key)`.
|
||||
var i = findEnvVar(key)
|
||||
if i >= 0:
|
||||
return substr(environment[i], find(environment[i], '=')+1)
|
||||
return TaintedString(substr(environment[i], find(environment[i], '=')+1))
|
||||
else:
|
||||
var env = cgetenv(key)
|
||||
if env == nil: return ""
|
||||
result = $env
|
||||
if env == nil: return TaintedString("")
|
||||
result = TaintedString($env)
|
||||
|
||||
proc existsEnv*(key: string): bool =
|
||||
## Checks whether the environment variable named `key` exists.
|
||||
@@ -733,14 +733,15 @@ proc putEnv*(key, val: string) =
|
||||
if SetEnvironmentVariableA(key, val) == 0'i32:
|
||||
OSError()
|
||||
|
||||
iterator envPairs*(): tuple[key, value: string] =
|
||||
iterator envPairs*(): tuple[key, value: TaintedString] =
|
||||
## Iterate over all `environments variables`:idx:. In the first component
|
||||
## of the tuple is the name of the current variable stored, in the second
|
||||
## its value.
|
||||
getEnvVarsC()
|
||||
for i in 0..high(environment):
|
||||
var p = find(environment[i], '=')
|
||||
yield (substr(environment[i], 0, p-1), substr(environment[i], p+1))
|
||||
yield (TaintedString(substr(environment[i], 0, p-1)),
|
||||
TaintedString(substr(environment[i], p+1)))
|
||||
|
||||
iterator walkFiles*(pattern: string): string =
|
||||
## Iterate over all the files that match the `pattern`. On POSIX this uses
|
||||
@@ -1078,18 +1079,18 @@ proc exclFilePermissions*(filename: string,
|
||||
|
||||
proc getHomeDir*(): string {.rtl, extern: "nos$1".} =
|
||||
## Returns the home directory of the current user.
|
||||
when defined(windows): return getEnv("USERPROFILE") & "\\"
|
||||
else: return getEnv("HOME") & "/"
|
||||
when defined(windows): return string(getEnv("USERPROFILE")) & "\\"
|
||||
else: return string(getEnv("HOME")) & "/"
|
||||
|
||||
proc getConfigDir*(): string {.rtl, extern: "nos$1".} =
|
||||
## Returns the config directory of the current user for applications.
|
||||
when defined(windows): return getEnv("APPDATA") & "\\"
|
||||
else: return getEnv("HOME") & "/.config/"
|
||||
when defined(windows): return string(getEnv("APPDATA")) & "\\"
|
||||
else: return string(getEnv("HOME")) & "/.config/"
|
||||
|
||||
proc getTempDir*(): string {.rtl, extern: "nos$1".} =
|
||||
## Returns the temporary directory of the current user for applications to
|
||||
## save temporary files in.
|
||||
when defined(windows): return getEnv("TEMP") & "\\"
|
||||
when defined(windows): return string(getEnv("TEMP")) & "\\"
|
||||
else: return "/tmp/"
|
||||
|
||||
when defined(windows):
|
||||
@@ -1107,14 +1108,14 @@ when defined(windows):
|
||||
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA())
|
||||
result = ownArgv.len-1
|
||||
|
||||
proc paramStr*(i: int): string {.rtl, extern: "nos$1".} =
|
||||
proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1".} =
|
||||
## Returns the `i`-th `command line argument`:idx: given to the
|
||||
## application.
|
||||
##
|
||||
## `i` should be in the range `1..paramCount()`, else
|
||||
## the `EOutOfIndex` exception is raised.
|
||||
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA())
|
||||
return ownArgv[i]
|
||||
return TaintedString(ownArgv[i])
|
||||
|
||||
elif not defined(createNimRtl):
|
||||
# On Posix, there is no portable way to get the command line from a DLL.
|
||||
@@ -1122,8 +1123,8 @@ elif not defined(createNimRtl):
|
||||
cmdCount {.importc: "cmdCount".}: cint
|
||||
cmdLine {.importc: "cmdLine".}: cstringArray
|
||||
|
||||
proc paramStr*(i: int): string =
|
||||
if i < cmdCount and i >= 0: return $cmdLine[i]
|
||||
proc paramStr*(i: int): TaintedString =
|
||||
if i < cmdCount and i >= 0: return TaintedString($cmdLine[i])
|
||||
raise newException(EInvalidIndex, "invalid index")
|
||||
|
||||
proc paramCount*(): int = return cmdCount-1
|
||||
@@ -1172,13 +1173,14 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1".} =
|
||||
result = "" # error!
|
||||
else:
|
||||
# little heuristic that may work on other POSIX-like systems:
|
||||
result = getEnv("_")
|
||||
result = string(getEnv("_"))
|
||||
if len(result) == 0:
|
||||
result = ParamStr(0) # POSIX guaranties that this contains the executable
|
||||
# as it has been executed by the calling process
|
||||
result = string(ParamStr(0))
|
||||
# POSIX guaranties that this contains the executable
|
||||
# as it has been executed by the calling process
|
||||
if len(result) > 0 and result[0] != DirSep: # not an absolute path?
|
||||
# iterate over any path in the $PATH environment variable
|
||||
for p in split(getEnv("PATH"), {PathSep}):
|
||||
for p in split(string(getEnv("PATH")), {PathSep}):
|
||||
var x = joinPath(p, result)
|
||||
if ExistsFile(x): return x
|
||||
|
||||
@@ -1230,7 +1232,7 @@ proc findExe*(exe: string): string =
|
||||
## is added an ``.exe`` file extension if it has no extension.
|
||||
result = addFileExt(exe, os.exeExt)
|
||||
if ExistsFile(result): return
|
||||
var path = os.getEnv("PATH")
|
||||
var path = string(os.getEnv("PATH"))
|
||||
for candidate in split(path, pathSep):
|
||||
var x = candidate / result
|
||||
if ExistsFile(x): return x
|
||||
|
||||
@@ -48,7 +48,7 @@ when defined(os.ParamCount):
|
||||
else:
|
||||
result.cmd = ""
|
||||
for i in countup(1, ParamCount()):
|
||||
result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i)) & ' '
|
||||
result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i).string) & ' '
|
||||
result.kind = cmdEnd
|
||||
result.key = ""
|
||||
result.val = ""
|
||||
|
||||
@@ -787,6 +787,19 @@ proc compileOption*(option, arg: string): bool {.
|
||||
const
|
||||
hasThreadSupport = compileOption("threads")
|
||||
hasSharedHeap = defined(boehmgc) # don't share heaps; every thread has its own
|
||||
# taintMode = compileOption("taintmode")
|
||||
|
||||
when defined(taintMode):
|
||||
# XXX use a compile time option for it!
|
||||
type TaintedString* = distinct string ## a distinct string type that
|
||||
## is `tainted`:idx:. It is an alias for
|
||||
## ``string`` if the taint mode is not
|
||||
## turned on. Use the ``-d:taintMode``
|
||||
## command line switch to turn the taint
|
||||
## mode on.
|
||||
else:
|
||||
type TaintedString* = string
|
||||
|
||||
|
||||
when hasThreadSupport:
|
||||
{.pragma: rtlThreadVar, threadvar.}
|
||||
@@ -896,11 +909,6 @@ type # these work for most platforms:
|
||||
PInt64* = ptr Int64 ## an alias for ``ptr int64``
|
||||
PInt32* = ptr Int32 ## an alias for ``ptr int32``
|
||||
|
||||
type TOptional*[T] = object
|
||||
case hasValue* : bool
|
||||
of true: value*: T
|
||||
of false: nil
|
||||
|
||||
proc toFloat*(i: int): float {.
|
||||
magic: "ToFloat", noSideEffect, importc: "toFloat".}
|
||||
## converts an integer `i` into a ``float``. If the conversion
|
||||
@@ -1653,7 +1661,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
|
||||
proc FlushFile*(f: TFile) {.importc: "fflush", noDecl.}
|
||||
## Flushes `f`'s buffer.
|
||||
|
||||
proc readFile*(filename: string): string
|
||||
proc readFile*(filename: string): TaintedString
|
||||
## Opens a file named `filename` for reading. Then reads the
|
||||
## file's content completely into a string and
|
||||
## closes the file afterwards. Returns the string.
|
||||
@@ -1675,7 +1683,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
|
||||
proc write*(f: TFile, a: openArray[string])
|
||||
## Writes a value to the file `f`. May throw an IO exception.
|
||||
|
||||
proc readLine*(f: TFile): string
|
||||
proc readLine*(f: TFile): TaintedString
|
||||
## reads a line of text from the file `f`. May throw an IO exception.
|
||||
## A line of text may be delimited by ``CR``, ``LF`` or
|
||||
## ``CRLF``. The newline character(s) are not part of the returned string.
|
||||
@@ -1814,22 +1822,22 @@ when not defined(EcmaScript) and not defined(NimrodVM):
|
||||
when hasThreadSupport:
|
||||
include "system/channels"
|
||||
|
||||
iterator lines*(filename: string): string =
|
||||
iterator lines*(filename: string): TaintedString =
|
||||
## Iterate over any line in the file named `filename`.
|
||||
## If the file does not exist `EIO` is raised.
|
||||
var f = open(filename)
|
||||
var res = ""
|
||||
while not endOfFile(f):
|
||||
rawReadLine(f, res)
|
||||
yield res
|
||||
yield TaintedString(res)
|
||||
Close(f)
|
||||
|
||||
iterator lines*(f: TFile): string =
|
||||
iterator lines*(f: TFile): TaintedString =
|
||||
## Iterate over any line in the file `f`.
|
||||
var res = ""
|
||||
while not endOfFile(f):
|
||||
rawReadLine(f, res)
|
||||
yield res
|
||||
yield TaintedString(res)
|
||||
|
||||
include "system/assign"
|
||||
include "system/repr"
|
||||
|
||||
@@ -55,8 +55,8 @@ proc rawReadLine(f: TFile, result: var string) =
|
||||
break
|
||||
add result, chr(int(c))
|
||||
|
||||
proc readLine(f: TFile): string =
|
||||
result = ""
|
||||
proc readLine(f: TFile): TaintedString =
|
||||
result = TaintedString("")
|
||||
rawReadLine(f, result)
|
||||
|
||||
proc write(f: TFile, i: int) =
|
||||
@@ -81,7 +81,7 @@ proc write(f: TFile, c: Char) = putc(c, f)
|
||||
proc write(f: TFile, a: openArray[string]) =
|
||||
for x in items(a): write(f, x)
|
||||
|
||||
proc readFile(filename: string): string =
|
||||
proc readFile(filename: string): TaintedString =
|
||||
var f = open(filename)
|
||||
try:
|
||||
var len = getFileSize(f)
|
||||
|
||||
Reference in New Issue
Block a user