summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-05-29 09:07:24 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-05-29 09:07:24 +0200
commit688c54d8f158ff977161a234374b1cd321ba95f3 (patch)
treee55216bb241ac468dc79cd761fbe9b1e93a37934
parenta5701d6b71853e683f4d655b6b5ea4a13bec993b (diff)
downloadNim-688c54d8f158ff977161a234374b1cd321ba95f3.tar.gz
compiler API: final cleanups; improve security by diabling 'gorge' and friends
-rw-r--r--compiler/main.nim3
-rw-r--r--compiler/nim.cfg2
-rw-r--r--compiler/nimeval.nim9
-rw-r--r--compiler/vm.nim21
-rw-r--r--compiler/vmops.nim23
-rw-r--r--nimsuggest/nimsuggest.nim9
-rw-r--r--nimsuggest/nimsuggest.nim.cfg3
-rw-r--r--tests/compilerapi/myscript.nim2
-rw-r--r--tests/compilerapi/tcompilerapi.nim13
9 files changed, 56 insertions, 29 deletions
diff --git a/compiler/main.nim b/compiler/main.nim
index c5b2ddca5..ba2537ef8 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -9,6 +9,9 @@
 
 # implements the command dispatcher and several commands
 
+when not defined(nimcore):
+  {.error: "nimcore MUST be defined for Nim's core tooling".}
+
 import
   llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
   os, condsyms, rodread, rodwrite, times,
diff --git a/compiler/nim.cfg b/compiler/nim.cfg
index 853ae7e00..f4211fae5 100644
--- a/compiler/nim.cfg
+++ b/compiler/nim.cfg
@@ -5,6 +5,7 @@ path:"llvm"
 path:"$projectPath/.."
 
 define:booting
+define:nimcore
 #import:"$projectpath/testability"
 
 @if windows:
@@ -13,6 +14,5 @@ define:booting
 
 define:useStdoutAsStdmsg
 
-cs:partial
 #define:useNodeIds
 #gc:markAndSweep
diff --git a/compiler/nimeval.nim b/compiler/nimeval.nim
index d5df6a9df..dde6039ba 100644
--- a/compiler/nimeval.nim
+++ b/compiler/nimeval.nim
@@ -29,7 +29,7 @@ iterator exportedSymbols*(i: Interpreter): PSym =
     s = nextIter(it, i.mainModule.tab)
 
 proc selectUniqueSymbol*(i: Interpreter; name: string;
-                         symKinds: set[TSymKind]): PSym =
+                         symKinds: set[TSymKind] = {skLet, skVar}): PSym =
   ## Can be used to access a unique symbol of ``name`` and
   ## the given ``symKinds`` filter.
   assert i != nil
@@ -55,8 +55,11 @@ proc callRoutine*(i: Interpreter; routine: PSym; args: openArray[PNode]): PNode
   assert i != nil
   result = vm.execProc(PCtx i.graph.vm, routine, args)
 
-proc declareRoutine*(i: Interpreter; pkg, module, name: string;
-                     impl: proc (a: VmArgs) {.closure, gcsafe.}) =
+proc getGlobalValue*(i: Interpreter; letOrVar: PSym): PNode =
+  result = vm.getGlobalValue(PCtx i.graph.vm, letOrVar)
+
+proc implementRoutine*(i: Interpreter; pkg, module, name: string;
+                       impl: proc (a: VmArgs) {.closure, gcsafe.}) =
   assert i != nil
   let vm = PCtx(i.graph.vm)
   vm.registerCallback(pkg & "." & module & "." & name, impl)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index c7b68a24c..b1b8132e2 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -972,7 +972,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         when hasFFI:
           let prcValue = c.globals.sons[prc.position-1]
           if prcValue.kind == nkEmpty:
-            globalError(c.config, c.debug[pc], "canot run " & prc.name.s)
+            globalError(c.config, c.debug[pc], "cannot run " & prc.name.s)
           let newValue = callForeignFunction(prcValue, prc.typ, tos.slots,
                                              rb+1, rc-1, c.debug[pc])
           if newValue.kind != nkEmpty:
@@ -1336,14 +1336,17 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
                                      c.module, c.config)
     of opcGorge:
-      decodeBC(rkNode)
-      inc pc
-      let rd = c.code[pc].regA
-
-      createStr regs[ra]
-      regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
-                                     regs[rc].node.strVal, regs[rd].node.strVal,
-                                     c.debug[pc], c.config)[0]
+      when defined(nimcore):
+        decodeBC(rkNode)
+        inc pc
+        let rd = c.code[pc].regA
+
+        createStr regs[ra]
+        regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
+                                      regs[rc].node.strVal, regs[rd].node.strVal,
+                                      c.debug[pc], c.config)[0]
+      else:
+        globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
     of opcNError:
       decodeB(rkNode)
       let a = regs[ra].node
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index 617295b0d..a7d47d7a3 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -107,15 +107,16 @@ proc registerAdditionalOps*(c: PCtx) =
   wrap1f_math(ceil)
   wrap2f_math(fmod)
 
-  wrap2s(getEnv, ospathsop)
-  wrap1s(existsEnv, ospathsop)
-  wrap2svoid(putEnv, ospathsop)
-  wrap1s(dirExists, osop)
-  wrap1s(fileExists, osop)
-  wrap2svoid(writeFile, systemop)
-  wrap1s(readFile, systemop)
-  systemop getCurrentExceptionMsg
-  registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
-    setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
-  systemop gorgeEx
+  when defined(nimcore):
+    wrap2s(getEnv, ospathsop)
+    wrap1s(existsEnv, ospathsop)
+    wrap2svoid(putEnv, ospathsop)
+    wrap1s(dirExists, osop)
+    wrap1s(fileExists, osop)
+    wrap2svoid(writeFile, systemop)
+    wrap1s(readFile, systemop)
+    systemop getCurrentExceptionMsg
+    registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
+      setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
+    systemop gorgeEx
   macrosop getProjectPath
diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim
index 4956f4bf2..dd52e0383 100644
--- a/nimsuggest/nimsuggest.nim
+++ b/nimsuggest/nimsuggest.nim
@@ -9,6 +9,9 @@
 
 ## Nimsuggest is a tool that helps to give editors IDE like capabilities.
 
+when not defined(nimcore):
+  {.error: "nimcore MUST be defined for Nim's core tooling".}
+
 import strutils, os, parseopt, parseutils, sequtils, net, rdstdin, sexp
 # Do NOT import suggest. It will lead to wierd bugs with
 # suggestionResultHook, because suggest.nim is included by sigmatch.
@@ -486,9 +489,9 @@ var
 
 proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
   let conf = graph.config
-  clearPasses()
-  registerPass verbosePass
-  registerPass semPass
+  clearPasses(graph)
+  registerPass graph, verbosePass
+  registerPass graph, semPass
   conf.cmd = cmdIdeTools
   incl conf.globalOptions, optCaasEnabled
   wantMainModule(conf)
diff --git a/nimsuggest/nimsuggest.nim.cfg b/nimsuggest/nimsuggest.nim.cfg
index 38e74b3c7..820db0dba 100644
--- a/nimsuggest/nimsuggest.nim.cfg
+++ b/nimsuggest/nimsuggest.nim.cfg
@@ -8,6 +8,8 @@ path:"$lib/packages/docutils"
 
 define:useStdoutAsStdmsg
 define:nimsuggest
+define:nimcore
+
 # die when nimsuggest uses more than 4GB:
 @if cpu32:
   define:"nimMaxHeap=2000"
@@ -15,7 +17,6 @@ define:nimsuggest
   define:"nimMaxHeap=4000"
 @end
 
-#cs:partial
 #define:useNodeIds
 #define:booting
 #define:noDocgen
diff --git a/tests/compilerapi/myscript.nim b/tests/compilerapi/myscript.nim
index 083385b6f..539b07de1 100644
--- a/tests/compilerapi/myscript.nim
+++ b/tests/compilerapi/myscript.nim
@@ -5,3 +5,5 @@ echo "top level statements are executed!"
 
 proc hostProgramRunsThis*(a, b: float): float =
   result = addFloats(a, b, 1.0)
+
+let hostProgramWantsThis* = "my secret"
diff --git a/tests/compilerapi/tcompilerapi.nim b/tests/compilerapi/tcompilerapi.nim
index 00c9bc523..90d343264 100644
--- a/tests/compilerapi/tcompilerapi.nim
+++ b/tests/compilerapi/tcompilerapi.nim
@@ -1,6 +1,7 @@
 discard """
   output: '''top level statements are executed!
 2.0
+my secret
 '''
 """
 
@@ -16,7 +17,7 @@ proc main() =
     quit "cannot find Nim's standard library"
 
   var intr = createInterpreter("myscript.nim", [std, getAppDir()])
-  intr.declareRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
+  intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
     setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
   )
 
@@ -31,6 +32,16 @@ proc main() =
     echo res.floatVal
   else:
     echo "bug!"
+
+  let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis")
+  if foreignValue == nil:
+    quit "script does not export a global of the name: hostProgramWantsThis"
+  let val = intr.getGlobalValue(foreignValue)
+  if val.kind in {nkStrLit..nkTripleStrLit}:
+    echo val.strVal
+  else:
+    echo "bug!"
+
   destroyInterpreter(intr)
 
 main()
\ No newline at end of file