X-Git-Url: https://mudpy.org/gitweb?p=mudpy.git;a=blobdiff_plain;f=mudpy%2Fcommand.py;h=d1860534517ee3c72e6bcd99062553d26bd198e2;hp=ea779399ce0a4943c194ebe065eec8cdeae237a2;hb=3f200ce7ae627a036203c4d65502d96fe941fbb7;hpb=bc3ee2dd11df80f98cd391a094a17c20df322e7c diff --git a/mudpy/command.py b/mudpy/command.py index ea77939..d186053 100644 --- a/mudpy/command.py +++ b/mudpy/command.py @@ -1,6 +1,6 @@ """User command functions for the mudpy engine.""" -# Copyright (c) 2004-2019 mudpy authors. Permission to use, copy, +# Copyright (c) 2004-2020 mudpy authors. Permission to use, copy, # modify, and distribute this software is granted under terms # provided in the LICENSE file distributed with this software. @@ -115,7 +115,7 @@ def error(actor, input_data): """Generic error for an unrecognized command word.""" # 90% of the time use a generic error - # Whitelist the random.randrange() call in bandit since it's not used for + # Allow the random.randrange() call in bandit since it's not used for # security/cryptographic purposes if random.randrange(10): # nosec message = '''I'm not sure what "''' + input_data + '''" means...''' @@ -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: @@ -171,7 +199,7 @@ def help(actor, parameters): description = command.get("description") if not description: description = "(no short description provided)" - if command.get("administrative"): + if command.is_restricted(): output = "$(red)" else: output = "$(grn)" @@ -194,7 +222,7 @@ def help(actor, parameters): if actor.can_run(command): if really_see_also: really_see_also += ", " - if command.get("administrative"): + if command.is_restricted(): really_see_also += "$(red)" else: really_see_also += "$(grn)" @@ -244,7 +272,7 @@ def help(actor, parameters): "description", "(no short description provided)") # administrative command names are in red, others in green - if command.get("administrative"): + if command.is_restricted(): color = "red" else: color = "grn" @@ -277,7 +305,7 @@ def move(actor, parameters): actor.universe.contents[actor.get("location")].portals()): if portal.startswith(parameters): actor.move_direction(portal) - return(portal) + return portal actor.send("You cannot go that way.") return True @@ -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 whitelist 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: