CA2102:在常规处理程序中捕捉非 CLSCompliant 异常

类型名

CatchNonClsCompliantExceptionsInGeneralHandlers

CheckId

CA2102

类别

Microsoft.Security

是否重大更改

非重大更改

原因

程序集中未标记为 RuntimeCompatibilityAttribute 或标记为 RuntimeCompatibility(WrapNonExceptionThrows = false) 的某个成员包含一个处理 System.Exception 的 catch 块,并且不包含紧跟其后的一般 catch 块。 此规则忽略 Visual Basic 程序集。

规则说明

处理 Exception 的 catch 块会捕获所有符合公共语言规范 (CLS) 的异常。 但是,它不捕获不符合 CLS 的异常。 不符合 CLS 的异常可以从本机代码中引发,或者从 Microsoft 中间语言 (MSIL) 汇编程序生成的托管代码中引发。 请注意,C# 和 Visual Basic 编译器不允许引发不符合 CLS 的异常,并且 Visual Basic 不捕获不符合 CLS 的异常。 如果 catch 块的目的是处理所有异常,请使用下面的一般 catch 块语法。

  • C#:catch {}

  • C++:catch(...) {} 或 catch(Object^) {}

当从 catch 块中移除以前允许的权限时,未处理的、不符合 CLS 的异常将变成安全隐患。 因为不符合 CLS 的异常不被捕获,所以引发不符合 CLS 异常的恶意方法将可以用提升的权限运行。

如何解决冲突

若要在目标是捕获所有异常的情况下修复此与规则的冲突,请替代或添加一般 catch 块或者将程序集标记为 RuntimeCompatibility(WrapNonExceptionThrows = true)。 如果移除了 catch 块中的权限,请复制一般 catch 块中的功能。 如果目标不是处理所有异常,请将处理 Exception 的 catch 块替换为处理具体异常类型的 catch 块。

何时禁止显示警告

如果 try 块不包含任何可能生成不符合 CLS 的异常的语句,可以安全地禁止显示此规则发出的警告。 因为任何本机代码或托管代码都可能引发不符合 CLS 的异常,所以这要求了解可以在 try 块的所有代码路径中执行的所有代码。 请注意,不符合 CLS 的异常不是由公共语言运行时引发的。

示例

下面的示例演示引发不符合 CLS 的异常的 MSIL 类。

.assembly ThrowNonClsCompliantException {}
.class public auto ansi beforefieldinit ThrowsExceptions
{
   .method public hidebysig static void
         ThrowNonClsException() cil managed
   {
      .maxstack  1
      IL_0000:  newobj     instance void [mscorlib]System.Object::.ctor()
      IL_0005:  throw
   }
}

下面的示例演示一个包含满足此规则的一般 catch 块的方法。

// CatchNonClsCompliantException.cs
using System;

namespace SecurityLibrary
{
   class HandlesExceptions
   {
      void CatchAllExceptions()
      {
         try
         {
            ThrowsExceptions.ThrowNonClsException();
         }
         catch(Exception e)
         {
            // Remove some permission.
            Console.WriteLine("CLS compliant exception caught");
         }
         catch
         {
            // Remove the same permission as above.
            Console.WriteLine("Non-CLS compliant exception caught.");
         }
      }

      static void Main()
      {
         HandlesExceptions handleExceptions = new HandlesExceptions();
         handleExceptions.CatchAllExceptions();
      }
   }
}

按以下方式编译前面的示例。

ilasm /dll ThrowNonClsCompliantException.il
csc /r:ThrowNonClsCompliantException.dll CatchNonClsCompliantException.cs

相关规则

CA1031:不要捕捉一般异常类型

请参见

参考

异常和异常处理(C# 编程指南)

Ilasm.exe(MSIL 汇编程序)

概念

重写安全检查

公共语言规范