예제 #1
0
    def parse(obj):
        """ Bool operations in non-if statements

        The _if.py parser handles a boolean operation in an if statement
          e.g., if var1 and var2:
        So if we're here it means we're in some other expression
          e.g., chmod +x file || echo "No file found"
        """
        return " {} ".format(parse(obj.op)).join(
            [parse(val) for val in obj.values])
예제 #2
0
 def parse(obj):
     if len(obj.ops) != 1:
         raise Unparseable(
             "Compare operations must one and only have one operation")
     if len(obj.comparators) != 1:
         raise Unparseable(
             "Compare operations must one and only have one comparator")
     numeric_compare = False
     if isinstance(obj.left, Num) or isinstance(obj.comparators[0], Num):
         numeric_compare = True
     return "{} {} {}".format(
         parse(obj.left),
         parse(obj.ops[0], numeric=numeric_compare),
         parse(obj.comparators[0]),
     )
예제 #3
0
def envvar(call_args, call_kwargs, parseable=None, **kwargs):
    default = get_kwarg(call_kwargs, 'default', default=None)
    var_name = parse(call_args[0], raw=True)
    parseable._known_vars.add(var_name)
    if default is not None:
        return "{var}=${{{var}:-{default}}}".format(var=var_name,
                                                    default=default)
예제 #4
0
 def parse(cls, obj):
     cls._known_funcs.add(obj.name)
     return "\n".join([
         "{}() {{".format(obj.name),
         parse(obj.args),
         parse_body(obj.body),
         "}",
     ])
예제 #5
0
def _color(color_code, args):
    from shellshock.convert import ConvertContext
    ConvertContext.colors_used = True
    return ("\"${{SHELLSHOCK_COLOR_{color_code}}}"
            "{text}"
            "${{SHELLSHOCK_COLOR_EC}}\"".format(
                color_code=color_code,
                text=parse(args[0], raw=True),
            ))
예제 #6
0
 def parse_conditional(cls, obj_test):
     if isinstance(obj_test, Name):
         # They are testing a boolean variable, compare to true
         return "[ {test} = true ]".format(test=parse(obj_test))
     elif isinstance(obj_test, UnaryOp) and \
             isinstance(obj_test.op, Not) and \
             isinstance(obj_test.operand, Name):
         # They are testing NOT a boolean variable, still assume true
         return "[ {test} = true ]".format(test=parse(obj_test))
     elif isinstance(obj_test, Call):
         return "{test}".format(test=parse(obj_test))
     elif isinstance(obj_test, UnaryOp) and \
             isinstance(obj_test.op, Not) and \
             isinstance(obj_test.operand, Call):
         # They are testing NOT a call, prefix the ! and parse the call
         return "{test}".format(test=parse(obj_test))
     else:
         # It's a more complicated test, parse it
         return "[ {test} ]".format(test=parse(obj_test))
예제 #7
0
def get_kwarg(call_kwargs, kwarg_name, default=__get_kwarg_default, **kwargs):
    """ Return the value of a kwarg in a converter call """
    for kwarg in call_kwargs:
        if kwarg.arg == kwarg_name:
            default = parse(kwarg.value, **kwargs)
            break
    if default is __get_kwarg_default:
        raise KeyError(
            "Required kwarg '{}' was not provided".format(kwarg_name))
    return default
예제 #8
0
    def _call_mock(cls, mock_id, mock_args):
        """ Call a unit test mock instead of the real method.

        This will spawn a subshell that does two things:
          1. Records the mock call with arguments for assertion in the test
          2. Calls a stub function that returns the mock side effect
        """
        return '$(__record_mock_call {mock} {args}; __mock_{mock})'.format(
            mock=mock_id,
            args=" ".join([parse(arg) for arg in mock_args]),
        )
예제 #9
0
 def parse(cls, obj):
     assign_target = obj.targets[0].id
     cls._known_vars.add(assign_target)
     if isinstance(obj.value, Call) and obj.value.func.attr == 'input':
         # If we're assigning from user input, adjust accordingly
         return cls._read_input_into_var(assign_target, obj)
     else:
         return "{}={}".format(
             assign_target,
             parse(obj.value),
         )
예제 #10
0
    def parse(cls, obj, **kwargs):
        func_name = parse(obj.func)

        # Process keyword args to see if this is a func call ID to mock
        for kwarg in obj.keywords:
            if kwarg.arg == '__id__':
                mock_id = parse(kwarg.value, raw=True)
                if mock_id in cls._known_mocks:
                    return cls._call_mock(mock_id, obj.args)

        if func_name in cls._known_funcs:
            return "{} {}".format(
                func_name,
                " ".join([parse(arg) for arg in obj.args]),
            )
        else:
            return run_converter(
                func=func_name,
                call_ref=obj,
                parseable=cls,
                context=ConvertContext,
                **kwargs,
            )
예제 #11
0
    def _read_input_into_var(cls, var, obj):
        """ Read user input into variable

        At this point we assume obj.value is a Call object pointing to
        ss.input and obj.value.args[0] is the input prompt. We know the user
        is trying to set this input to a new variable, but we must make a temp
        variable in between. The variable name will be based off the hash of
        the prompt for repeatability's sake.
        """
        prompt_hash = sha256()
        prompt_hash.update(obj.value.args[0].s.encode())
        temp_var = "INPUT_VAR_{}".format(prompt_hash.hexdigest()[:8])
        return [
            parse(obj.value, assign_to_var=temp_var),
            "{new_var}=\"${temp_var}\"".format(new_var=var, temp_var=temp_var),
        ]
예제 #12
0
 def parse(cls, obj):
     arg_list = []
     num_args = len(obj.args)
     num_defaults = len(obj.defaults)
     for arg_index, arg in enumerate(obj.args):
         cls._known_vars.add(arg.arg)
         default = None
         default_index = arg_index + num_defaults - num_args
         if default_index >= 0:
             default = obj.defaults[default_index]
         arg_list.append(
             parse(
                 arg,
                 arg_num=(arg_index + 1),
                 arg_default=default,
             ))
     return "\n".join(arg_list)
예제 #13
0
def input(call_args,
          call_kwargs,
          parseable=None,
          assign_to_var=None,
          **kwargs):
    if assign_to_var is not None:
        # See if we are assigning this to a new variable first
        target_var = assign_to_var
    else:
        # If we're not assigning, they better specify the 'target' kwarg
        target_var = get_kwarg(call_kwargs, 'target', raw=True)
    parseable._known_vars.add(target_var)

    return "read -p {prompt} {var} </dev/tty".format(
        prompt=parse(call_args[0]),
        var=target_var,
    )
예제 #14
0
    def parse(cls, obj):
        out_lines = []

        if isinstance(obj.test, BoolOp):
            conds = " {} ".format(parse(obj.test.op)).join(
                [cls.parse_conditional(val) for val in obj.test.values])
        else:
            conds = cls.parse_conditional(obj.test)
        out_lines.append("if {conds}; then".format(conds=conds))
        out_lines.append(
            "{body}".format(body=parse_body(obj.body))
        )
        if obj.orelse:
            out_lines.append("else")
            out_lines.append(
                "{body}".format(body=parse_body(obj.orelse))
            )
        out_lines.append("fi")
        return out_lines
예제 #15
0
 def parse(obj):
     """ Returns a stringified version of the attr. """
     return "{}.{}".format(parse(obj.value), obj.attr)
예제 #16
0
def shell(call_args, **kwargs):
    arg = call_args[0]
    return parse(arg, raw=True).strip()
예제 #17
0
def print(call_args, **kwargs):
    return "echo -e {}".format(" ".join([parse(arg) for arg in call_args]))
예제 #18
0
def exit(call_args, **kwargs):
    return "exit {}".format(parse(call_args[0]))
예제 #19
0
 def parse(obj):
     return "{} {}".format(
         parse(obj.op),
         parse(obj.operand),
     )
예제 #20
0
def my_custom_converter(args):
    return "echo 'I came from a custom converter'  args -> {}".format(" ".join(
        [parse(arg) for arg in args]))
예제 #21
0
파일: arg.py 프로젝트: mattdodge/shellshock
 def parse(obj, arg_num, arg_default):
     trailing = ""
     if arg_default:
         trailing = ":-{}".format(parse(arg_default))
     return "  {}=${{{}{}}}".format(obj.arg, arg_num, trailing)
예제 #22
0
 def parse(obj):
     return parse(obj.value)
예제 #23
0
def _file_check(test, call_args):
    return "[ {} {} ]".format(test, parse(call_args[0]))
예제 #24
0
 def numeric_bin_op(cls, obj):
     return "$(({left} {op} {right}))".format(left=parse(obj.left),
                                              op=parse(obj.op),
                                              right=parse(obj.right))
예제 #25
0
def subshell(call_args, **kwargs):
    """ Run the argument in a subshell, return the result """
    return "\"$({})\"".format(parse(call_args[0], raw=True))
예제 #26
0
    def string_bin_op(cls, obj):
        if not isinstance(obj.op, Add):
            raise Unparseable("Binary op {} not supported on strings".format(
                type(obj.op)))

        return "{}{}".format(parse(obj.left), parse(obj.right))
예제 #27
0
def shebang(call_args, context=None, **kwargs):
    context.shebang = parse(call_args[0], raw=True)
예제 #28
0
 def parse(obj):
     return "echo {}".format(" ".join(
         [parse(value) for value in obj.values]))