Skip to content

Commit

Permalink
add defensive check
Browse files Browse the repository at this point in the history
  • Loading branch information
dsainati1 committed Oct 17, 2023
1 parent 3e0f26a commit 346f71a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 44 deletions.
17 changes: 17 additions & 0 deletions runtime/interpreter/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,23 @@ func (e ValueTransferTypeError) Error() string {
)
}

// UnexpectedMappedEntitlementError
type UnexpectedMappedEntitlementError struct {
Type sema.Type
LocationRange
}

var _ errors.InternalError = UnexpectedMappedEntitlementError{}

func (UnexpectedMappedEntitlementError) IsInternalError() {}

func (e UnexpectedMappedEntitlementError) Error() string {
return fmt.Sprintf(
"invalid transfer of value: found an unexpected runtime mapped entitlement `%s`",
e.Type.QualifiedString(),
)
}

// ResourceConstructionError
type ResourceConstructionError struct {
CompositeType *sema.CompositeType
Expand Down
8 changes: 8 additions & 0 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,14 @@ func (interpreter *Interpreter) convert(value Value, valueType, targetType sema.
// transferring a reference at runtime does not change its entitlements; this is so that an upcast reference
// can later be downcast back to its original entitlement set

// check defensively that we never create a runtime mapped entitlement value
if _, isMappedAuth := unwrappedTargetType.Authorization.(*sema.EntitlementMapAccess); isMappedAuth {
panic(UnexpectedMappedEntitlementError{
Type: unwrappedTargetType,
LocationRange: locationRange,
})
}

switch ref := value.(type) {
case *EphemeralReferenceValue:
return NewEphemeralReferenceValue(
Expand Down
44 changes: 0 additions & 44 deletions runtime/tests/checker/entitlements_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7587,50 +7587,6 @@ func TestCheckEntitlementMappingComplexFields(t *testing.T) {
require.IsType(t, &sema.TypeMismatchError{}, errors[0])
})

t.Run("lambda escape", func(t *testing.T) {
t.Parallel()

_, err := ParseAndCheck(t, `
entitlement Inner1
entitlement Inner2
entitlement Outer1
entitlement Outer2
entitlement mapping MyMap {
Outer1 -> Inner1
Outer2 -> Inner2
}
struct InnerObj {
access(Inner1) fun first(): Int{ return 9999 }
access(Inner2) fun second(): Int{ return 8888 }
}
struct Carrier{
access(MyMap) let arr: [auth(MyMap) &InnerObj]
init() {
self.arr = [&InnerObj()]
}
}
struct FuncGenerator {
access(MyMap) fun generate(): auth(MyMap) &Int? {
fun innerFunc(_ param: auth(MyMap) &InnerObj): Int {
return 123;
}
var f = innerFunc; // will fail if we're called via a reference
return nil;
}
}
fun foo() {
(&FuncGenerator() as auth(Outer1) &FuncGenerator).generate()
}
`)

errors := RequireCheckerErrors(t, err, 1)
require.IsType(t, &sema.TypeMismatchError{}, errors[0])
})

t.Run("dictionary mapped field", func(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 346f71a

Please sign in to comment.