Hiral Desai
Hiral Desai

Reputation: 1122

CA2000: Object is not disposed along all exception paths

I am having trouble trying to figure out why I'm getting this warning in following code.

CA2000 : Microsoft.Reliability : In method 'Encryption64.Decrypt(String, String)', object 'des' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'des' before all references to it are out of scope.

CA2000 : Microsoft.Reliability : In method 'Encryption64.Encrypt(String, String)', object 'des' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'des' before all references to it are out of scope.

Public Class Encryption64

    Private key() As Byte = {}
    Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}

    Public Function Decrypt(ByVal stringToDecrypt As String, ByVal sEncryptionKey As String) As String

        Dim des As New DESCryptoServiceProvider()
        Dim ms As New MemoryStream()
        Dim ReturnValue As String = String.Empty

        Try

            Dim inputByteArray(stringToDecrypt.Length) As Byte
            key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
            inputByteArray = Convert.FromBase64String(stringToDecrypt)

            Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV),CryptoStreamMode.Write)
            cs.Write(inputByteArray, 0, inputByteArray.Length)
            cs.FlushFinalBlock()

            Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
            ReturnValue = encoding.GetString(ms.ToArray())

        Catch e As Exception

            ReturnValue = e.Message

        Finally

            If des IsNot Nothing Then
                des.Dispose()
            End If

            If ms IsNot Nothing Then
                ms.Dispose()
            End If

        End Try

        Return ReturnValue

    End Function

    Public Function Encrypt(ByVal stringToEncrypt As String, ByVal SEncryptionKey As String) As String

        Dim des As New DESCryptoServiceProvider()
        Dim ms As New MemoryStream()
        Dim ReturnValue As String = String.Empty

        Try

            key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))

            Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes(stringToEncrypt)
            Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), CryptoStreamMode.Write)

            cs.Write(inputByteArray, 0, inputByteArray.Length)
            cs.FlushFinalBlock()

            ReturnValue = Convert.ToBase64String(ms.ToArray())

        Catch e As Exception

            ReturnValue = e.Message

        Finally

            If des IsNot Nothing Then
                des.Dispose()
            End If

            If ms IsNot Nothing Then
                ms.Dispose()
            End If

        End Try

        Return ReturnValue

    End Function

End Class

Upvotes: 0

Views: 1558

Answers (2)

Jim Wooley
Jim Wooley

Reputation: 10398

Since you are declaring (and instantiating) your des objects outside of the Try ... Finally blocks, it is possible for your code to raise an exception in the line Dim ms As New MemoryStream() and your .Dispose() will not be called.

When you are working with objects that implement IDisposable, it is much preferable where possible to wrap them in a Using block instead of a Try...Finally block. For example:

Public Function Decrypt(ByVal stringToDecrypt As String, ByVal sEncryptionKey As String) As String

    Dim ms As New MemoryStream() 
    Dim ReturnValue As String = String.Empty 

        Dim inputByteArray(stringToDecrypt.Length) As Byte 
        key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8)) 
        inputByteArray = Convert.FromBase64String(stringToDecrypt) 

        Using ms as New MemoryStream
           Using des As New DESCryptoServiceProvider
              Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV),CryptoStreamMode.Write) 
              cs.Write(inputByteArray, 0, inputByteArray.Length) 
              cs.FlushFinalBlock() 
           End Using ' des
           Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8 
           ReturnValue = encoding.GetString(ms.ToArray()) 
        End Using ' ms 
    Catch e As Exception 

        ReturnValue = e.Message 

    End Try 

    Return ReturnValue 

End Function 

Upvotes: 1

JohnD
JohnD

Reputation: 14757

Just a guess, but maybe it's not smart enough to realize that this code line will always be true:

If des IsNot Nothing Then

In other words, it might assume that because there is a conditional statement, the Dispose() call might not be executed.

To check, you can try commenting out the "if" and see if the warning goes away.

Upvotes: 0

Related Questions