diff --git a/rules/S7131/csharp/metadata.json b/rules/S7131/csharp/metadata.json index 6746948bd61..2c63c085104 100644 --- a/rules/S7131/csharp/metadata.json +++ b/rules/S7131/csharp/metadata.json @@ -1,23 +1,2 @@ { - "title": "A write lock should not be released when a read lock has been acquired and vice versa", - "type": "BUG", - "status": "ready", - "remediation": { - "func": "Constant\/Issue", - "constantCost": "30min" - }, - "tags": [ - ], - "defaultSeverity": "Major", - "ruleSpecification": "RSPEC-7131", - "sqKey": "S7131", - "scope": "All", - "defaultQualityProfiles": ["Sonar way"], - "quickfix": "infeasible", - "code": { - "impacts": { - "RELIABILITY": "HIGH" - }, - "attribute": "LOGICAL" - } } diff --git a/rules/S7131/csharp/rule.adoc b/rules/S7131/csharp/rule.adoc index 535d058c374..ca89ed5537e 100644 --- a/rules/S7131/csharp/rule.adoc +++ b/rules/S7131/csharp/rule.adoc @@ -1,20 +1,5 @@ -When using https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock[ReaderWriterLock] and https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim] for managing read and write locks, you should not release a read lock while holding a write lock and vice versa, otherwise you might have runtime exceptions. -The locks should be always correctly paired so that the shared resource is accessed safely. - -This rule raises if: - -* you call https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.upgradetowriterlock[ReaderWriterLock.UpgradeToWriterLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.releasereaderlock[ReaderWriterLock.ReleaseReaderLock] -* you call https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.exitreadlock[ReaderWriterLockSlim.ExitReadLock] -* you call https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.downgradefromwriterlock[ReaderWriterLock.DowngradeFromWriterLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.releasewriterlock[ReaderWriterLock.ReleaseWriterLock] -* or you call 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.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock], https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.exitwritelock[ReaderWriterLockSlim.ExitWriteLock] - - -== Why is this an issue? - -If you use the `ReaderWriterLockSlim` class, you will get a https://learn.microsoft.com/en-us/dotnet/api/system.threading.lockrecursionexception[LockRecursionException]. -In the case of `ReaderWriterLock`, you'll get a runtime exception for trying to release a lock that is not owned by the calling thread. - +include::../description-dotnet.adoc[] === Code examples @@ -90,11 +75,6 @@ public class Example } ---- -== 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] +include::../resources-dotnet.adoc[] include::../rspecator.adoc[] \ No newline at end of file diff --git a/rules/S7131/description-dotnet.adoc b/rules/S7131/description-dotnet.adoc new file mode 100644 index 00000000000..f63e0a3c890 --- /dev/null +++ b/rules/S7131/description-dotnet.adoc @@ -0,0 +1,15 @@ +When using https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock[ReaderWriterLock] and https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim] for managing read and write locks, you should not release a read lock while holding a write lock and vice versa, otherwise you might have runtime exceptions. +The locks should be always correctly paired so that the shared resource is accessed safely. + +This rule raises if: + +* you call https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.upgradetowriterlock[ReaderWriterLock.UpgradeToWriterLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.releasereaderlock[ReaderWriterLock.ReleaseReaderLock] +* you call https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.exitreadlock[ReaderWriterLockSlim.ExitReadLock] +* you call https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.downgradefromwriterlock[ReaderWriterLock.DowngradeFromWriterLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.releasewriterlock[ReaderWriterLock.ReleaseWriterLock] +* or you call 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.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock], https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] or https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock] and then use https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.exitwritelock[ReaderWriterLockSlim.ExitWriteLock] + + +== Why is this an issue? + +If you use the `ReaderWriterLockSlim` class, you will get a https://learn.microsoft.com/en-us/dotnet/api/system.threading.lockrecursionexception[LockRecursionException]. +In the case of `ReaderWriterLock`, you'll get a runtime exception for trying to release a lock that is not owned by the calling thread. diff --git a/rules/S7131/metadata.json b/rules/S7131/metadata.json index 2c63c085104..6746948bd61 100644 --- a/rules/S7131/metadata.json +++ b/rules/S7131/metadata.json @@ -1,2 +1,23 @@ { + "title": "A write lock should not be released when a read lock has been acquired and vice versa", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "30min" + }, + "tags": [ + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-7131", + "sqKey": "S7131", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "infeasible", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } } diff --git a/rules/S7131/resources-dotnet.adoc b/rules/S7131/resources-dotnet.adoc new file mode 100644 index 00000000000..c12a3ab7ff7 --- /dev/null +++ b/rules/S7131/resources-dotnet.adoc @@ -0,0 +1,6 @@ +== 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] \ No newline at end of file diff --git a/rules/S7131/vbnet/metadata.json b/rules/S7131/vbnet/metadata.json new file mode 100644 index 00000000000..7a73a41bfdf --- /dev/null +++ b/rules/S7131/vbnet/metadata.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/rules/S7131/vbnet/rule.adoc b/rules/S7131/vbnet/rule.adoc new file mode 100644 index 00000000000..a69d9592acb --- /dev/null +++ b/rules/S7131/vbnet/rule.adoc @@ -0,0 +1,65 @@ +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 Writer() + rwLock.AcquireWriterLock(2000) + Try + ' ... + Finally + rwLock.ReleaseReaderLock() ' Noncompliant, will throw runtime exception + End Try + End Sub + + Public Sub Reader() + rwLock.AcquireReaderLock(2000) + Try + ' ... + Finally + rwLock.ReleaseWriterLock() ' Noncompliant, will throw runtime exception + End Try + End Sub + +End Class +---- + +==== Compliant solution + +[source,vbnet,diff-id=1,diff-type=compliant] +---- +Public Class Example + + Private Shared rwLock As New ReaderWriterLock() + + Public Shared Sub Writer() + rwLock.AcquireWriterLock(2000) + Try + ' ... + Finally + rwLock.ReleaseWriterLock() + End Try + End Sub + + Public Shared Sub Reader() + rwLock.AcquireReaderLock(2000) + Try + ' ... + Finally + rwLock.ReleaseReaderLock() + End Try + End Sub + +End Class +---- + +include::../resources-dotnet.adoc[] + +include::../rspecator.adoc[] \ No newline at end of file