示例#1
0
def test_with_stmt_subscript(e_exec, mocker):
    _write_ = mocker.stub()
    _write_.side_effect = lambda ob: ob

    glb = {'_write_': _write_}
    e_exec(WITH_STMT_SUBSCRIPT, glb)

    # Test single_key
    ctx = mocker.MagicMock()
    ctx.__enter__.return_value = ctx
    x = {}

    glb['single_key'](ctx, x)

    assert x['key'] == ctx
    _write_.assert_called_once_with(x)
    _write_.reset_mock()

    # Test slice_key
    ctx = mocker.MagicMock()
    ctx.__enter__.return_value = (1, 2)

    x = [0, 0, 0, 0, 0, 0]
    glb['slice_key'](ctx, x)

    assert x == [0, 0, 1, 2, 0, 0, 0]
    _write_.assert_called_once_with(x)
示例#2
0
def test_RestrictingNodeTransformer__test_ternary_if(
        e_exec, mocker):
    src = 'x.y = y.a if y.z else y.b'
    _getattr_ = mocker.stub()
    _getattr_.side_effect = lambda ob, key: ob[key]
    _write_ = mocker.stub()
    _write_.side_effect = lambda ob: ob

    glb = {
        '_getattr_': _getattr_,
        '_write_': _write_,
        'x': mocker.stub(),
        'y': {'a': 'a', 'b': 'b'},
    }

    glb['y']['z'] = True
    e_exec(src, glb)

    assert glb['x'].y == 'a'
    _write_.assert_called_once_with(glb['x'])
    _getattr_.assert_has_calls([
        mocker.call(glb['y'], 'z'),
        mocker.call(glb['y'], 'a')])

    _write_.reset_mock()
    _getattr_.reset_mock()

    glb['y']['z'] = False
    e_exec(src, glb)

    assert glb['x'].y == 'b'
    _write_.assert_called_once_with(glb['x'])
    _getattr_.assert_has_calls([
        mocker.call(glb['y'], 'z'),
        mocker.call(glb['y'], 'b')])
示例#3
0
def test_RestrictingNodeTransformer__visit_FunctionDef__8(
        e_exec, mocker):
    _getiter_ = mocker.stub()
    _getiter_.side_effect = lambda it: it

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

    e_exec('def simple((a, b)): return a, b', glb)

    val = (1, 2)
    ret = glb['simple'](val)
    assert ret == val
    _getiter_.assert_called_once_with(val)
    _getiter_.reset_mock()

    e_exec(NESTED_SEQ_UNPACK, glb)

    val = (1, 2, (3, (4, 5)))
    ret = glb['nested'](val)
    assert ret == (1, 2, 3, 4, 5)
    assert 3 == _getiter_.call_count
    _getiter_.assert_any_call(val)
    _getiter_.assert_any_call(val[2])
    _getiter_.assert_any_call(val[2][1])
    _getiter_.reset_mock()

    ret = glb['nested_with_order']((1, 2), (3, 4))
    assert ret == (1, 2, 3, 4)
    _getiter_.assert_has_calls([
        mocker.call((1, 2)),
        mocker.call((3, 4))])
    _getiter_.reset_mock()
示例#4
0
def test_Guards__write_wrapper__2(e_exec):
    """It wraps setattr and it works when guarded_setattr is implemented."""

    class ObjWithGuardedSetattr:
        my_attr = None

        def __guarded_setattr__(self, key, value):
            setattr(self, key, value)

    set_attribute_using_guarded_setattr_code = '''
myobj_with_guarded_setattr = ObjWithGuardedSetattr()
setattr(myobj_with_guarded_setattr, 'my_attr', 'bar')
    '''

    restricted_globals = dict(
        __builtins__=safe_builtins,
        ObjWithGuardedSetattr=ObjWithGuardedSetattr,
        myobj_with_guarded_setattr=None,
        __name__='restricted_module',
        __metaclass__=type,
        _write_=lambda x: x,
        _getattr_=getattr,)

    e_exec(set_attribute_using_guarded_setattr_code, restricted_globals)
    assert restricted_globals['myobj_with_guarded_setattr'].my_attr == 'bar'
示例#5
0
def test_Guards__guarded_setattr__1(e_exec):
    """It allows use setattr and delattr when _guarded_writes is True.
    """
    class MyObjectD:
        value = None
        _guarded_writes = 1

    setattr_code = '''
my_object_d = MyObjectD()
setattr(my_object_d, 'value', 9999)'''

    delattr_code = "delattr(my_object_d, 'value')"

    restricted_globals = dict(
        __builtins__=safe_builtins,
        MyObjectD=MyObjectD,
        my_object_d=None,
        __name__='restricted_module',
        __metaclass__=type,
        _write_=lambda x: x,
        _getattr_=getattr,)

    e_exec(setattr_code, restricted_globals)
    assert 9999 == restricted_globals['my_object_d'].value

    e_exec(delattr_code, restricted_globals)
    assert None is restricted_globals['my_object_d'].value
示例#6
0
def test_read_slice_subscript_no_step(e_exec, mocker):
    value = None
    _getitem_ = mocker.stub()
    _getitem_.side_effect = lambda ob, index: (ob, index)
    glb = {'_getitem_': _getitem_}
    e_exec(SLICE_SUBSCRIPT_NO_STEP, glb)

    assert (value, slice(1, 2, None)) == glb['slice_subscript_no_step'](value)
示例#7
0
def test_read_simple_subscript(e_exec, mocker):
    value = None
    _getitem_ = mocker.stub()
    _getitem_.side_effect = lambda ob, index: (ob, index)
    glb = {'_getitem_': _getitem_}
    e_exec(SIMPLE_SUBSCRIPTS, glb)

    assert (value, 'b') == glb['simple_subscript'](value)
示例#8
0
def test_tuple_subscript(e_exec, mocker):
    value = None
    _getitem_ = mocker.stub()
    _getitem_.side_effect = lambda ob, index: (ob, index)
    glb = {'_getitem_': _getitem_}
    e_exec(TUPLE_SUBSCRIPTS, glb)

    assert (value, (1, 2)) == glb['tuple_subscript'](value)
示例#9
0
def test_RestrictingNodeTransformer__visit_TryFinally__2(e_exec, mocker):
    """It allows try-except-finally statements."""
    trace = mocker.stub()
    e_exec(TRY_EXCEPT_FINALLY)['try_except_finally'](trace)

    trace.assert_has_calls(
        [mocker.call('try'),
         mocker.call('except'),
         mocker.call('finally')])
示例#10
0
def test_write_subscripts(e_exec, mocker):
    value = {'b': None}
    _write_ = mocker.stub()
    _write_.side_effect = lambda ob: ob
    glb = {'_write_': _write_}
    e_exec(WRITE_SUBSCRIPTS, glb)

    glb['assign_subscript'](value)
    assert value['b'] == 1
def test_RestrictingNodeTransformer__visit_Lambda__12(e_exec):
    """Lambda functions with tuple unpacking and simple params are allowed."""
    restricted_globals = dict(
        g=None,
        _unpack_sequence_=guarded_unpack_sequence,
        _getiter_=default_guarded_getiter,
    )
    e_exec(LAMBDA_FUNC_3, restricted_globals)
    assert (64, 6) == restricted_globals['g']((4, 3), 2)
示例#12
0
def test_del_subscripts(e_exec, mocker):
    value = {'b': None}
    _write_ = mocker.stub()
    _write_.side_effect = lambda ob: ob
    glb = {'_write_': _write_}
    e_exec(DEL_SUBSCRIPT, glb)
    glb['del_subscript'](value)

    assert value == {}
示例#13
0
def test_read_slice_subscript_no_lower_bound(e_exec, mocker):
    value = None
    _getitem_ = mocker.stub()
    _getitem_.side_effect = lambda ob, index: (ob, index)
    glb = {'_getitem_': _getitem_}
    e_exec(SLICE_SUBSCRIPT_NO_LOWER_BOUND, glb)

    assert (value, slice(None, 1,
                         None)) == glb['slice_subscript_no_lower_bound'](
                             value)  # NOQA: E501
示例#14
0
def test_read_extended_slice_subscript(e_exec, mocker):
    value = None
    _getitem_ = mocker.stub()
    _getitem_.side_effect = lambda ob, index: (ob, index)
    glb = {'_getitem_': _getitem_}
    e_exec(EXTENDED_SLICE_SUBSCRIPT, glb)
    ret = glb['extended_slice_subscript'](value)
    ref = (value, (0, slice(None, 1, None), slice(1, None, None),
                   slice(1, 2, None), slice(1, 2, 3)))

    assert ref == ret
示例#15
0
def test_RestrictingNodeTransformer__visit_ClassDef__6(e_exec):
    """It allows to define an ``__init__`` method."""
    restricted_globals = dict(
        t=None,
        _write_=lambda x: x,
        __metaclass__=type,
    )

    e_exec(CONSTRUCTOR_TEST, restricted_globals)
    t = restricted_globals['t']
    assert t.input == 42
示例#16
0
def test_RestrictingNodeTransformer__visit_Attribute__8(e_exec, mocker):
    """It transforms attribute access in lamda default kw to `_write_`."""
    _getattr_ = mocker.Mock()
    _getattr_.side_effect = getattr

    glb = {'_getattr_': _getattr_, 'b': mocker.Mock(b=2)}

    e_exec('lambda_default = lambda x=b.b: x', glb)

    _getattr_.assert_has_calls([mocker.call(glb['b'], 'b')])
    assert glb['lambda_default']() == 2
示例#17
0
def test_Guards__safer_getattr__1(e_exec):
    """It prevents using the format method of a string.

    format() is considered harmful:
    http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
    """
    glb = {
        '__builtins__': safe_builtins,
    }
    with pytest.raises(NotImplementedError) as err:
        e_exec(STRING_DOT_FORMAT_DENIED, glb)
    assert 'Using format() on a str is not safe.' == str(err.value)
示例#18
0
def test_RestrictingNodeTransformer__visit_Attribute__5(e_exec, mocker):
    """It transforms writing to an attribute to `_write_`."""
    glb = {
        '_write_': mocker.stub(),
        'a': mocker.stub(),
    }
    glb['_write_'].return_value = glb['a']

    e_exec("a.b = 'it works'", glb)

    glb['_write_'].assert_called_once_with(glb['a'])
    assert glb['a'].b == 'it works'
示例#19
0
def test_Guards__safer_getattr__3(e_exec):
    """It allows to use `safer_getattr`."""
    restricted_globals = dict(
        __builtins__=safe_builtins,
        __name__=None,
        __metaclass__=type,
        _write_=lambda x: x,
        getattr=safer_getattr,
        result=None,
    )
    e_exec(SAFER_GETATTR_ALLOWED, restricted_globals)
    assert restricted_globals['result'] == 2
示例#20
0
def test_RestrictingNodeTransformer__visit_Attribute__5_5(e_exec, mocker):
    """It transforms deleting of an attribute to `_write_`."""
    glb = {
        '_write_': mocker.stub(),
        'a': mocker.stub(),
    }
    glb['a'].b = 'it exists'
    glb['_write_'].return_value = glb['a']

    e_exec("del a.b", glb)

    glb['_write_'].assert_called_once_with(glb['a'])
    assert not hasattr(glb['a'], 'b')
def test_os_import(e_exec):
    """It does not allow to import anything by default.

    The `__import__` function is not provided as it is not safe.
    """
    # Caution: This test is broken on PyPy until the following issue is fixed:
    # https://bitbucket.org/pypy/pypy/issues/2653
    # PyPy currently ignores the restriction of the `__builtins__`.
    glb = {'__builtins__': safe_builtins}

    with pytest.raises(ImportError) as err:
        e_exec(OS_IMPORT_EXAMPLE, glb)
    assert '__import__ not found' == str(err.value)
示例#22
0
def test_RestrictingNodeTransformer__visit_ClassDef__8(e_exec):
    """It allows to define a ``__contains__`` method."""
    restricted_globals = dict(
        result1=None,
        result2=None,
        _getattr_=getattr,
        _write_=lambda x: x,
        __metaclass__=type,
    )

    e_exec(CONTAINER_TEST, restricted_globals)
    assert restricted_globals['result1'] is True
    assert restricted_globals['result2'] is True
def test_RestrictingNodeTransformer__guard_iter__1(e_exec, mocker):
    it = (1, 2, 3)
    _getiter_ = mocker.stub()
    _getiter_.side_effect = lambda x: x
    glb = {'_getiter_': _getiter_}
    e_exec(ITERATORS, glb)

    ret = glb['for_loop'](it)
    assert 6 == ret
    _getiter_.assert_called_once_with(it)
    _getiter_.reset_mock()

    ret = glb['nested_for_loop']((1, 2), (3, 4))
    assert 20 == ret
    _getiter_.assert_has_calls([mocker.call((1, 2)), mocker.call((3, 4))])
    _getiter_.reset_mock()

    ret = glb['dict_comp'](it)
    assert {1: 2, 2: 4, 3: 6} == ret
    _getiter_.assert_called_once_with(it)
    _getiter_.reset_mock()

    ret = glb['list_comp'](it)
    assert [2, 4, 6] == ret
    _getiter_.assert_called_once_with(it)
    _getiter_.reset_mock()

    ret = glb['nested_list_comp']((1, 2), (3, 4))
    assert [5, 6] == ret
    _getiter_.assert_has_calls([mocker.call((1, 2)), mocker.call((3, 4))])
    _getiter_.reset_mock()

    ret = glb['set_comp'](it)
    assert {2, 4, 6} == ret
    _getiter_.assert_called_once_with(it)
    _getiter_.reset_mock()

    ret = glb['generator'](it)
    assert isinstance(ret, types.GeneratorType)
    assert list(ret) == [2, 4, 6]
    _getiter_.assert_called_once_with(it)
    _getiter_.reset_mock()

    ret = glb['nested_generator']((0, 1, 2), (1, 2))
    assert isinstance(ret, types.GeneratorType)
    assert list(ret) == [2, 3, 3, 4]
    _getiter_.assert_has_calls(
        [mocker.call((0, 1, 2)),
         mocker.call((1, 2)),
         mocker.call((1, 2))])
    _getiter_.reset_mock()
示例#24
0
def test_RestrictingNodeTransformer__visit_Attribute__7(e_exec, mocker):
    """It transforms attribute access in function default kw to `_write_`."""
    _getattr_ = mocker.Mock()
    _getattr_.side_effect = getattr

    glb = {
        '_getattr_': _getattr_,
        'a': mocker.Mock(a=1),
    }

    e_exec(TRANSFORM_ATTRIBUTE_ACCESS_FUNCTION_DEFAULT, glb)

    _getattr_.assert_has_calls([mocker.call(glb['a'], 'a')])
    assert glb['func_default']() == 1
示例#25
0
def test_RestrictingNodeTransformer__visit_ExceptHandler__1(e_exec, mocker):
    _getiter_ = mocker.stub()
    _getiter_.side_effect = lambda it: it

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

    e_exec(EXCEPT_WITH_TUPLE_UNPACK, glb)
    err = Exception(1, (2, 3))
    ret = glb['tuple_unpack'](err)
    assert ret == 6

    _getiter_.assert_has_calls([mocker.call(err), mocker.call((2, 3))])
示例#26
0
def test_RestrictingNodeTransformer__visit_ClassDef__3(e_exec):
    """It applies the global __metaclass__ to all generated classes if present.
    """
    def _metaclass(name, bases, dict):
        ob = type(name, bases, dict)
        ob.foo = 2411
        return ob

    restricted_globals = dict(__metaclass__=_metaclass,
                              b=None,
                              _getattr_=getattr)

    e_exec(IMPLICIT_METACLASS, restricted_globals)

    assert restricted_globals['b'] == 2411
示例#27
0
def test_RestrictingNodeTransformer__visit_Call__2(e_exec, mocker):
    _apply_ = mocker.stub()
    _apply_.side_effect = lambda func, *args, **kwargs: func(*args, **kwargs)

    glb = {'_apply_': _apply_, 'foo': lambda *args, **kwargs: (args, kwargs)}

    e_exec(FUNCTIONC_CALLS, glb)

    ret = glb['positional_args']()
    assert ((1, 2), {}) == ret
    assert _apply_.called is False
    _apply_.reset_mock()

    ret = glb['star_args']()
    ref = ((3, 4), {})
    assert ref == ret
    _apply_.assert_called_once_with(glb['foo'], *ref[0])
    _apply_.reset_mock()

    ret = glb['positional_and_star_args']()
    ref = ((1, 2, 3, 4), {})
    assert ref == ret
    _apply_.assert_called_once_with(glb['foo'], *ref[0])
    _apply_.reset_mock()

    ret = glb['kw_args']()
    ref = ((), {'x': 5, 'y': 6})
    assert ref == ret
    _apply_.assert_called_once_with(glb['foo'], **ref[1])
    _apply_.reset_mock()

    ret = glb['star_and_kw']()
    ref = ((3, 4), {'x': 5, 'y': 6})
    assert ref == ret
    _apply_.assert_called_once_with(glb['foo'], *ref[0], **ref[1])
    _apply_.reset_mock()

    ret = glb['positional_and_star_and_kw_args']()
    ref = ((1, 3, 4), {'x': 5, 'y': 6})
    assert ref == ret
    _apply_.assert_called_once_with(glb['foo'], *ref[0], **ref[1])
    _apply_.reset_mock()

    ret = glb['positional_and_star_and_keyword_and_kw_args']()
    ref = ((1, 2, 3, 4), {'x': 5, 'y': 6, 'r': 9})
    assert ref == ret
    _apply_.assert_called_once_with(glb['foo'], *ref[0], **ref[1])
    _apply_.reset_mock()
示例#28
0
def test_RestrictingNodeTransformer__visit_ClassDef__5(e_exec):
    """It preserves base classes and decorators for classes."""

    restricted_globals = dict(comb=None,
                              _getattr_=getattr,
                              _write_=lambda x: x,
                              __metaclass__=type,
                              __name__='restricted_module',
                              __builtins__=safe_builtins)

    e_exec(DECORATED_CLASS, restricted_globals)

    comb = restricted_globals['comb']
    assert comb.class_att == 2342
    assert comb.base_att == 42
    assert comb.wrap_att == 23
示例#29
0
def test_Guards__guarded_unpack_sequence__1(e_exec, mocker):
    """If the sequence is shorter then expected the interpreter will raise
    'ValueError: need more than X value to unpack' anyway
    => No childs are unpacked => nothing to protect."""
    src = "one, two, three = (1, 2)"

    _getiter_ = mocker.stub()
    _getiter_.side_effect = lambda it: it
    glb = {
        '_getiter_': _getiter_,
        '_unpack_sequence_': guarded_unpack_sequence,
    }

    with pytest.raises(ValueError) as excinfo:
        e_exec(src, glb)
    assert 'values to unpack' in str(excinfo.value)
    assert _getiter_.call_count == 1
示例#30
0
def test_RestrictingNodeTransformer__visit_Lambda__9(e_exec, mocker):
    _getiter_ = mocker.stub()
    _getiter_.side_effect = lambda it: it
    glb = {
        '_getiter_': _getiter_,
        '_unpack_sequence_': guarded_unpack_sequence,
        '_getattr_': lambda ob, val: getattr(ob, val)
    }

    src = "m = lambda (a, (b, c)), *ag, **kw: a+b+c+sum(ag)+sum(kw.values())"
    e_exec(src, glb)

    ret = glb['m']((1, (2, 3)), 4, 5, 6, g=7, e=8)
    assert ret == 36
    assert 2 == _getiter_.call_count
    _getiter_.assert_any_call((1, (2, 3)))
    _getiter_.assert_any_call((2, 3))