92 lines
3.6 KiB
Plaintext
92 lines
3.6 KiB
Plaintext
== Why is this an issue?
|
|
|
|
A cast is an https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/implicit-and-explicit-conversions[explicit conversion], which is a way to tell the compiler the intent to convert from one type to another.
|
|
|
|
In Visual Basic, there are two explicit conversion operators:
|
|
|
|
[source,vbnet]
|
|
----
|
|
Public Sub Method(Value As Object)
|
|
Dim i As Integer
|
|
i = DirectCast(Value, Integer) ' Direct casting from object holding an integer type to Integer
|
|
i = CType(Value, Integer) ' Conversion from the underlying type to Integer
|
|
End Sub
|
|
----
|
|
|
|
In most cases, the compiler will be able to catch invalid casts between incompatible value types or reference types.
|
|
|
|
However, the compiler will not be able to detect invalid casts to https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/interfaces/[interfaces].
|
|
|
|
=== What is the potential impact?
|
|
|
|
Invalid casts will lead to unexpected behaviors or runtime errors such as https://learn.microsoft.com/en-us/dotnet/api/system.invalidcastexception[InvalidCastException].
|
|
|
|
=== Exceptions
|
|
|
|
No issue is reported if the interface has no implementing class in the assembly.
|
|
|
|
== How to fix it
|
|
|
|
To prevent an `InvalidCastException` from raising during an explicit conversion, it is recommended to use the https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/trycast-operator[`TryCast` operator].
|
|
When the conversion is not possible, the `TryCast` operator returns `Nothing` and will never raise an exception.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,vbnet,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
Public Interface IMyInterface
|
|
End Interface
|
|
|
|
Public Class Implementer
|
|
Implements IMyInterface
|
|
End Class
|
|
|
|
Public Class AnotherClass
|
|
End Class
|
|
|
|
Module Program
|
|
Sub Main()
|
|
Dim Another As New AnotherClass
|
|
Dim x As IMyInterface = DirectCast(Another, IMyInterface) ' Noncompliant: InvalidCastException is being thrown
|
|
End Sub
|
|
End Module
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,vbnet,diff-id=1,diff-type=compliant]
|
|
----
|
|
Public Interface IMyInterface
|
|
End Interface
|
|
|
|
Public Class Implementer
|
|
Implements IMyInterface
|
|
End Class
|
|
|
|
Public Class AnotherClass
|
|
End Class
|
|
|
|
Module Program
|
|
Sub Main()
|
|
Dim Another As New AnotherClass
|
|
Dim x = TryCast(Another, IMyInterface) ' Compliant: but will always be Nothing
|
|
End Sub
|
|
End Module
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
* https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/type-conversions[Type Conversions in Visual Basic]
|
|
** https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/implicit-and-explicit-conversions[Implicit and Explicit Conversions in Visual Basic]
|
|
** https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/how-to-convert-an-object-to-another-type[How to: Convert an Object to Another Type in Visual Basic]
|
|
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/directcast-operator[`DirectCast` operator]
|
|
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/functions/ctype-function[`CType` function]
|
|
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/trycast-operator[`TryCast` operator]
|
|
* CWE - https://cwe.mitre.org/data/definitions/588[CWE-588 - Attempt to Access Child of a Non-structure Pointer]
|
|
* CWE - https://cwe.mitre.org/data/definitions/704[CWE-704 - Incorrect Type Conversion or Cast]
|
|
|
|
include::../rspecator-dotnet.adoc[]
|