From 0d7489692b9859862ce53e4e298b66b91152060f Mon Sep 17 00:00:00 2001 From: Nozim Mehrubonov Date: Thu, 6 Jul 2023 14:31:01 +0100 Subject: [PATCH 1/5] Add warning for implicit Capability exposition via arrays --- lint/warn_implicit_capability_exposition.go | 88 ++++++++++++++++++ ...arn_implicit_capability_exposition_test.go | 91 +++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 lint/warn_implicit_capability_exposition.go create mode 100644 lint/warn_implicit_capability_exposition_test.go diff --git a/lint/warn_implicit_capability_exposition.go b/lint/warn_implicit_capability_exposition.go new file mode 100644 index 00000000..4e4127a6 --- /dev/null +++ b/lint/warn_implicit_capability_exposition.go @@ -0,0 +1,88 @@ +package lint + +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/tools/analysis" +) + +/* + * Cadence-lint - The Cadence linter + * + * Copyright 2019-2022 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var ImplicitCapabilityLeak = (func() *analysis.Analyzer { + + elementFilter := []ast.Element{ + (*ast.FieldDeclaration)(nil), + } + + return &analysis.Analyzer{ + Description: "Detects potential capability leak via public fields", + Requires: []*analysis.Analyzer{ + analysis.InspectorAnalyzer, + }, + Run: func(pass *analysis.Pass) interface{} { + inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) + + location := pass.Program.Location + //elaboration := pass.Program.Elaboration + report := pass.Report + + inspector.Preorder( + elementFilter, + func(element ast.Element) { + fieldDeclaration, ok := element.(*ast.FieldDeclaration) + if !ok { + return + } + if fieldDeclaration.DeclarationAccess() != ast.AccessPublic { + return + } + + arr, ok := fieldDeclaration.TypeAnnotation.Type.(*ast.VariableSizedType) + if !ok { + return + } + nominalType, ok := arr.Type.(*ast.NominalType) + if !ok { + return + } + if nominalType.Identifier.Identifier != "Capability" { + return + } + + report( + analysis.Diagnostic{ + Location: location, + Range: ast.NewRangeFromPositioned(nil, element), + Category: ReplacementCategory, + Message: "capability might be leaking", + }, + ) + }, + ) + + return nil + }, + } +})() + +func init() { + RegisterAnalyzer( + "implicit-capability-leak", + ImplicitCapabilityLeak, + ) +} diff --git a/lint/warn_implicit_capability_exposition_test.go b/lint/warn_implicit_capability_exposition_test.go new file mode 100644 index 00000000..509e99c4 --- /dev/null +++ b/lint/warn_implicit_capability_exposition_test.go @@ -0,0 +1,91 @@ +/* + * Cadence-lint - The Cadence linter + * + * Copyright 2019-2022 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lint_test + +import ( + "testing" + + "github.com/onflow/cadence-tools/lint" + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/tools/analysis" + "github.com/stretchr/testify/require" +) + +func TestImplicitCapabilityLeak(t *testing.T) { + + t.Parallel() + + t.Run("invalid", func(t *testing.T) { + + t.Parallel() + + diagnostics := testAnalyzers(t, + ` + pub contract MyContract { + pub let myCapArray: [Capability] + + init() { + self.myCapArray = [] + } + } + `, + lint.ImplicitCapabilityLeak, + ) + + require.Equal( + t, + []analysis.Diagnostic{ + { + Range: ast.Range{ + StartPos: ast.Position{Offset: 37, Line: 3, Column: 7}, + EndPos: ast.Position{Offset: 68, Line: 3, Column: 38}, + }, + Location: testLocation, + Category: lint.ReplacementCategory, + Message: "capability might be leaking", + }, + }, + diagnostics, + ) + }) + + //t.Run("valid", func(t *testing.T) { + // + // t.Parallel() + // + // diagnostics := testAnalyzers(t, + // ` + // pub contract MyContract { + // pub let myCapArray: [Capability] + // + // init() { + // self.myCapArray = [] + // } + // } + // `, + // lint.UnnecessaryForceAnalyzer, + // ) + // + // require.Equal( + // t, + // []analysis.Diagnostic(nil), + // diagnostics, + // ) + //}) +} From 7c1f391250415b65876dc69c513b141e7c3969ff Mon Sep 17 00:00:00 2001 From: Nozim Mehrubonov Date: Thu, 6 Jul 2023 14:35:26 +0100 Subject: [PATCH 2/5] Add valid test case example --- ...arn_implicit_capability_exposition_test.go | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/lint/warn_implicit_capability_exposition_test.go b/lint/warn_implicit_capability_exposition_test.go index 509e99c4..608b0fdd 100644 --- a/lint/warn_implicit_capability_exposition_test.go +++ b/lint/warn_implicit_capability_exposition_test.go @@ -65,27 +65,27 @@ func TestImplicitCapabilityLeak(t *testing.T) { ) }) - //t.Run("valid", func(t *testing.T) { - // - // t.Parallel() - // - // diagnostics := testAnalyzers(t, - // ` - // pub contract MyContract { - // pub let myCapArray: [Capability] - // - // init() { - // self.myCapArray = [] - // } - // } - // `, - // lint.UnnecessaryForceAnalyzer, - // ) - // - // require.Equal( - // t, - // []analysis.Diagnostic(nil), - // diagnostics, - // ) - //}) + t.Run("valid", func(t *testing.T) { + + t.Parallel() + + diagnostics := testAnalyzers(t, + ` + pub contract MyContract { + priv let myCapArray: [Capability] + + init() { + self.myCapArray = [] + } + } + `, + lint.ImplicitCapabilityLeak, + ) + + require.Equal( + t, + []analysis.Diagnostic(nil), + diagnostics, + ) + }) } From f5d7802a0575e7db53a1b7ca284a76b6853f0eb9 Mon Sep 17 00:00:00 2001 From: Nozim Mehrubonov Date: Fri, 7 Jul 2023 16:15:42 +0100 Subject: [PATCH 3/5] Rename files --- ...apability_exposition.go => warn_implicit_capability_leak.go} | 0 ...exposition_test.go => warn_implicit_capability_leak_test.go} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lint/{warn_implicit_capability_exposition.go => warn_implicit_capability_leak.go} (100%) rename lint/{warn_implicit_capability_exposition_test.go => warn_implicit_capability_leak_test.go} (97%) diff --git a/lint/warn_implicit_capability_exposition.go b/lint/warn_implicit_capability_leak.go similarity index 100% rename from lint/warn_implicit_capability_exposition.go rename to lint/warn_implicit_capability_leak.go diff --git a/lint/warn_implicit_capability_exposition_test.go b/lint/warn_implicit_capability_leak_test.go similarity index 97% rename from lint/warn_implicit_capability_exposition_test.go rename to lint/warn_implicit_capability_leak_test.go index 608b0fdd..0e9168e4 100644 --- a/lint/warn_implicit_capability_exposition_test.go +++ b/lint/warn_implicit_capability_leak_test.go @@ -27,7 +27,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestImplicitCapabilityLeak(t *testing.T) { +func TestImplicitCapabilityLeakViaArray(t *testing.T) { t.Parallel() From 8a4aa5a5a14164f5ad2c0d36aebe5a8c2ada4cdb Mon Sep 17 00:00:00 2001 From: Nozim Mehrubonov Date: Fri, 7 Jul 2023 16:17:45 +0100 Subject: [PATCH 4/5] Move the header annotation to the top --- lint/warn_implicit_capability_leak.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lint/warn_implicit_capability_leak.go b/lint/warn_implicit_capability_leak.go index 4e4127a6..c701cedc 100644 --- a/lint/warn_implicit_capability_leak.go +++ b/lint/warn_implicit_capability_leak.go @@ -1,10 +1,3 @@ -package lint - -import ( - "github.com/onflow/cadence/runtime/ast" - "github.com/onflow/cadence/tools/analysis" -) - /* * Cadence-lint - The Cadence linter * @@ -23,6 +16,13 @@ import ( * limitations under the License. */ +package lint + +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/tools/analysis" +) + var ImplicitCapabilityLeak = (func() *analysis.Analyzer { elementFilter := []ast.Element{ From 1cc4b49ba41b88ff09fec8bd56b9be16791a35ab Mon Sep 17 00:00:00 2001 From: Nozim Mehrubonov Date: Sun, 16 Jul 2023 19:15:49 +0100 Subject: [PATCH 5/5] Remove commented code --- lint/warn_implicit_capability_leak.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lint/warn_implicit_capability_leak.go b/lint/warn_implicit_capability_leak.go index c701cedc..e5b9f2e8 100644 --- a/lint/warn_implicit_capability_leak.go +++ b/lint/warn_implicit_capability_leak.go @@ -38,7 +38,6 @@ var ImplicitCapabilityLeak = (func() *analysis.Analyzer { inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) location := pass.Program.Location - //elaboration := pass.Program.Elaboration report := pass.Report inspector.Preorder(