2016-04-10 3 views
1

In meinem kleinen Spiel-Projekt möchte ich Spieler einige In-Game-Sachen zu manipulieren schreiben einige Clojure Skripte direkt im Spiel. Also, ich heruntergeladen habe Clojure lib und verwendet diesen Code:Entfernen/Whitelist alle Bindungen in Clojure

private val eval = Clojure.`var`("clojure.core", "eval") 

fun eval(code: String): Any? = 
    try { 
    eval.invoke(Clojure.read("(do $code)")) 
    }catch(e: Exception) { 
    e.printStackTrace() 
    null 
    } 

aber die Sache ist, von so Spieler tun kann, das gesamte Programm manipulieren, wie es läuft in derselben Umgebung ist, wie das Spiel-Code. Das einfachste Beispiel ist (System/exit 0).

Meine Frage ist - wie alle Clojure Bindings aus meinem Scripting-Kontext entfernt werden, außer einigen grundlegenden vordefinierten Dingen, wie mathematischen Operatoren, Sammlungszauber und so weiter?

Auch ich kann meine eigenen Bindungen (für die Verkabelung dieser Skripte zu tatsächlichen Spiellogik) mit eval.invoke("(def do-magic [x] (println "magic"))"), aber gibt es einen konsistenten Weg, dies zu tun?

upd: brauche ich wirklicheinfach Sachen wie Mathematik und springen um mit einfachen Funktionen zu tun. Vielleicht ein bisschen Sammelmagie. Also muss ich alles mit Ausnahme dieses Zeug blockieren, so dass jeder unsichere Code überhaupt nicht existieren kann.

+0

was cljs statt CLJ und läuft Player-Code über eingebettete js eval (zB. Rhino)? Das wird wahrscheinlich viel einfacher zu Sandkasten – noisesmith

+0

Oh, das ist das richtige Wort, um diese Art von Sachen zu googlen! 'Sandkasten'! Vielen Dank, fand endlich eine Menge Artikel darüber – necauqua

Antwort

1

Diese Technik heißt sandbox und einfach Googeln "Clojure Sandbox" führte mich schließlich zu den Artikeln zu diesem Thema.

UPD: Ich habe benötigt, um weiße Liste stuff, nicht schwarze Liste wie es im Internet verwendet wurde. ganzen Tag damit verbracht, aber schließlich bekam dies funktioniert

private val eval = Clojure.`var`("clojure.core", "eval") 

val whitelist = listOf("+", "-", "*", "/", "=") //example 

init { 
    val wh = whitelist.joinToString(" ", "[", "]") { "\"$it\"" } 
    eval(""" 
    (let [wh (vec (map symbol $wh))] 
     (doseq [n (all-ns) :let [n (ns-name n)]] 
     (if (= (str n) "clojure.core") 
      (doseq [[k _] (ns-map n) :when (not (some (fn [x] (= x k)) wh))] 
      (ns-unmap n k)) 
      (remove-ns n)))) 
    """) 
} 

fun eval(code: String): Any? = 
    try { 
    eval.invoke(Clojure.read("(do $code)")) 
    }catch(e: Exception) { 
    e.printStackTrace() 
    null 
    } 
Verwandte Themen