コード例 #1
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_insert_on_long_tuple(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(
            UniversalLupleType(
                [ IntegerType(), IntegerType() ],
                IntegerType()
            )
        )

        foo.insert(0, 2)
        self.assertEqual(list(foo), [ 2, 4, 6, 8 ])
コード例 #2
0
def list_template_op(values):
    for v in values:
        check_is_opcode(v)
    return PythonObject(
        {
            "opcode":
            "template",
            "opcodes":
            PythonList(
                [PythonList([literal_op(i), v]) for i, v in enumerate(values)])
        },
        debug_reason="code")
コード例 #3
0
ファイル: test.py プロジェクト: richardhills/lockdown
 def test_misc2(self):
     # Came up writing test_misc1
     PythonObject({
         "local": PythonList([ 39, 3 ])
     }, bind=UniversalObjectType({
         "local": UniversalTupleType([ IntegerType(), IntegerType() ])
     }, wildcard_type=RICH_READONLY_TYPE))
コード例 #4
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_basic_tuple_of_ints(self):
        foo = PythonList([ 1, 2, 3 ])

        get_manager(foo).add_composite_type(UniversalTupleType([ IntegerType(), IntegerType(), IntegerType() ]))

        foo[0] = 42
        self.assertEqual(foo[0], 42)
コード例 #5
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_basic_list_of_ints(self):
        foo = PythonList([ 1, 2, 3 ])

        get_manager(foo).add_composite_type(UniversalListType(IntegerType()))

        foo[0] = 42
        self.assertEqual(foo[0], 42)
コード例 #6
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_outside_tuple_access_allowed(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalListType(AnyType()))

        self.assertEqual(foo[2], 8)
        foo[2] = "hello"
        self.assertEqual(foo[2], "hello")
コード例 #7
0
def object_template_op(values, debug_reason="code", **kwargs):
    values_list = []

    for k, v in values.items():
        check_is_opcode(v)
        if isinstance(k, basestring):
            k = literal_op(k)

        values_list.append(PythonList([k, v]))

    return PythonObject(spread_dict(
        {
            "opcode": "template",
            "opcodes": PythonList(values_list, debug_reason=debug_reason)
        }, **kwargs),
                        debug_reason=debug_reason)
コード例 #8
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_outside_tuple_access_blocked(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalTupleType([ IntegerType(), AnyType() ]))

        with self.assertRaises(IndexError):
            foo[2]
        with self.assertRaises(IndexError):
            foo[2] = "hello"
コード例 #9
0
def comma_op(*opcodes):
    for v in opcodes:
        check_is_opcode(v)
    return PythonObject({
        "opcode": "comma",
        "opcodes": PythonList(opcodes)
    },
                        debug_reason="code")
コード例 #10
0
ファイル: test.py プロジェクト: richardhills/lockdown
 def test_misc1(self):
     # Came up testing lockdown local variable binding
     PythonObject({
         "local": PythonList([ 39, 3 ]),
         "types": PythonObject({})
     }, bind=UniversalObjectType({
         "local": UniversalTupleType([ IntegerType(), IntegerType() ]),
         "types": DEFAULT_READONLY_COMPOSITE_TYPE
     }, wildcard_type=RICH_READONLY_TYPE))
コード例 #11
0
ファイル: test.py プロジェクト: richardhills/lockdown
 def test_1(self):
     code = parse("""
         function(int foo) => int {
             return foo;
         }
     """,
                  debug=True)
     _, result = bootstrap_function(code, argument=PythonList([5]))
     self.assertEqual(result.value, 5)
コード例 #12
0
ファイル: test.py プロジェクト: richardhills/lockdown
 def test_3(self):
     code = parse("""
         function(any foo) {
             return foo + 3;
         }
     """,
                  debug=True)
     _, result = bootstrap_function(code,
                                    argument=PythonList([5]),
                                    check_safe_exit=False)
     self.assertEqual(result.value, 8)
コード例 #13
0
def match_op(value_expression, matchers):
    check_is_opcode(value_expression)
    for matcher in matchers:
        check_is_opcode(matcher)
    return PythonObject(
        {
            "opcode": "match",
            "value": value_expression,
            "matchers": PythonList(matchers)
        },
        debug_reason="code")
コード例 #14
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_mixed_type_tuple(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalTupleType([ IntegerType(), AnyType() ]))

        with self.assertRaises(TypeError):
            foo[0] = "hello"

        self.assertEqual(foo[0], 4)

        foo[1] = "what"
        self.assertEqual(foo[1], "what")
コード例 #15
0
ファイル: test.py プロジェクト: richardhills/lockdown
 def test_2(self):
     code = parse("""
         function(any foo) {
             return foo.bar;
         }
     """,
                  debug=True)
     _, result = bootstrap_function(
         code,
         argument=PythonList([
             PythonObject({"bar": 5}, bind=DEFAULT_READONLY_COMPOSITE_TYPE)
         ]),
         check_safe_exit=False)
     self.assertEqual(result.value, 5)
コード例 #16
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_add_locals(self):
        func = function_lit(
            no_value_type(), build_break_types(int_type()),
            return_op(
                addition_op(
                    dereference_op(
                        dereference_op(
                            dereference_op(context_op(), literal_op("outer"),
                                           True), literal_op("local"), True),
                        literal_op(0), True),
                    dereference_op(
                        dereference_op(
                            dereference_op(context_op(), literal_op("outer"),
                                           True), literal_op("local"), True),
                        literal_op(1), True))))

        context = PythonObject(
            {
                "local":
                PythonList([39, 3]),
                "_types":
                PythonObject({
                    "local":
                    UniversalTupleType([IntegerType(),
                                        IntegerType()])
                })
            },
            bind=UniversalObjectType({
                "local":
                UniversalTupleType([IntegerType(),
                                    IntegerType()]),
                "_types":
                DEFAULT_READONLY_COMPOSITE_TYPE
            }))

        _, result = bootstrap_function(func, outer_context=context)

        self.assertEquals(result.caught_break_mode, "return")
        self.assertEquals(result.value, 42)
コード例 #17
0
def build_closed_function_type(data):
    if not isinstance(data._get("break_types"), Universal):
        raise FatalError()
    for mode, break_types in data._get("break_types")._items():
        if not isinstance(mode, basestring):
            raise FatalError()
        if not isinstance(break_types, Universal):
            raise FatalError()
        for break_type in break_types._values():
            if not isinstance(break_type, Universal):
                raise FatalError(break_type)

    return ClosedFunctionType(
        enrich_type(data._get("argument")),
        PythonDict(
            {
                mode: PythonList(
                    [enrich_break_type(b) for b in break_types._values()])
                for mode, break_types in data._get("break_types")._items()
            },
            bind=DEFAULT_READONLY_COMPOSITE_TYPE,
            debug_reason="type"))
コード例 #18
0
ファイル: test.py プロジェクト: richardhills/lockdown
 def test_simple_list_assignment(self):
     foo = PythonList([ 4, 6, 8 ])
     get_manager(foo).add_composite_type(UniversalListType(IntegerType()))
コード例 #19
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_set_on_non_sparse_blocked(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalListType(IntegerType(), is_sparse=False))

        with self.assertRaises(IndexError):
            foo[4] = 12
コード例 #20
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_incorrect_type_blocked(self):
        foo = PythonList([ 4, 6, 8 ])

        with self.assertRaises(Exception):
            get_manager(foo).add_composite_type(UniversalListType(StringType()))
コード例 #21
0
ファイル: function.py プロジェクト: richardhills/lockdown
def prepare(data, outer_context, frame_manager, immediate_context=None):
    if not isinstance(data, Composite):
        raise FatalError()
    get_manager(data).add_composite_type(DEFAULT_READONLY_COMPOSITE_TYPE)

    if not hasattr(data, "code"):
        raise PreparationException("Code missing from function")

    actual_break_types_factory = BreakTypesFactory(None)

    context = Universal(True,
                        initial_wrapped={"prepare": outer_context},
                        bind=DEFAULT_READONLY_COMPOSITE_TYPE,
                        debug_reason="static-prepare-context")

    static = evaluate(
        enrich_opcode(
            data.static,
            combine(type_conditional_converter,
                    UnboundDereferenceBinder(context))), context,
        frame_manager)

    get_manager(static).add_composite_type(DEFAULT_READONLY_COMPOSITE_TYPE)

    argument_type = enrich_type(static._get("argument"))
    outer_type = enrich_type(static._get("outer"))

    suggested_argument_type = suggested_outer_type = None

    if immediate_context:
        suggested_argument_type = immediate_context.get(
            "suggested_argument_type", None)
        suggested_outer_type = immediate_context.get("suggested_outer_type",
                                                     None)

    if suggested_outer_type is None:
        suggested_outer_type = NoValueType()

    try:
        argument_type = prepare_piece_of_context(argument_type,
                                                 suggested_argument_type)
    except DanglingInferredType:
        raise PreparationException(
            "Failed to infer argument types in {} from {}".format(
                argument_type, suggested_argument_type))
    try:
        outer_type = prepare_piece_of_context(outer_type, suggested_outer_type)
    except DanglingInferredType:
        raise PreparationException(
            "Failed to infer outer types in {} from {}".format(
                argument_type, suggested_argument_type))

    local_type = enrich_type(static._get("local"))

    context = Universal(
        True,
        initial_wrapped={
            "prepare":
            outer_context,
            "static":
            static,
            #        "types": derich_type(
            #            UniversalObjectType({
            #                "outer": outer_type,
            #                "argument": argument_type,
            ##                "local": local_type
            #            }), {}
            #        ),
            "_types":
            Universal(
                True,
                initial_wrapped={
                    "outer": outer_type,
                    "argument": argument_type,
                    #            "local": local_type
                },
                debug_reason="local-prepare-context")
        },
        bind=DEFAULT_READONLY_COMPOSITE_TYPE,
        debug_reason="local-prepare-context")

    # optimization to avoid generating context_type lazily
    get_manager(context)._context_type = UniversalObjectType(
        {
            "outer": outer_type,
            "argument": argument_type,
            #        "local": local_type
        },
        wildcard_type=AnyType(),
        name="local-prepare-context-type")

    local_initializer = enrich_opcode(
        data.local_initializer,
        combine(type_conditional_converter, UnboundDereferenceBinder(context)))
    actual_local_type, local_other_break_types = get_expression_break_types(
        local_initializer, context, frame_manager)

    get_manager(context).remove_composite_type(DEFAULT_READONLY_COMPOSITE_TYPE)

    if actual_local_type is MISSING:
        raise PreparationException(
            "Actual local type missing. local_other_break_types: {}".format(
                local_other_break_types))

    actual_local_type = flatten_out_types(actual_local_type)

    local_type = prepare_piece_of_context(local_type, actual_local_type)

    local_type_reasoner = Reasoner()

    if not local_type.is_copyable_from(actual_local_type, local_type_reasoner):
        raise PreparationException("Invalid local type: {} != {}: {}".format(
            local_type, actual_local_type, local_type_reasoner.to_message()))

    actual_break_types_factory.merge(local_other_break_types)

    declared_break_types = PythonDict({
        mode: PythonList([
            enrich_break_type(break_type)
            for break_type in break_types._values()
        ])
        for mode, break_types in static._get("break_types")._items()
    })

    get_manager(declared_break_types).add_composite_type(
        DEFAULT_READONLY_COMPOSITE_TYPE)

    context = Universal(
        True,
        initial_wrapped={
            "prepare":
            outer_context,
            "static":
            static,
            #        "types": derich_type(
            #            UniversalObjectType({
            #                "outer": outer_type,
            #                "argument": argument_type,
            #                "local": local_type
            #            }), {}
            #        ),
            "_types":
            Universal(True,
                      initial_wrapped={
                          "outer": outer_type,
                          "argument": argument_type,
                          "local": local_type
                      },
                      debug_reason="code-prepare-context")
        },
        bind=DEFAULT_READONLY_COMPOSITE_TYPE,
        debug_reason="code-prepare-context")

    get_manager(context)._context_type = UniversalObjectType(
        {
            "outer": outer_type,
            "argument": argument_type,
            "local": local_type
        },
        wildcard_type=AnyType(),
        name="code-prepare-context-type")

    code = enrich_opcode(
        data.code,
        combine(type_conditional_converter, UnboundDereferenceBinder(context)))

    code_break_types = code.get_break_types(context, frame_manager)

    get_manager(context).remove_composite_type(DEFAULT_READONLY_COMPOSITE_TYPE)

    actual_break_types_factory.merge(code_break_types)

    final_declared_break_types = BreakTypesFactory(None)

    for mode, actual_break_types in actual_break_types_factory.build().items():
        for actual_break_type in actual_break_types:
            declared_break_types_for_mode = declared_break_types.get(
                mode, declared_break_types.get("wildcard", []))
            for declared_break_type_for_mode in declared_break_types_for_mode:
                # Check if this declared_break_type_for_mode is enough to capture the actual_break_types
                declared_out = declared_break_type_for_mode["out"]
                declared_in = declared_break_type_for_mode.get("in", None)
                actual_out = actual_break_type["out"]
                actual_in = actual_break_type.get("in", None)

                final_out = prepare_lhs_type(declared_out, actual_out)
                if declared_in is not None:
                    if isinstance(declared_in,
                                  InferredType) and actual_in is None:
                        final_in = None
                    else:
                        final_in = prepare_lhs_type(declared_in, actual_in)
                else:
                    final_in = declared_in


#                 if declared_in is not None and actual_in is None:
#                     continue

                out_is_compatible = final_out.is_copyable_from(
                    actual_out, DUMMY_REASONER)
                in_is_compatible = final_in is None or actual_in.is_copyable_from(
                    final_in, DUMMY_REASONER)

                if out_is_compatible and in_is_compatible:
                    final_declared_break_types.add(mode, final_out, final_in)
                    break
            else:
                raise PreparationException(
                    """Nothing declared for {}, {}.\nFunction declares break types {}.\nBut local_initialization breaks {}, code breaks {}"""
                    .format(mode, actual_break_type, declared_break_types,
                            local_other_break_types, code_break_types))

    return OpenFunction(data, code, outer_context, static, argument_type,
                        outer_type, local_type, local_initializer,
                        final_declared_break_types.build())
コード例 #22
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_insert_at_start(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalListType(IntegerType()))

        foo.insert(0, 2)
        self.assertEqual(list(foo), [ 2, 4, 6, 8 ])
コード例 #23
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_combined_const_list_and_tuple(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalLupleType([ IntegerType(), AnyType() ], Const(AnyType())))

        self.assertEqual(foo[2], 8)
コード例 #24
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_list_set_and_get(self):
        foo = PythonList([ 123 ])
        foo._set(0, 42)

        self.assertEqual(foo._get(0), 42)
コード例 #25
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_list_insert(self):
        foo = PythonList([ 123 ])
        foo._insert(0, 42)

        self.assertEqual(foo._to_list(), [ 42, 123 ])
コード例 #26
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_list_appending_blocked(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalTupleType([]))

        with self.assertRaises(IndexError):
            foo.append(10)
コード例 #27
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_list_modification_right_type_ok(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalListType(IntegerType()))

        foo.append(10)
コード例 #28
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_bounds_enforced(self):
        foo = PythonList([ 1, 2 ])

        with self.assertRaises(Exception):
            get_manager(foo).add_composite_type(UniversalTupleType([ IntegerType(), IntegerType(), IntegerType() ]))
コード例 #29
0
ファイル: managers.py プロジェクト: richardhills/lockdown
def get_manager(obj, trigger=None):
    """
    Returns the run time CompositeManager for an object (if it needs one!)

    CompositeManager objects are needed for objects that can have CompositeTypes. In Lockdown, this is
    Python Lists, Objects, Dictionaries, Tuples, etc

    CompositeManagers exist alongside the base Python objects for their lifetime. They are GCed when the
    Python object is GCed.

    When code interacts with these base Python objects, they will often use the CompositeManager to
    determine what interactions are allowed or not, to maintain consistency with the rest of the Lockdown
    application. The CompositeManager maintains a weak ref to the object for which it is responsible.
    """
    manager = managers_by_object_id.get(id(obj), None)
    if manager:
        return manager

    if isinstance(obj, InternalMarker):
        return None

    from lockdown.type_system.composites import Composite
    if not isinstance(obj, (list, tuple, dict, Composite)) and not hasattr(
            obj, "__dict__"):
        return None

    if isinstance(obj, Type):
        return None

    from lockdown.executor.function import LockdownFunction, OpenFunction
    if isinstance(obj, (LockdownFunction, OpenFunction)):
        return None

    from lockdown.executor.opcodes import Opcode
    if isinstance(obj, Opcode):
        return None

    from lockdown.type_system.composites import CompositeObjectManager

    old_obj = obj
    if isinstance(obj, Composite):
        manager = CompositeObjectManager(obj, obj_cleared_callback, False)
    elif isinstance(obj, list):
        if not get_environment().consume_python_objects:
            raise FatalError()
        from lockdown.type_system.universal_type import PythonList
        obj = PythonList(obj)
        replace_all_refs(old_obj, obj)
        manager = CompositeObjectManager(obj, obj_cleared_callback, False)
    elif isinstance(obj, tuple):
        if not get_environment().consume_python_objects:
            raise FatalError()
        from lockdown.type_system.universal_type import PythonList
        obj = PythonList(obj)
        replace_all_refs(old_obj, obj)
        manager = CompositeObjectManager(obj, obj_cleared_callback, False)
    elif isinstance(obj, dict):
        if not get_environment().consume_python_objects:
            raise FatalError()
        from lockdown.type_system.universal_type import PythonDict
        obj = PythonDict(obj, debug_reason="monkey-patch")
        replace_all_refs(old_obj, obj)
        manager = CompositeObjectManager(obj, obj_cleared_callback, True)
    elif isinstance(obj, object) and hasattr(obj, "__dict__"):
        if not get_environment().consume_python_objects:
            raise FatalError()
        from lockdown.type_system.universal_type import PythonObject
        original_type = obj.__class__
        new_type = type(
            "Lockdown{}".format(original_type.__name__).encode("utf-8"), (
                PythonObject,
                original_type,
            ), {})
        obj = new_type(obj.__dict__)
        replace_all_refs(old_obj, obj)
        manager = CompositeObjectManager(obj, obj_cleared_callback, True)
        manager.debug_reason = "monkey-patch"
    else:
        raise FatalError()

    managers_by_object_id[id(obj)] = manager

    return manager
コード例 #30
0
ファイル: test.py プロジェクト: richardhills/lockdown
    def test_list_modification_wrong_type_blocked(self):
        foo = PythonList([ 4, 6, 8 ])
        get_manager(foo).add_composite_type(UniversalListType(IntegerType()))

        with self.assertRaises(TypeError):
            foo.append("hello")