﻿# Аннотирование C\# кода в формате JSON

Способы подключения файла c аннотациями

Подробнее о способе подключения файла аннотаций вы можете узнать в [этой](https://pvs-studio.ru/ru/docs/manual/6810/#how_to_enable) документации\.

## Структура файла с аннотациями

Содержимое файла — JSON\-объект, состоящий из трёх обязательных полей: `language`, `version` и `annotations`\. 

Поле `language` должно иметь значение `csharp`\. Поле `version` принимает значение целого типа и задаёт версию механизма\. В зависимости от значения файл с разметкой может обрабатываться по\-разному\. Актуальная на данный момент версия — 2\.

Поле _annotations_ — массив объектов "аннотация":

```cpp
{
  "language": "csharp",
  "version": 2,
  "annotations":
  [
    {
      ...
    },
    {
      ...
    }
  ]
}
```

Аннотации могут быть трёх типов: 

* аннотации методов;
* аннотации конструкторов;
* аннотации свойств\.

## Аннотации для taint\-анализа 

В анализаторе существует ряд аннотаций для [taint\-анализа](https://pvs-studio.ru/ru/blog/terms/6496/)\. С их помощью можно размечать источники и приёмники заражения\. Также существует возможность помечать методы/конструкторы, которые производят валидацию taint\-данных\. Таким образом, если taint\-данные прошли валидацию, то при их попадании в приёмник предупреждения анализатора не будет\.

За каждый из видов уязвимостей отвечает отдельное диагностическое правило\. На данный момент в анализаторе представлены следующие taint\-диагностики:

* [V5608](https://pvs-studio.ru/ru/docs/warnings/v5608/) — SQL injection;
* [V5609](https://pvs-studio.ru/ru/docs/warnings/v5609/) — Path traversal vulnerability;
* [V5610](https://pvs-studio.ru/ru/docs/warnings/v5610/) — XSS vulnerability;
* [V5611](https://pvs-studio.ru/ru/docs/warnings/v5611/) — Insecure deserialization vulnerability;
* [V5614](https://pvs-studio.ru/ru/docs/warnings/v5614/) — XXE vulnerability;
* [V5615](https://pvs-studio.ru/ru/docs/warnings/v5615/) — XEE vulnerability;
* [V5616](https://pvs-studio.ru/ru/docs/warnings/v5616/) — Command injection;
* [V5618](https://pvs-studio.ru/ru/docs/warnings/v5618/) — Server\-side request forgery;
* [V5619](https://pvs-studio.ru/ru/docs/warnings/v5619/) — Log injection;
* [V5620](https://pvs-studio.ru/ru/docs/warnings/v5620/) — LDAP injection;
* [V5622](https://pvs-studio.ru/ru/docs/warnings/v5622/) — XPath injection;
* [V5623](https://pvs-studio.ru/ru/docs/warnings/v5623/) — Open redirect vulnerability;
* [V5624](https://pvs-studio.ru/ru/docs/warnings/v5624/) — Configuration vulnerability;
* [V5626](https://pvs-studio.ru/ru/docs/warnings/v5626/) — ReDoS vulnerability;
* [V5627](https://pvs-studio.ru/ru/docs/warnings/v5627/) — NoSQL injection;
* [V5628](https://pvs-studio.ru/ru/docs/warnings/v5628/) — Zip Slip vulnerability\.

### Принцип работы taint\-аннотаций

Для каждого из диагностических правил существуют специальные аннотации, которые позволяют разметить приёмники и методы/конструкторы, производящие валидацию\.

Что касается источников taint\-данных, то они являются общими для всех диагностик\. Такие данные также можно разметить с помощью аннотаций\.

**Примечание\.** Атрибуты для разметки taint\-аннотаций описаны в следующих разделах\.  

Стоит отметить, что, помимо пользовательских аннотаций, в анализаторе уже имеется ряд taint\-аннотаций для различных библиотек\. Например, при передаче результата выполнения метода `System.Console.ReadLine` в конструктор `System.Data.SqlClient.SqlCommand` возможно возникновение SQL injection\. В анализаторе есть аннотации, которые говорят, что `System.Console.ReadLine` — источник taint\-данных, а `System.Data.SqlClient.SqlCommand` — приёмник, при попадании в который taint\-данных может возникнуть SQL injection\.

Таким образом, размечая источники taint\-данных, анализатор будет учитывать их для уже существующих приёмников и наоборот\. Если добавить аннотацию приёмника, то анализатор будет выдавать предупреждение при попадании в него уже размеченных источников taint\-данных \(например, `System.Console.ReadLine`\)\. 

## Аннотации методов

**Примечание\.** Объект аннотации метода должен содержать хотя бы одно опциональное поле\.

Объект аннотации метода состоит из следующих полей:

### Поле "type"

Обязательное поле\. Принимает строку со значением `method`\.

### Поле "namespace\_name"

Обязательное поле\. Принимает строку с именем пространства имён, которое содержит метод\.

### Поле "type\_name"

Обязательное поле\. Принимает строку с именем класса, в котором определён метод\. 

### Поле "method\_name"

Обязательное поле\. Принимает строку с именем метода\. 

### Поле "attributes"

Опциональное поле\. Массив строк, который задаёт свойства сущности\.

#### Возможные атрибуты метода 

|\\\#|Название атрибута|Описание атрибута|
|---|---|---|
|1|not\\\_apply\\\_to\\\_child\\\_class|Аннотация не будет применяться при вызове проаннотированного метода у объекта дочернего класса\\\.|
|2|caller\\\_is\\\_xml\\\_parser|Объект, вызывающий метод, является XML\\\-парсером, который может быть уязвим \\\(\[V5614\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5614/\), \[V5615\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5615/\)\\\)\\\.|
|3|use\\\_return|Необходимо использовать возвращаемое значение метода\\\.|
|4|dispose\\\_equivalent|Метод работает аналогично методу \`Dispose\`\\\.|
|5|returns\\\_new\\\_value|При каждом вызове метод возвращает новый объект\\\.|
|6|external\\\_modification|Метод изменяет что\\\-то внешнее \\\(печать в консоли, создание файлов и т\\\. п\\\.\\\)\\\.|
|7|empty\\\_collection\\\_exception|При вызове этого метода у пустой коллекции будет выброшено исключение\\\.|



### Поле "params"

Опциональное поле\. Данное поле описано в разделе "Аннотации параметров"\.

### Поле "returns"

**Примечание\.** Объект аннотации возвращаемого значения должен либо содержать поля `namespace_name` и `type_name`, либо оба поля должны отсутствовать \(или иметь значение `null`\)\. Если оба поля отсутствуют, то при выборе аннотации не будет учитываться тип возвращаемого значения\.

Опциональное поле\. Объект возвращаемого значения, состоит из следующих полей:

#### Поле "namespace\_name"

Опциональное поле\. Принимает строку с именем пространства имён, которое содержит тип возвращаемого значения метода\.

#### Поле "type\_name"

Опциональное поле\. Принимает строку с именем класса, в котором определён тип возвращаемого значения метода\. 

#### Поле "attributes"

Опциональное поле\. Массив строк, который задаёт свойства возвращаемого значения метода\.

**Возможные атрибуты возвращаемого значения**

|\\\#|Название атрибута|Описание атрибута|
|---|---|---|
|1|not\\\_apply\\\_to\\\_child\\\_class|Аннотация не будет применяться для методов, тип возвращаемого значения которых является дочерним для проаннотированного типа\\\.|
|2|always\\\_taint|Метод возвращает taint\\\-данные\\\.|
|3|transfer\\\_annotations\\\_from\\\_caller|Если вызывающий объект содержит аннотацию, она будет перенесена на возвращаемое значение метода\\\.|
|4|not\\\_null|Метод никогда не возвращает \`null\`\\\.|
|5|file\\\_path|Метод возвращает путь до файла\\\.|
|6|sensitive\\\_data|Метод возвращает sensitive\\\-данные\\\.|



### Особенности аннотирования методов расширения

При аннотировании методов расширения необходимо указывать тип, в котором определён метод расширения\. Например, есть метод расширения для класса `System.String` — `MyNamespace.StringExtensions.CustomizeString(this string str)`\. Нужно писать аннотацию для типа `MyNamespace.StringExtensions`, а **не** для `System.String`\. Стоит учесть, что все методы расширения будут иметь как минимум один аргумент\. 

Существует возможность аннотировать **не** тип, в котором определён метод расширения, а расширяемый тип\. Если обратиться к примеру, описанному выше, то это `System.String`\. Однако данный способ является нежелательным, так как накладывает ряд ограничений на обработку анализатором аннотации такого вида\. Например, нельзя сделать аннотацию для первого параметра \(с модификатором `this`\)\.

## Аннотации конструкторов

**Примечание\.** Объект аннотации конструктора должен содержать хотя бы одно опциональное поле\.

Объект аннотации конструктора состоит из следующих полей:

### Поле "type"

Обязательное поле\. Принимает строку со значением `ctor`\.

### Поле "namespace\_name"

Обязательное поле\. Принимает строку с именем пространства имён, которое содержит конструктор\.

### Поле "type\_name"

Обязательное поле\. Принимает строку с именем класса, в котором определён конструктор\. 

### Поле "attributes"

Опциональное поле\. Массив строк, который задаёт свойства сущности\.

#### Возможные атрибуты конструкторов 

|\\\#|Название атрибута|Описание атрибута|
|---|---|---|
|1|not\\\_apply\\\_to\\\_child\\\_class|Аннотация не будет применяться для дочерних реализаций проаннотированного конструктора\\\.|
|2|create\\\_taint\\\_object|Созданный конструктором объект — taint\\\.|



### Поле "params"

Опциональное поле\. Данное поле описано в разделе "Аннотации параметров"\.

## Аннотации свойств

Объект аннотации свойства состоит из следующих полей:

### Поле "type"

Обязательное поле\. Принимает строку со значением `property`\.

### Поле "namespace\_name"

Обязательное поле\. Принимает строку с именем пространства имён, которое содержит свойство\.

### Поле "type\_name"

Обязательное поле\. Принимает строку с именем класса, в котором определено свойство\. 

### Поле "attributes"

Опциональное поле\. Массив строк, который задаёт свойства сущности\.

#### Возможные атрибуты свойств

**Примечание\.** К каждому из атрибутов taint\-приёмников прикреплена ссылка на соответствующую диагностику\.

|\\\#|Название атрибута|Описание атрибута|
|---|---|---|
|1|not\\\_apply\\\_to\\\_child\\\_class|Аннотация не будет применяться при обращении к проаннотированному свойству у объекта дочернего класса\\\.|
|2|transfer\\\_annotation\\\_to\\\_return\\\_value|Если на вызывающем объекте есть аннотация, то она будет перенесена на возвращаемое значение\\\.|
|3|transfer\\\_annotation\\\_to\\\_caller|Если свойству присваивается значение, то аннотации этого значения будут перенесены на вызывающий объект свойства\\\.|
|4|return\\\_taint|Свойство возвращает taint\\\-данные\\\.|
|5|sql\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к SQL Injection \\\(\[V5608\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5608/\)\\\)\\\.|
|6|path\\\_traversal\\\_target|Запись в это свойство заражённых данных приводит к Path Traversal \\\(\[V5609\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5609/\)\\\)\\\.|
|7|xss\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к XSS Injection \\\(\[V5610\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5610/\)\\\)\\\.|
|8|insecure\\\_deserialization\\\_target|Запись в это свойство заражённых данных приводит к Insecure Deserialization \\\(\[V5611\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5611/\)\\\)\\\.|
|9|command\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к Command Injection \\\(\[V5616\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5616/\)\\\)\\\.|
|10|ssrf\\\_target|Запись в это свойство заражённых данных приводит к Server\\\-Side Request Forgery \\\(\[V5618\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5618/\)\\\)\\\.|
|11|log\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к Log Injection \\\(\[V5619\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5619/\)\\\)\\\.|
|12|ldapi\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к LDAP Injection \\\(\[V5620\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5620/\)\\\)\\\.|
|13|xpath\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к XPath Injection \\\(\[V5622\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5622/\)\\\)\\\.|
|14|open\\\_redirect\\\_target|Запись в это свойство заражённых данных приводит к Open Redirect \\\(\[V5623\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5623/\)\\\)\\\.|
|15|configuration\\\_attack\\\_target|Запись в это свойство заражённых данных приводит к Configuration Attack \\\(\[5624\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5624/\)\\\)\\\.|
|16|nosql\\\_injection\\\_target|Запись в это свойство заражённых данных приводит к NoSQL Injection \\\(\[V5627\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5627/\)\\\)\\\.|
|17|redos\\\_target|Запись в это свойство заражённых данных приводит к ReDoS \\\(\[V5626\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5626/\)\\\)\\\.|
|18|zipslip\\\_target|Запись в это свойство заражённых данных приводит к ZipSlip \\\(\[V5628\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5628/\)\\\)\\\.|
|19|modified\\\_in\\\_another\\\_thread|Свойство может измениться в другом потоке\\\.|
|20|sensitive\\\_data|Свойство содержит sensitive\\\-данные\\\.|
|21|file\\\_path|Свойство содержит путь до файла\\\.|



## Аннотации параметров

**Примечание 1\.** Объект аннотации параметра может находиться только внутри массива `params`, объекта аннотации метода или конструктора\.

**Примечание 2\.** Объект аннотации параметра должен либо содержать поля `namespace_name` и `type_name`, либо оба поля должны отсутствовать \(или иметь значение `null`\)\.

**Примечание 3\.** Если аннотация метода/конструктора должна применяться ко всем перегрузкам этого метода/конструктора, то поле `params` должно **отсутствовать** в аннотации\.

Объект аннотации параметра состоит из следующих полей:

### Поле "namespace\_name"

Обязательное поле\. Принимает строку с именем пространства имён, которое содержит тип параметра\.

### Поле "type\_name"

Обязательное поле\. Принимает строку с именем класса, в котором определён тип параметра\. 

### Поле "attributes"

Опциональное поле\. Массив строк, который задаёт свойства сущности\.

#### Возможные атрибуты параметров 

**Примечание\.** К каждому из атрибутов taint\-приёмников и taint\-валидации прикреплена ссылка на соответствующую диагностику\.

|\\\#|Название атрибута|Описание атрибута|
|---|---|---|
|1|ignore\\\_current\\\_and\\\_next|При подборе соответствующей аннотации не будут учитываться текущий и следующие параметры \\\(данная аннотация может быть только у последнего аргумента\\\)\\\.|
|2|transfer\\\_annotation\\\_to\\\_return\\\_value|Если параметр содержит аннотацию, она будет перенесена на возвращаемое значение метода\\\.|
|3|object\\\_creation\\\_infector|Заражение нового созданного объекта происходит через этот параметр \\\(актуально только для конструкторов\\\)\\\.|
|4|sql\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к SQL Injection \\\(\[V5608\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5608/\)\\\)\\\.|
|5|sql\\\_injection\\\_validation|Вызов метода сбрасывает SQL Injection taint\\\-статус для данного параметра \\\(\[V5608\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5608/\)\\\)\\\.|
|6|path\\\_traversal\\\_target|Передача в этот параметр заражённых данных приводит к Path Traversal \\\(\[V5609\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5609/\)\\\)\\\.|
|7|path\\\_traversal\\\_validation|Вызов метода сбрасывает Path Traversal taint\\\-статус для данного параметра \\\(\[V5609\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5609/\)\\\)\\\.|
|8|xss\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к XSS Injection \\\(\[V5610\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5610/\)\\\)\\\.|
|9|xss\\\_injection\\\_validation|Вызов метода сбрасывает XSS Injection taint\\\-статус для данного параметра \\\(\[V5610\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5610/\)\\\)\\\.|
|10|insecure\\\_deserialization\\\_target|Передача в этот параметр заражённых данных приводит к Insecure Deserialization \\\(\[V5611\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5611/\)\\\)\\\.|
|11|insecure\\\_deserialization\\\_validation|Вызов метода сбрасывает Insecure Deserialization taint\\\-статус для данного параметра \\\(\[V5611\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5611/\)\\\)\\\.|
|12|command\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к Command Injection \\\(\[V5616\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5616/\)\\\)\\\.|
|13|command\\\_injection\\\_validation|Вызов метода сбрасывает Command Injection taint\\\-статус для данного параметра \\\(\[V5616\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5616/\)\\\)\\\.|
|14|xml\\\_source\\\_to\\\_parse|Параметр \\\- источник XML, который будет парситься\\\. Это может быть сам XML\\\-файл, путь до него, поток с XML\\\-файлов, парсер, содержащий поток XML\\\-файла, и т\\\. п\\\. \\\(\[V5614\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5614/\), \[V5615\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5615/\)\\\)\\\.|
|15|transfer\\\_xml\\\_settings\\\_to\\\_return|Передаёт настройки XML\\\-парсера из этого аргумента в возвращаемое значение\\\. \\\(\[V5614\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5614/\), \[V5615\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5615/\)\\\)\\\.|
|16|ssrf\\\_target|Передача в этот параметр заражённых данных приводит к Server\\\-Side Request Forgery \\\(\[V5618\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5618/\)\\\)\\\.|
|17|ssrf\\\_validation|Вызов метода сбрасывает Server\\\-Side Request Forgery taint\\\-статус для данного параметра \\\(\[V5618\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5618/\)\\\)\\\.|
|18|log\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к Log Injection \\\(\[V5619\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5619/\)\\\)\\\.|
|19|log\\\_injection\\\_validation|Вызов метода сбрасывает Log Injection taint\\\-статус для данного параметра \\\(\[V5619\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5619/\)\\\)\\\.|
|20|ldapi\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к LDAP Injection \\\(\[V5620\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5620/\)\\\)\\\.|
|21|ldapi\\\_injection\\\_validation|Вызов метода сбрасывает LDAP Injection taint\\\-статус для данного параметра \\\(\[V5620\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5620/\)\\\)\\\.|
|22|xpath\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к XPath Injection \\\(\[V5622\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5622/\)\\\)\\\.|
|23|xpath\\\_injection\\\_validation|Вызов метода сбрасывает XPath Injection taint\\\-статус для данного параметра \\\(\[V5622\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5622/\)\\\)\\\.|
|24|open\\\_redirect\\\_target|Передача в этот параметр заражённых данных приводит к Open Redirect \\\(\[V5623\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5623/\)\\\)\\\.|
|25|open\\\_redirect\\\_validation|Вызов метода сбрасывает Open Redirect taint\\\-статус для данного параметра \\\(\[V5623\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5623/\)\\\)\\\.|
|26|configuration\\\_attack\\\_target|Передача в этот параметр заражённых данных приводит к Configuration Attack \\\(\[5624\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5624/\)\\\)\\\.|
|27|configuration\\\_attack\\\_validation|Вызов метода сбрасывает Configuration Attack taint\\\-статус для данного параметра \\\(\[5624\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5624/\)\\\)\\\.|
|28|nosql\\\_injection\\\_target|Передача в этот параметр заражённых данных приводит к NoSQL Injection \\\(\[V5627\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5627/\)\\\)\\\.|
|29|nosql\\\_injection\\\_validation|Вызов метода сбрасывает NoSQL Injection taint\\\-статус для данного параметра \\\(\[V5627\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5627/\)\\\)\\\.|
|30|redos\\\_target|Строка, которая разбирается с помощью регулярного выражения\\\. Передача в этот параметр заражённых данных приводит к ReDoS, если регулярное выражение небезопасно \\\(\[V5626\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5626/\)\\\)\\\.|
|31|redos\\\_validation|Вызов метода сбрасывает ReDoS taint\\\-статус для данного параметра \\\(\[V5626\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5626/\)\\\)\\\.|
|32|zipslip\\\_target|Строка, которая может быть использована как путь для извлечения файла из архива\\\. Передача в этот параметр заражённых данных приводит к ZipSlip \\\(\[V5628\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5628/\)\\\)\\\.|
|33|zipslip\\\_validation|Вызов метода сбрасывает ZipSlip taint\\\-статус для данного параметра \\\(\[V5628\]\(https://pvs\-studio\.ru/ru/docs/warnings/v5628/\)\\\)\\\.|
|34|regex|Параметр является регулярным выражением\\\.|
|35|format\\\_string|Параметр является строкой формата\\\.|
|36|params|Параметр имеет модификатор \`params\`\\\.|
|37|ref\\\_or\\\_out|Параметр имеет модификатор \`ref\` или \`out\`\\\.|
|38|file\\\_path|Параметр является путём до файла\\\.|
|39|greater\\\_than\\\_zero|Параметр должен быть строго больше нуля\\\.|
|40|greater\\\_than\\\_or\\\_equal\\\_to\\\_zero|Параметр должен быть больше или равен нулю\\\.|
|41|not\\\_null|Параметр не должен быть \`null\`\\\.|
|42|not\\\_null\\\_after\\\_method\\\_call|Значение, соответствующее параметру, точно \*\*не\*\* будет \`null\` после вызова метода\\\.|
|43|sensitive\\\_data|Данный параметр \*\*не\*\* должен содержать sensitive\\\-данные\\\.|

### Игнорирование типа параметра

Чтобы проигнорировать тип параметра, **не** нужно указывать поля `namespace_name` и `type_name` или нужно записать в **оба** поля `null`\.

## Схема JSON

JSON схемы поставляются в дистрибутиве, а также доступны по ссылкам ниже:

* [V1 \(поддерживается начиная с версии 7\.33\)](https://files.pvs-studio.com/media/custom_annotations/v1/csharp-annotations.schema.json);
* [V2 \(поддерживается начиная с версии 7\.38\)](https://files.pvs-studio.com/media/custom_annotations/v2/csharp-annotations.schema.json)\.

## Примеры

### Аннотация метода

Рассмотрим метод: 

```cpp
namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput()
    {
      ....
    }
  }
}
```

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint\-данные\. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом: 

```cpp
{
  "version": 2,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}
```

### Аннотация конструктора

Рассмотрим конструктор: 

```cpp
namespace MyNamespace
{
  public class MyClass
  {
    public MyClass()
    {
      ....
    }
  }
}
```

Допустим, данный конструктор создаёт объект, который может содержать taint\-данные\. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом: 

```cpp
{
  "version": 2,
  "language": "csharp",
  "annotations": [
    {
      "type": "ctor",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "attributes": [ "create_taint_object" ]
    }
  ]
}
```

### Аннотация свойства

Рассмотрим свойство: 

```cpp
namespace MyNamespace
{
  public class MyClass
  {
    public string UserInput 
    {
      get
      {
        ....
      }
    }
  }
}
```

Допустим, данное свойство возвращает пользовательский ввод, который может содержать taint\-данные\. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом: 

```cpp
{
  "version": 2,
  "language": "csharp",
  "annotations": [
    {
      "type": "property",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "property_name": "UserInput",
      "attributes": [ "return_taint" ]
    }
  ]
}
```

### Аннотация метода/конструктора, тип параметра которых неважен

**Примечание\.** В качестве примера используется аннотация метода\. Игнорирование типа параметров конструктора производится аналогичным образом \(не указывать `type_name` и `namespace_name` у аннотации параметра\)\.

Рассмотрим две перегрузки метода `GetUserInput`: 

```cpp
namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput(string str)
    {
      ....
    }

    public string GetUserInput(int index)
    {
      ....
    }
  }
}
```

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint\-данные, вне зависимости от типа параметра\. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом: 

```cpp
{
  "version": 2,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "params": [
        { }
      ],
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}
```

В данном случае для первого параметра нет аннотаций\. Также при подборе аннотации метода неважно, какой тип будет иметь первый параметр\. Поэтому аннотация параметра представлена пустым объектом\.

### Аннотация метода/конструктора c игнорированием некоторых параметров

**Примечание\.** В качестве примера используется аннотация метода\. Игнорирование параметров конструктора производится аналогичным образом \(с помощью аннотации `ignore_current_and_next`\)\. 

Рассмотрим две перегрузки метода `GetUserInput`: 

```cpp
namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput(string str)
    {
      ....
    }

    public string GetUserInput(string str, bool flag1, bool flag2)
    {
      ....
    }
  }
}
```

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint\-данные, если использована перегрузка с одним или более параметрами\. Также, если в первый параметр передать taint\-данные, возникнет SQL injection\. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом: 

```cpp
{
  "version": 2,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "params": [
        {
          "namespace_name": "System",
          "type_name": "String",
          "attributes": [ "sql_injection_target" ]
        },
        {
          "attributes": [ "ignore_current_and_next" ]
        }
      ],
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}
```

Для второго параметра есть аннотация `ignore_current_and_next`\. Она позволяет игнорировать количество параметров \(включая проаннотированный параметр\) при обработке аннотации\.

### Аннотация метода/конструктора с игнорированием всех параметров

**Примечание\.** В качестве примера используется аннотация метода\. Игнорирование всех параметров для конструктора производится аналогичным образом \(в аннотации не указывается поле `params`\)\. 

Рассмотрим три перегрузки метода `GetUserInput`: 

```cpp
namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput()
    {
      ....
    }

    public string GetUserInput(string str)
    {
      ....
    }

    public string GetUserInput(string str, bool flag)
    {
      ....
    }
  }
}
```

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint\-данные, вне зависимости от перегрузки\. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом: 

```cpp
{
  "version": 2,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}
```

Данная аннотация будет применена ко всем перегрузкам метода `MyNamespace.MyClass.GetUserInput`, так как в ней нет поля `params`\.