Skip to content

Commit ff1ac97

Browse files
authored
Merge pull request #1725 from EvilBeaver/feature/cfg
ControlFlowGraph и диагностика с примером
2 parents 626dfc1 + 1a15ad1 commit ff1ac97

35 files changed

+2801
-4
lines changed

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ dependencies {
9191
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
9292
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
9393

94+
// graphs
95+
implementation("org.jgrapht", "jgrapht-core", "1.5.1")
96+
9497
// SARIF serialization
9598
implementation("com.contrastsecurity", "java-sarif", "2.0")
9699

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Все возможные пути выполнения функции должны содержать оператор Возврат (AllFunctionPathMustHaveReturn)
2+
3+
| Тип | Поддерживаются<br>языки | Важность | Включена<br>по умолчанию | Время на<br>исправление (мин) | Теги |
4+
|:-------------:|:-----------------------------:|:--------:|:------------------------------:|:-----------------------------------:|:------------------------------------------------------------:|
5+
| `Дефект кода` | `BSL`<br>`OS` | `Важный` | `Да` | `1` | `unpredictable`<br>`badpractice`<br>`suspicious` |
6+
7+
## Параметры
8+
9+
10+
| Имя | Тип | Описание | Значение<br>по умолчанию |
11+
|:--------------------------:|:--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------:|
12+
| `loopsExecutedAtLeastOnce` | `Булево` | `Считать, что циклы выполняются, как минимум, один раз.` | `true` |
13+
| `ignoreMissingElseOnExit` | `Булево` | `Игнорировать блоки Если-ИначеЕсли, которые не имеют ветки Иначе. Отключите, если нужно детектировать выход из метода по ложному условию в ИначеЕсли.` | `false` |
14+
<!-- Блоки выше заполняются автоматически, не трогать -->
15+
## Описание диагностики
16+
Каждая функция в языке 1С имеет в самом конце неявный оператор "Возврат Неопределено". Если управление доходит до конца функции, то функция возвращает неопределено.
17+
18+
Как правило, это не является штатным функционированием, программист должен явно описать все возвращаемые значения функции. Однако, довольно легко пропустить ситуацию, при которой управление дойдет до строки КонецФункции и вернется непредусмотренное значение Неопределено.
19+
20+
Данная диагностика проверяет, что все возможные пути выполнения функции имеют явный оператор Возврат и функция не возвращает непредвиденных значений.
21+
22+
## Примеры
23+
24+
### Неправильно
25+
26+
```bsl
27+
// если ставка заполнена, но не НДС10 и не НДС10 - вернется Неопределено
28+
// это может быть, как запланированное поведение,
29+
// так и ошибка проверки прочих вариантов.
30+
Функция ОпределитьСтавкуНДС(Знач Ставка)
31+
Если Ставка = Перечисления.СтавкиНДС.НДС20 Тогда
32+
Возврат 20;
33+
ИначеЕсли Ставка = Перечисления.СтавкиНДС.НДС10 Тогда
34+
Возврат 10;
35+
ИначеЕсли Не ЗначениеЗаполнено(Ставка) Тогда
36+
Возврат Константы.СтавкаНДСПоУмолчанию.Получить();
37+
КонецЕсли;
38+
39+
// здесь будет неявный возврат Неопределено
40+
КонецФункции
41+
```
42+
43+
### Правильно
44+
45+
```
46+
// явно указать намерение вернуть результат в конце функции.
47+
Функция ОпределитьСтавкуНДС(Знач Ставка)
48+
Если Ставка = Перечисления.СтавкиНДС.НДС20 Тогда
49+
Возврат 20;
50+
ИначеЕсли Ставка = Перечисления.СтавкиНДС.НДС10 Тогда
51+
Возврат 10;
52+
ИначеЕсли Не ЗначениеЗаполнено(Ставка) Тогда
53+
Возврат Константы.СтавкаНДСПоУмолчанию.Получить();
54+
КонецЕсли;
55+
56+
// Явно декларируем намерение вернуть Неопределено
57+
Возврат Неопределено;
58+
КонецФункции
59+
```
60+
61+
### Еще пример ошибочного кода:
62+
63+
```bsl
64+
Функция СуммаСкидки(Знач КорзинаЗаказа)
65+
Если КорзинаЗаказа.Строки.Количество() > 10 Тогда
66+
Возврат Скидки.СкидкаНаКрупнуюКорзину(КорзинаЗаказа);
67+
ИначеЕсли КорзинаЗаказа.ЕстьКартаЛояльности Тогда
68+
// функция возвращает непредусмотренное значение Неопределено
69+
Скидки.СкидкаПоКартеЛояльности(КорзинаЗаказа);
70+
Иначе
71+
Возврат 0;
72+
КонецЕсли;
73+
КонецФункции
74+
```
75+
76+
## Сниппеты
77+
78+
<!-- Блоки ниже заполняются автоматически, не трогать -->
79+
### Экранирование кода
80+
81+
```bsl
82+
// BSLLS:AllFunctionPathMustHaveReturn-off
83+
// BSLLS:AllFunctionPathMustHaveReturn-on
84+
```
85+
86+
### Параметр конфигурационного файла
87+
88+
```json
89+
"AllFunctionPathMustHaveReturn": {
90+
"loopsExecutedAtLeastOnce": true,
91+
"ignoreMissingElseOnExit": false
92+
}
93+
```

docs/diagnostics/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@
88

99
## Список реализованных диагностик
1010

11-
Общее количество: **143**
11+
Общее количество: **144**
1212

1313
* Потенциальная уязвимость: **4**
1414
* Уязвимость: **4**
1515
* Ошибка: **44**
16-
* Дефект кода: **91**
16+
* Дефект кода: **92**
1717

1818

1919
| Ключ | Название | Включена по умолчанию | Важность | Тип | Тэги |
2020
| --- | --- | :-: | --- | --- | --- |
21+
[AllFunctionPathMustHaveReturn](AllFunctionPathMustHaveReturn.md) | Все возможные пути выполнения функции должны содержать оператор Возврат | Да | Важный | Дефект кода | `unpredictable`<br>`badpractice`<br>`suspicious`
2122
[AssignAliasFieldsInQuery](AssignAliasFieldsInQuery.md) | Назначение псевдонимов выбранным полям в запросе | Да | Важный | Дефект кода | `standard`<br>`sql`<br>`badpractice`
2223
[BeginTransactionBeforeTryCatch](BeginTransactionBeforeTryCatch.md) | Нарушение правил работы с транзакциями для метода 'НачатьТранзакцию' | Да | Важный | Ошибка | `standard`
2324
[CachedPublic](CachedPublic.md) | Кеширование программного интерфейса | Да | Важный | Дефект кода | `standard`<br>`design`
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# All execution paths of a function must have a Return statement (AllFunctionPathMustHaveReturn)
2+
3+
| Type | Scope | Severity | Activated<br>by default | Minutes<br>to fix | Tags |
4+
|:------------:|:-------------------:|:--------:|:-----------------------------:|:-----------------------:|:------------------------------------------------------------:|
5+
| `Code smell` | `BSL`<br>`OS` | `Major` | `Yes` | `1` | `unpredictable`<br>`badpractice`<br>`suspicious` |
6+
7+
## Parameters
8+
9+
10+
| Name | Type | Description | Default value |
11+
|:--------------------------:|:---------:|:------------------------------------------------------------------------------------------------------------------:|:-------------:|
12+
| `loopsExecutedAtLeastOnce` | `Boolean` | `Assume loops are executed at least once` | `true` |
13+
| `ignoreMissingElseOnExit` | `Boolean` | `Ignore ElIf clauses which has no Else branch. Disable to detect exits from ElIf condition which results to False` | `false` |
14+
<!-- Блоки выше заполняются автоматически, не трогать -->
15+
## Description
16+
Functions should not have an implicit return. All returned values must be shown excplicitly.
17+
18+
## Examples
19+
```bsl
20+
Function CalculadeDiscount(ShoppingCart)
21+
If ShoppingCart.Rows.Count() > 10 Then
22+
Return Discounts.DiscountForABigCart(ShoppingCart);
23+
ElIf ShoppingCart.HasLoyaltyCard Then
24+
// Return is missed unintentionally
25+
// causing unexpected return of Undefined
26+
Discounts.DiscountByLoyaltyCard(ShoppingCart);
27+
Else
28+
Return 0;
29+
EndIf;
30+
EndFunction
31+
```
32+
33+
## Snippets
34+
35+
<!-- Блоки ниже заполняются автоматически, не трогать -->
36+
### Diagnostic ignorance in code
37+
38+
```bsl
39+
// BSLLS:AllFunctionPathMustHaveReturn-off
40+
// BSLLS:AllFunctionPathMustHaveReturn-on
41+
```
42+
43+
### Parameter for config
44+
45+
```json
46+
"AllFunctionPathMustHaveReturn": {
47+
"loopsExecutedAtLeastOnce": true,
48+
"ignoreMissingElseOnExit": false
49+
}
50+
```

docs/en/diagnostics/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ To escape individual sections of code or files from triggering diagnostics, you
88

99
## Implemented diagnostics
1010

11-
Total: **143**
11+
Total: **144**
1212

1313
* Security Hotspot: **4**
1414
* Vulnerability: **4**
1515
* Error: **44**
16-
* Code smell: **91**
16+
* Code smell: **92**
1717

1818

1919
| Key | Name| Enabled by default | Severity | Type | Tags |
2020
| --- | --- | :-: | --- | --- | --- |
21+
[AllFunctionPathMustHaveReturn](AllFunctionPathMustHaveReturn.md) | All execution paths of a function must have a Return statement | Yes | Major | Code smell | `unpredictable`<br>`badpractice`<br>`suspicious`
2122
[AssignAliasFieldsInQuery](AssignAliasFieldsInQuery.md) | Assigning aliases to selected fields in a query | Yes | Major | Code smell | `standard`<br>`sql`<br>`badpractice`
2223
[BeginTransactionBeforeTryCatch](BeginTransactionBeforeTryCatch.md) | Violating transaction rules for the 'BeginTransaction' method | Yes | Major | Error | `standard`
2324
[CachedPublic](CachedPublic.md) | Cached public methods | Yes | Major | Code smell | `standard`<br>`design`

0 commit comments

Comments
 (0)