Skip to content

Commit

Permalink
Merge pull request #2598 from onflow/supun/use-builtin-entitlements
Browse files Browse the repository at this point in the history
Add builtin entitlements to array/dictionary functions
  • Loading branch information
SupunS authored Jul 6, 2023
2 parents e9508ca + aaef3a3 commit 750be9f
Show file tree
Hide file tree
Showing 14 changed files with 833 additions and 49 deletions.
4 changes: 2 additions & 2 deletions runtime/convertValues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1949,7 +1949,7 @@ func TestExportReferenceValue(t *testing.T) {
var v:[AnyStruct] = []
acct.save(v, to: /storage/x)
var ref = acct.borrow<&[AnyStruct]>(from: /storage/x)!
var ref = acct.borrow<auth(Insertable) &[AnyStruct]>(from: /storage/x)!
ref.append(ref)
return ref
}
Expand Down Expand Up @@ -1984,7 +1984,7 @@ func TestExportReferenceValue(t *testing.T) {
var v:[AnyStruct] = []
acct.save(v, to: /storage/x)
var ref1 = acct.borrow<&[AnyStruct]>(from: /storage/x)!
var ref1 = acct.borrow<auth(Insertable) &[AnyStruct]>(from: /storage/x)!
var ref2 = acct.borrow<&[AnyStruct]>(from: /storage/x)!
ref1.append(ref2)
Expand Down
16 changes: 8 additions & 8 deletions runtime/resource_duplicate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ func TestRuntimeResourceDuplicationUsingDestructorIteration(t *testing.T) {
// --- this code actually makes use of the vuln ---
access(all) resource DummyResource {
access(all) var dictRef: &{Bool: AnyResource};
access(all) var arrRef: &[Vault];
access(all) var dictRef: auth(Mutable) &{Bool: AnyResource};
access(all) var arrRef: auth(Mutable) &[Vault];
access(all) var victim: @Vault;
init(dictRef: &{Bool: AnyResource}, arrRef: &[Vault], victim: @Vault) {
init(dictRef: auth(Mutable) &{Bool: AnyResource}, arrRef: auth(Mutable) &[Vault], victim: @Vault) {
self.dictRef = dictRef;
self.arrRef = arrRef;
self.victim <- victim;
Expand All @@ -85,8 +85,8 @@ func TestRuntimeResourceDuplicationUsingDestructorIteration(t *testing.T) {
access(all) fun duplicateResource(victim1: @Vault, victim2: @Vault): @[Vault]{
let arr : @[Vault] <- [];
let dict: @{Bool: DummyResource} <- { }
let ref = &dict as &{Bool: AnyResource};
let arrRef = &arr as &[Vault];
let ref = &dict as auth(Mutable) &{Bool: AnyResource};
let arrRef = &arr as auth(Mutable) &[Vault];
var v1: @DummyResource? <- create DummyResource(dictRef: ref, arrRef: arrRef, victim: <- victim1);
dict[false] <-> v1;
Expand Down Expand Up @@ -372,9 +372,9 @@ func TestRuntimeResourceDuplicationUsingDestructorIteration(t *testing.T) {
script := `
access(all) resource Vault {
access(all) var balance: UFix64
access(all) var arrRef: &[Vault]
access(all) var arrRef: auth(Mutable) &[Vault]
init(balance: UFix64, _ arrRef: &[Vault]) {
init(balance: UFix64, _ arrRef: auth(Mutable) &[Vault]) {
self.balance = balance
self.arrRef = arrRef;
}
Expand All @@ -397,7 +397,7 @@ func TestRuntimeResourceDuplicationUsingDestructorIteration(t *testing.T) {
access(all) fun main(): UFix64 {
let arr: @[Vault] <- []
let arrRef = &arr as &[Vault];
let arrRef = &arr as auth(Mutable) &[Vault];
var v1 <- create Vault(balance: 1000.0, arrRef); // This will be duplicated
var v2 <- create Vault(balance: 1.0, arrRef); // This will be lost
Expand Down
6 changes: 3 additions & 3 deletions runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,7 @@ func TestRuntimeStorageMultipleTransactionsResourceWithArray(t *testing.T) {
prepare(signer: AuthAccount) {
signer.save(<-createContainer(), to: /storage/container)
signer.link<&Container>(/public/container, target: /storage/container)
signer.link<auth(Insertable) &Container>(/public/container, target: /storage/container)
}
}
`)
Expand All @@ -2017,7 +2017,7 @@ func TestRuntimeStorageMultipleTransactionsResourceWithArray(t *testing.T) {
prepare(signer: AuthAccount) {
let publicAccount = getAccount(signer.address)
let ref = publicAccount.getCapability(/public/container)
.borrow<&Container>()!
.borrow<auth(Insertable) &Container>()!
let length = ref.values.length
ref.appendValue(1)
Expand All @@ -2034,7 +2034,7 @@ func TestRuntimeStorageMultipleTransactionsResourceWithArray(t *testing.T) {
let publicAccount = getAccount(signer.address)
let ref = publicAccount
.getCapability(/public/container)
.borrow<&Container>()!
.borrow<auth(Insertable) &Container>()!
let length = ref.values.length
ref.appendValue(2)
Expand Down
5 changes: 3 additions & 2 deletions runtime/sema/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1904,10 +1904,11 @@ func (checker *Checker) checkEntitlementMapAccess(
return
}

// otherwise, mapped entitlements may only be used in structs and resources
// otherwise, mapped entitlements may only be used in structs, resources and attachments
if containerKind == nil ||
(*containerKind != common.CompositeKindResource &&
*containerKind != common.CompositeKindStructure) {
*containerKind != common.CompositeKindStructure &&
*containerKind != common.CompositeKindAttachment) {
checker.report(
&InvalidMappedEntitlementMemberError{
Pos: startPos,
Expand Down
35 changes: 26 additions & 9 deletions runtime/sema/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,16 @@ It does not modify the original array.
If either of the parameters are out of the bounds of the array, or the indices are invalid (` + "`from > upTo`" + `), then the function will fail.
`

var insertableEntitledAccess = NewEntitlementSetAccess(
[]*EntitlementType{InsertableEntitlement, MutableEntitlement},
Disjunction,
)

var removableEntitledAccess = NewEntitlementSetAccess(
[]*EntitlementType{RemovableEntitlement, MutableEntitlement},
Disjunction,
)

func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {

members := map[string]MemberResolver{
Expand Down Expand Up @@ -2048,9 +2058,10 @@ func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {
Mutating: true,
Resolve: func(memoryGauge common.MemoryGauge, identifier string, targetRange ast.Range, report func(error)) *Member {
elementType := arrayType.ElementType(false)
return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
arrayType,
insertableEntitledAccess,
identifier,
ArrayAppendFunctionType(elementType),
arrayTypeAppendFunctionDocString,
Expand All @@ -2075,9 +2086,10 @@ func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {
)
}

return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
arrayType,
insertableEntitledAccess,
identifier,
ArrayAppendAllFunctionType(arrayType),
arrayTypeAppendAllFunctionDocString,
Expand Down Expand Up @@ -2146,9 +2158,10 @@ func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {

elementType := arrayType.ElementType(false)

return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
arrayType,
insertableEntitledAccess,
identifier,
ArrayInsertFunctionType(elementType),
arrayTypeInsertFunctionDocString,
Expand All @@ -2163,9 +2176,10 @@ func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {

elementType := arrayType.ElementType(false)

return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
arrayType,
removableEntitledAccess,
identifier,
ArrayRemoveFunctionType(elementType),
arrayTypeRemoveFunctionDocString,
Expand All @@ -2180,12 +2194,12 @@ func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {

elementType := arrayType.ElementType(false)

return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
arrayType,
removableEntitledAccess,
identifier,
ArrayRemoveFirstFunctionType(elementType),

arrayTypeRemoveFirstFunctionDocString,
)
},
Expand All @@ -2198,9 +2212,10 @@ func getArrayMembers(arrayType ArrayType) map[string]MemberResolver {

elementType := arrayType.ElementType(false)

return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
arrayType,
removableEntitledAccess,
identifier,
ArrayRemoveLastFunctionType(elementType),
arrayTypeRemoveLastFunctionDocString,
Expand Down Expand Up @@ -5378,9 +5393,10 @@ func (t *DictionaryType) initializeMemberResolvers() {
Kind: common.DeclarationKindFunction,
Mutating: true,
Resolve: func(memoryGauge common.MemoryGauge, identifier string, _ ast.Range, _ func(error)) *Member {
return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
t,
insertableEntitledAccess,
identifier,
DictionaryInsertFunctionType(t),
dictionaryTypeInsertFunctionDocString,
Expand All @@ -5391,9 +5407,10 @@ func (t *DictionaryType) initializeMemberResolvers() {
Kind: common.DeclarationKindFunction,
Mutating: true,
Resolve: func(memoryGauge common.MemoryGauge, identifier string, _ ast.Range, _ func(error)) *Member {
return NewPublicFunctionMember(
return NewFunctionMember(
memoryGauge,
t,
removableEntitledAccess,
identifier,
DictionaryRemoveFunctionType(t),
dictionaryTypeRemoveFunctionDocString,
Expand Down
Loading

0 comments on commit 750be9f

Please sign in to comment.