Пример #1
0
def test_print_stmt__simple_prints(c_exec):
    glb = {'_print_': PrintCollector, '_getattr_': None}

    code, errors = c_exec(ALLOWED_PRINT_STATEMENT)[:2]
    assert code is not None
    assert errors == ()
    exec(code, glb)
    assert glb['_print']() == 'Hello World!\n'

    code, errors = c_exec(ALLOWED_PRINT_STATEMENT_WITH_NO_NL)[:2]
    assert code is not None
    assert errors == ()
    exec(code, glb)
    assert glb['_print']() == 'Hello World!'

    code, errors = c_exec(ALLOWED_MULTI_PRINT_STATEMENT)[:2]
    assert code is not None
    assert errors == ()
    exec(code, glb)
    assert glb['_print']() == 'Hello World! Hello Earth!\n'

    code, errors = c_exec(ALLOWED_PRINT_TUPLE)[:2]
    assert code is not None
    assert errors == ()
    exec(code, glb)
    assert glb['_print']() == "Hello World!\n"

    code, errors = c_exec(ALLOWED_PRINT_MULTI_TUPLE)[:2]
    assert code is not None
    assert errors == ()
    exec(code, glb)
    assert glb['_print']() == "('Hello World!', 'Hello Earth!')\n"
Пример #2
0
def test_RestrictingNodeTransformer__visit_Import_star__1(c_exec):
    """Importing `*` is a SyntaxError in Python itself."""
    result = c_exec('import *')
    assert result.errors == (
        'Line 1: SyntaxError: invalid syntax in on statement: import *',
    )  # NOQA: E501
    assert result.code is None
Пример #3
0
def test_call_py2_builtins(c_exec):
    """It should not be allowed to access global __builtins__ in Python2."""
    result = c_exec('__builtins__["getattr"]')
    assert result.code is None
    assert result.errors == (
        'Line 1: "__builtins__" is an invalid variable name because it starts with "_"',
    )  # NOQA: E501
Пример #4
0
def test_RestrictingNodeTransformer__visit_FunctionDef__6(c_exec):
    """It prevents function arguments starting with `_` in tuples."""
    result = c_exec("def foo(a, (c, (_bad, c))): pass")
    # RestrictedPython.compile.compile_restricted_exec on Python 2 renders
    # the error message twice. This is necessary as otherwise *_bad and
    # **_bad would be allowed.
    assert functiondef_err_msg in result.errors
Пример #5
0
def test_RestrictingNodeTransformer__visit_Lambda__2(c_exec):
    """It prevents keyword arguments starting with `_`."""
    result = c_exec("lambda _bad=1: None")
    # RestrictedPython.compile.compile_restricted_exec on Python 2 renders
    # the error message twice. This is necessary as otherwise *_bad and **_bad
    # would be allowed.
    assert lambda_err_msg in result.errors
Пример #6
0
def test_with_stmt_multi_ctx_unpack_sequence(c_exec, mocker):
    result = c_exec(WITH_STMT_MULTI_CTX_WITH_UNPACK_SEQUENCE)
    assert result.errors == ()

    @contextlib.contextmanager
    def ctx1():
        yield (1, (2, 3))

    @contextlib.contextmanager
    def ctx2():
        yield (4, 5), (6, 7)

    _getiter_ = mocker.stub()
    _getiter_.side_effect = lambda ob: ob

    glb = {
        '_getiter_': _getiter_,
        '_unpack_sequence_': guarded_unpack_sequence
    }

    exec(result.code, glb)

    ret = glb['call'](ctx1, ctx2)

    assert ret == (1, 2, 3, 4, 5, 6, 7)
    _getiter_.assert_has_calls([
        mocker.call((1, (2, 3))),
        mocker.call((2, 3)),
        mocker.call(((4, 5), (6, 7))),
        mocker.call((4, 5)),
        mocker.call((6, 7))
    ])
Пример #7
0
def test_RestrictingNodeTransformer__visit_Lambda__6(c_exec):
    """It prevents arguments starting with `_` in nested tuple unpacking."""
    result = c_exec("lambda (a, (c, (_bad, c))): None")
    # RestrictedPython.compile.compile_restricted_exec on Python 2 renders
    # the error message twice. This is necessary as otherwise *_bad and
    # **_bad would be allowed.
    assert lambda_err_msg in result.errors
Пример #8
0
def test_print_stmt_conditional_print(c_exec):
    code, errors = c_exec(CONDITIONAL_PRINT)[:2]
    glb = {'_print_': PrintCollector, '_getattr_': None}
    exec(code, glb)

    assert glb['func'](True) == '1\n'
    assert glb['func'](False) == ''
Пример #9
0
def test_print_stmt_no_new_scope(c_exec):
    code, errors = c_exec(NO_PRINT_SCOPES)[:2]
    glb = {'_print_': PrintCollector, '_getattr_': None}
    exec(code, glb)

    ret = glb['class_scope']()
    assert ret == 'a\n'
Пример #10
0
def test_call_breakpoint(c_exec):
    """The Python3.7+ builtin function breakpoint should not
    be used and is forbidden in RestrictedPython.
    """
    result = c_exec('breakpoint()')
    assert result.errors == ('Line 1: "breakpoint" is a reserved name.', )
    assert result.code is None
Пример #11
0
def test_compile__compile_restricted_exec__4(c_exec):
    """It does not return code on a SyntaxError."""
    result = c_exec('asdf|')
    assert result.code is None
    assert result.warnings == []
    assert result.used_names == {}
    assert result.errors == (
        'Line 1: SyntaxError: invalid syntax in on statement: asdf|', )
Пример #12
0
def test_print_stmt__nested_print_collector(c_exec, mocker):
    code, errors = c_exec(INJECT_PRINT_COLLECTOR_NESTED)[:2]

    glb = {"_print_": PrintCollector, '_getattr_': None}
    exec(code, glb)

    ret = glb['main']()
    assert ret == 'inner\nf1\nf2main\n'
def test_import_py2_as_builtins(c_exec):
    """It should not be allowed to access global __builtins__ in Python2."""
    result = c_exec(__BUILTINS_EXAMPLE)
    assert result.code is None
    assert result.errors == (
        'Line 2: "__builtins__" is an invalid variable name because it starts with "_"',  # NOQA: E501
        'Line 4: "__builtins__" is an invalid variable name because it starts with "_"'  # NOQA: E501
    )
Пример #14
0
def test_RestrictingNodeTransformer__visit_Call__1(c_exec):
    """It compiles a function call successfully and returns the used name."""
    result = c_exec('a = max([1, 2, 3])')
    assert result.errors == ()
    loc = {}
    exec(result.code, {}, loc)
    assert loc['a'] == 3
    assert result.used_names == {'max': True}
def test_iterate_over_dict_items_plain(c_exec):
    glb = {}
    result = c_exec(ITERATE_OVER_DICT_ITEMS)
    assert result.code is not None
    assert result.errors == ()
    with pytest.raises(NameError) as excinfo:
        exec(result.code, glb, None)
    assert "name '_iter_unpack_sequence_' is not defined" in str(excinfo.value)
def test_iterate_over_dict_items_safe(c_exec):
    glb = safe_globals.copy()
    glb['_getiter_'] = default_guarded_getiter
    glb['_iter_unpack_sequence_'] = guarded_iter_unpack_sequence
    result = c_exec(ITERATE_OVER_DICT_ITEMS)
    assert result.code is not None
    assert result.errors == ()
    exec(result.code, glb, None)
Пример #17
0
def test_RestrictingNodeTransformer__visit_ClassDef__4(c_exec):
    """It does not allow to pass a metaclass to class definitions."""

    result = c_exec(EXPLICIT_METACLASS)

    assert result.errors == (
        'Line 2: The keyword argument "metaclass" is not allowed.', )
    assert result.code is None
Пример #18
0
def test_compile__compile_restricted_exec__2(c_exec):
    """It compiles without restrictions if there is no policy."""
    result = c_exec('_a = 42', policy=None)
    assert result.errors == ()
    assert result.warnings == []
    assert result.used_names == {}
    glob = {}
    exec(result.code, glob)
    assert glob['_a'] == 42
Пример #19
0
def test_print_stmt__with_print_no_printed(c_exec):
    code, errors, warnings = c_exec(WARN_PRINT_NO_PRINTED)[:3]

    assert code is not None
    assert errors == ()
    assert warnings == [
        "Line 3: Print statement is deprecated and not avaliable anymore in Python 3.",  # NOQA: E501
        "Line 2: Prints, but never reads 'printed' variable."
    ]
def test_yield(c_exec):
    """`yield` statement should be allowed."""
    result = c_exec(YIELD_EXAMPLE)
    assert result.errors == ()
    assert result.code is not None
    local = {}
    exec(result.code, {}, local)
    test_generator = local['test_generator']
    exec_result = list(test_generator())
    assert exec_result == [42]
Пример #21
0
def test_compile__compile_restricted_exec__1(c_exec):
    """It returns a CompileResult on success."""
    result = c_exec('a = 42')
    assert result.__class__ == CompileResult
    assert result.errors == ()
    assert result.warnings == []
    assert result.used_names == {}
    glob = {}
    exec(result.code, glob)
    assert glob['a'] == 42
Пример #22
0
def test_RestrictingNodeTransformer__module_func_def_name_call(c_exec):
    """It forbids definition and usage of magic methods as functions ...

    ... at module level.
    """
    result = c_exec(BLACKLISTED_FUNC_NAMES_CALL_TEST)
    # assert result.errors == ('Line 1: ')
    assert result.errors == (
        'Line 2: "__init__" is an invalid variable name because it starts with "_"',  # NOQA: E501
        'Line 5: "__init__" is an invalid variable name because it starts with "_"',  # NOQA: E501
    )
Пример #23
0
def test_print_stmt__fail_with_none_target(c_exec, mocker):
    code, errors = c_exec('print >> None, "test"')[:2]

    assert code is not None
    assert errors == ()

    glb = {'_getattr_': getattr, '_print_': PrintCollector}

    with pytest.raises(AttributeError) as excinfo:
        exec(code, glb)

    assert "'NoneType' object has no attribute 'write'" in str(excinfo.value)
Пример #24
0
def test_safer_getattr__underscore_name(c_exec):
    """It prevents accessing an attribute which starts with an underscore."""
    result = c_exec(GETATTR_UNDERSCORE_NAME)
    assert result.errors == ()
    assert result.warnings == []
    glb = safe_globals.copy()
    glb['getattr'] = safer_getattr
    with pytest.raises(AttributeError) as err:
        exec(result.code, glb, {})
    assert (
        '"__class__" is an invalid attribute name because it starts with "_"'
        == str(err.value))
Пример #25
0
def test_compile__compile_restricted_exec__5(c_exec):
    """It does not return code if the code contains a NULL byte."""
    result = c_exec('a = 5\x00')
    assert result.code is None
    assert result.warnings == []
    assert result.used_names == {}
    if IS_PY2:
        assert result.errors == (
            'compile() expected string without null bytes', )
    else:
        assert result.errors == (
            'source code string cannot contain null bytes', )
Пример #26
0
def test_compile__compile_restricted_exec__3(c_exec):
    """It returns a tuple of errors if the code is not allowed.

    There is no code in this case.
    """
    result = c_exec('_a = 42\n_b = 43')
    errors = (
        'Line 1: "_a" is an invalid variable name because it starts with "_"',
        'Line 2: "_b" is an invalid variable name because it starts with "_"')
    assert result.errors == errors
    assert result.warnings == []
    assert result.used_names == {}
    assert result.code is None
def test_yield_from(c_exec):
    """`yield from` statement should be allowed."""
    result = c_exec(YIELD_FORM_EXAMPLE)
    assert result.errors == ()
    assert result.code is not None

    def my_external_generator():
        my_list = [1, 2, 3, 4, 5]
        for elem in my_list:
            yield (elem)

    local = {}
    exec(result.code, {}, local)
    reader_wapper = local['reader_wapper']
    exec_result = list(reader_wapper(my_external_generator()))
    assert exec_result == [1, 2, 3, 4, 5]
Пример #28
0
def test_print_stmt__protect_chevron_print(c_exec, mocker):
    code, errors = c_exec(PROTECT_PRINT_STATEMENT_WITH_CHEVRON)[:2]

    _getattr_ = mocker.stub()
    _getattr_.side_effect = getattr
    glb = {'_getattr_': _getattr_, '_print_': PrintCollector}

    exec(code, glb)

    stream = mocker.stub()
    stream.write = mocker.stub()
    glb['print_into_stream'](stream)

    stream.write.assert_has_calls(
        [mocker.call('Hello World!'),
         mocker.call('\n')])

    _getattr_.assert_called_once_with(stream, 'write')
def test_async_yield_from(c_exec):
    """`yield from` statement should be allowed."""
    result = c_exec(ASYNC_YIELD_FORM_EXAMPLE)
    assert result.errors == (
        'Line 4: AsyncFunctionDef statements are not allowed.', )
    assert result.code is None
def test_asyncio_yield_from(c_exec):
    """`yield from` statement should be allowed."""
    result = c_exec(ASYNCIO_YIELD_FORM_EXAMPLE)
    assert result.errors == ()
    assert result.code is not None