CA2102: перехватывайте исключения, не являющиеся CLSCompliant, с помощью общих обработчиков

Товар Значение
Идентификатор правила CA2102
Категория Microsoft.Security
Критическое изменение Не критическое

Причина

Элемент в сборке, которая не помечена или помеченаRuntimeCompatibility(WrapNonExceptionThrows = false), RuntimeCompatibilityAttribute содержит блок catch, который обрабатывает System.Exception и не содержит сразу после общего блока перехвата. Это правило игнорирует сборки Visual Basic.

Примечание.

Это правило устарело. Дополнительные сведения см. в разделе "Устаревшие правила".

Описание правила

Блок catch, который обрабатывает Exception все исключения, соответствующие спецификации CLS. Однако он не перехватывает исключения, не совместимые с CLS. Исключения, не совместимые с CLS, могут создаваться из машинного кода или управляемого кода, созданного сборщиком промежуточного языка Майкрософт (MSIL). Обратите внимание, что компиляторы C# и Visual Basic не позволяют создавать исключения, не соответствующие CLS, и Visual Basic не перехватывает исключения, не соответствующие CLS. Если цель блока catch заключается в обработке всех исключений, используйте следующий общий синтаксис блока catch.

  • В C#: catch {}

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

Необработанное исключение, не соответствующее CLS, становится проблемой безопасности, когда ранее разрешенные разрешения удаляются в блоке catch. Так как исключения, не совместимые с CLS, не перехватываются, вредоносный метод, который создает исключение, не соответствующее CLS, может выполняться с повышенными разрешениями.

Устранение нарушений

Чтобы устранить нарушение этого правила, если намерение заключается в перехвате всех исключений, замене или добавлении общего блока перехвата или пометки сборки RuntimeCompatibility(WrapNonExceptionThrows = true). Если разрешения удаляются в блоке catch, дублируют функциональные возможности в общем блоке catch. Если это не намерение обрабатывать все исключения, замените блок catch, который обрабатывает Exception блоки catch, обрабатывающие определенные типы исключений.

Когда лучше отключить предупреждения

Это безопасно для подавления предупреждения из этого правила, если блок try не содержит никаких инструкций, которые могут создать исключение, не соответствующее CLS. Так как любой собственный или управляемый код может вызвать исключение, отличное от CLS, это требует знания обо всем коде, который можно выполнить во всех путях кода внутри блока try. Обратите внимание, что исключения, не совместимые с CLS, не создаются средой CLS.

Пример 1

В следующем примере показан класс MSIL, который создает исключение, отличное от CLS.

.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
   }
}

Пример 2

В следующем примере показан метод, содержащий общий блок перехвата, удовлетворяющий правилу.

// 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: не перехватывайте типы общих исключений

См. также