Skip to content

Commit

Permalink
NET-682 Modify S7133: Add vbnet rspec (#4514)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel-mikula-sonarsource authored Nov 18, 2024
1 parent 40e3960 commit 99589d0
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 54 deletions.
21 changes: 0 additions & 21 deletions rules/S7133/csharp/metadata.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,2 @@
{
"title": "Locks should be released within the same method",
"type": "BUG",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7133",
"sqKey": "S7133",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "targeted",
"code": {
"impacts": {
"RELIABILITY": "HIGH"
},
"attribute": "CONVENTIONAL"
}
}
39 changes: 6 additions & 33 deletions rules/S7133/csharp/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,24 +1,4 @@
This rule raises if you acquire a lock with one of the following methods, and do not release it within the same method.

* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterreadlock[ReaderWriterLockSlim.EnterReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.enter[SpinLock.Enter]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.tryenter[SpinLock.TryEnter]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.Enter]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.tryenter[Monitor.TryEnter]
== Why is this an issue?

Not releasing a lock in the same method where you acquire it, and releasing in another one, makes the code less clear and harder to maintain. You are also introducing the risk of not releasing a lock at all which can lead to deadlocks or exceptions.

include::../description-dotnet.adoc[]

=== Code examples

Expand All @@ -31,14 +11,14 @@ public class Example
private static ReaderWriterLock rwLock = new();
public void AcquireWriterLock() =>
rwLock.AcquireWriterLock(2000); // Noncompliant, as the lock release is on the callers responsibilty
rwLock.AcquireWriterLock(2000); // Noncompliant, as the lock release is on the callers responsibility
public void DoSomething()
public void DoSomething()
{
// ...
}
public void ReleaseWriterLock() =>
public void ReleaseWriterLock() =>
rwLock.ReleaseWriterLock();
}
----
Expand All @@ -58,21 +38,14 @@ public class Example
{
// ...
}
finally
finally
{
rwLock.ReleaseWriterLock();
}
}
}
----

== Resources

=== Documentation

* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock[ReaderWriterLock Class]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim Classs]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock[SpinLock Struct]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor[Monitor Classs]
include::../resources-dotnet.adoc[]

include::../rspecator.adoc[]
20 changes: 20 additions & 0 deletions rules/S7133/description-dotnet.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
This rule raises if you acquire a lock with one of the following methods, and do not release it within the same method.

* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterreadlock[ReaderWriterLockSlim.EnterReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.enter[SpinLock.Enter]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.tryenter[SpinLock.TryEnter]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.Enter]
* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.tryenter[Monitor.TryEnter]
== Why is this an issue?

Not releasing a lock in the same method where you acquire it, and releasing in another one, makes the code less clear and harder to maintain. You are also introducing the risk of not releasing a lock at all which can lead to deadlocks or exceptions.
21 changes: 21 additions & 0 deletions rules/S7133/metadata.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
{
"title": "Locks should be released within the same method",
"type": "BUG",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7133",
"sqKey": "S7133",
"scope": "All",
"defaultQualityProfiles": [ "Sonar way" ],
"quickfix": "targeted",
"code": {
"impacts": {
"RELIABILITY": "HIGH"
},
"attribute": "CONVENTIONAL"
}
}
8 changes: 8 additions & 0 deletions rules/S7133/resources-dotnet.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
== Resources

=== Documentation

* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock[ReaderWriterLock Class]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim Classs]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock[SpinLock Struct]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor[Monitor Classs]
2 changes: 2 additions & 0 deletions rules/S7133/vbnet/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
50 changes: 50 additions & 0 deletions rules/S7133/vbnet/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
include::../description-dotnet.adoc[]

=== Code examples

==== Noncompliant code example

[source,vbnet,diff-id=1,diff-type=noncompliant]
----
Public Class Example
Private Shared rwLock As New ReaderWriterLock
Public Sub AcquireWriterLock()
rwLock.AcquireWriterLock(2000) ' Noncompliant, as the lock release is on the callers responsibility
End Sub
Public Sub DoSomething()
' ...
End Sub
Public Sub ReleaseWriterLock()
rwLock.ReleaseWriterLock()
End Sub
End Class
----

==== Compliant solution

[source,vbnet,diff-id=1,diff-type=compliant]
----
Public Class Example
Private Shared rwLock As New ReaderWriterLock
Public Sub DoSomething()
rwLock.AcquireWriterLock(2000) ' Compliant, locks are released in the same method
Try
' ...
Finally
rwLock.ReleaseWriterLock()
End Try
End Sub
End Class
----

include::../resources-dotnet.adoc[]

include::../rspecator.adoc[]

0 comments on commit 99589d0

Please sign in to comment.