Replace show result with debug evaluate command
[mudpy.git] / mudpy / command.py
index 279da78..5ee7ce8 100644 (file)
@@ -134,6 +134,34 @@ def error(actor, input_data):
     return True
 
 
+def evaluate(actor, parameters):
+    """Evaluate a Python expression."""
+
+    if not parameters:
+        message = "You need to supply a Python expression."
+    elif "__" in parameters:
+        message = "Double-underscores (__) are not allowed in expressions."
+    elif "lambda" in parameters:
+        message = "Lambda functions are not allowed in expressions."
+    else:
+        # Strictly limit the allowed builtins and modules
+        eval_globals = {"__builtins__": dict()}
+        for allowed in ("dir", "globals", "len", "locals"):
+            eval_globals["__builtins__"][allowed] = __builtins__[allowed]
+        eval_globals["mudpy"] = mudpy
+        eval_globals["universe"] = actor.universe
+        try:
+            # there is no other option than to use eval() for this, since
+            # its purpose is to evaluate arbitrary expressions, so do what
+            # we can to secure it and allow it for bandit analysis
+            message = repr(eval(parameters, eval_globals))  # nosec
+        except Exception as e:
+            message = ("$(red)Your expression raised an exception...$(eol)"
+                       "$(eol)$(bld)%s$(nrm)" % e)
+    actor.send(message)
+    return True
+
+
 def halt(actor, parameters):
     """Halt the world."""
     if actor.owner:
@@ -548,20 +576,6 @@ def show(actor, parameters):
                             (facet, str(facets[facet])))
         else:
             message = 'Element "' + arguments[1] + '" does not exist.'
-    elif arguments[0] == "result":
-        if len(arguments) < 2:
-            message = "You need to specify an expression."
-        else:
-            try:
-                # there is no other option than to use eval() for this, since
-                # its purpose is to evaluate arbitrary expressions, so do what
-                # we can to secure it and allow it for bandit analysis
-                message = repr(eval(  # nosec
-                    " ".join(arguments[1:]),
-                    {"mudpy": mudpy, "universe": actor.universe}))
-            except Exception as e:
-                message = ("$(red)Your expression raised an exception...$(eol)"
-                           "$(eol)$(bld)%s$(nrm)" % e)
     elif arguments[0] == "log":
         if len(arguments) == 4:
             if re.match(r"^\d+$", arguments[3]) and int(arguments[3]) >= 0: