mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
Don't crash for invalid toplevel parseStmt/Expr calls (#23089)
This code will crash `check`/`nimsuggest` since the `ra` register is
uninitialised
```nim
import macros
static:
discard parseExpr("'")
```
Now it assigns an empty node so that it has something
Testament changes were so I could properly write a test. It would pass
even with a segfault since it could find the error
This commit is contained in:
@@ -1925,6 +1925,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) =
|
||||
if error.len == 0 and msg <= errMax:
|
||||
error = formatMsg(conf, info, msg, arg))
|
||||
|
||||
regs[ra].node = newNode(nkEmpty)
|
||||
if error.len > 0:
|
||||
c.errorFlag = error
|
||||
elif ast.len != 1:
|
||||
@@ -1942,6 +1944,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
error = formatMsg(conf, info, msg, arg))
|
||||
if error.len > 0:
|
||||
c.errorFlag = error
|
||||
regs[ra].node = newNode(nkEmpty)
|
||||
else:
|
||||
regs[ra].node = ast
|
||||
of opcQueryErrorFlag:
|
||||
|
||||
@@ -193,7 +193,6 @@ proc callNimCompiler(cmdTemplate, filename, options, nimcache: string,
|
||||
foundSuccessMsg = true
|
||||
elif not running(p):
|
||||
break
|
||||
close(p)
|
||||
result.msg = ""
|
||||
result.file = ""
|
||||
result.output = ""
|
||||
@@ -201,8 +200,9 @@ proc callNimCompiler(cmdTemplate, filename, options, nimcache: string,
|
||||
result.column = 0
|
||||
|
||||
result.err = reNimcCrash
|
||||
let exitCode = p.peekExitCode
|
||||
case exitCode
|
||||
result.exitCode = p.peekExitCode
|
||||
close p
|
||||
case result.exitCode
|
||||
of 0:
|
||||
if foundErrorMsg:
|
||||
result.debugInfo.add " compiler exit code was 0 but some Error's were found."
|
||||
@@ -214,7 +214,7 @@ proc callNimCompiler(cmdTemplate, filename, options, nimcache: string,
|
||||
if foundSuccessMsg:
|
||||
result.debugInfo.add " compiler exit code was 1 but no `isSuccess` was true."
|
||||
else:
|
||||
result.debugInfo.add " expected compiler exit code 0 or 1, got $1." % $exitCode
|
||||
result.debugInfo.add " expected compiler exit code 0 or 1, got $1." % $result.exitCode
|
||||
|
||||
if err =~ pegLineError:
|
||||
result.file = extractFilename(matches[0])
|
||||
@@ -521,7 +521,12 @@ proc testSpecHelper(r: var TResults, test: var TTest, expected: TSpec,
|
||||
r.addResult(test, target, extraOptions, expected.output, bufB, reOutputsDiffer)
|
||||
compilerOutputTests(test, target, extraOptions, given, expected, r)
|
||||
of actionReject:
|
||||
# Make sure its the compiler rejecting and not the system (e.g. segfault)
|
||||
cmpMsgs(r, expected, given, test, target, extraOptions)
|
||||
if given.exitCode != QuitFailure:
|
||||
r.addResult(test, target, extraOptions, "exitcode: " & $QuitFailure,
|
||||
"exitcode: " & $given.exitCode & "\n\nOutput:\n" &
|
||||
given.nimout, reExitcodesDiffer)
|
||||
|
||||
proc targetHelper(r: var TResults, test: TTest, expected: TSpec, extraOptions: string) =
|
||||
for target in expected.targets:
|
||||
|
||||
15
tests/macros/tfail_parse.nim
Normal file
15
tests/macros/tfail_parse.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
action: "reject"
|
||||
cmd: "nim check $file"
|
||||
errormsg: "expected expression, but got multiple statements [ValueError]"
|
||||
file: "macros.nim"
|
||||
"""
|
||||
|
||||
import macros
|
||||
static:
|
||||
discard parseStmt("'")
|
||||
discard parseExpr("'")
|
||||
discard parseExpr("""
|
||||
proc foo()
|
||||
proc foo() = discard
|
||||
""")
|
||||
Reference in New Issue
Block a user