Using eval() to assess user input and some condition. What alternatives?

Question:

First, to provide some context, I am designing a console based version of Blackjack for entertainment and learning purposes. The code below was my solution to evaluate different conditions given user input.

The function below handles sleep times and user inputs and its file is imported to main.

import consoleControl as cs

def console_control( string, n_sec, return_flag, break_check, condition, wrapper=str)

return_flag is set to True if a return is expected, and if a condition is passed the following code will be executed.

if condition:
    while True:
        try:
            # This is only meant to be used on numeric types 
            userIo = wrapper(input(string))
                if eval(str(userIo) + condition):
                    return userIo
                else:
                    return None

         except ValueError:
            return None

My first successfull run of this, included the following function call.

# Gets a positive numeric value
def get_bankRoll():
    while True:
        # condition being passed to console_control()
        condition = '> 0'
        try:
            while True:
                string = 'How much money will you be gamblin'... player? nEuros: '
                cash = hud_control(0, None, None, None, None, [string, None, True, None, condition, float])
            # more code follows

Calling to ->

# Printing routine with set ascii charaters and other printed statements
def hud_control(hud, cash, game_phase, hand_display_args,  new_line, control_args):

    # Code between '#' removed for clarity
    if hud == 0:
        pass
    else:
        pass
    if new_line:
        for x in range(new_line): print('n')
    # 

    if control_args:
        if control_args[-1]:
            return cs.console_control(*control_args)
        else:
            cs.console_control(*control_args)

I’ve read that eval is extremely unsafe, and indeed when I tested removing the wrapper and evaluated "sys.exit(0) #) I successfully exited. But with the wrapper I cannot, so assuming that I wish to only evaluate numeric expressions.

Any of the following would be good answers for me:

  • how would one exploit the current code?
  • what would be an alternative for dynamic (input, condition) assessment?

Note: I would prefer a classless implementation, if possible.

Asked By: Paulo Martins

||

Answers:

‘eval()’ is not safe. It does not stop user from malicious code input to be executed

An alternative is to use

import ast
s2 = ast.literal_eval(s1)
Answered By: perpetualstudent