Edit markers (command line): Difference between revisions
(edit markers descriptions change) |
(edit-markers change descriptions to more correct description) |
||
| (9 intermediate revisions by 2 users not shown) | |||
| Line 4: | Line 4: | ||
* '''skip''' — пропуск (удаление) маркеров, соответствующих условию | * '''skip''' — пропуск (удаление) маркеров, соответствующих условию | ||
* '''change''' — изменение полей маркеров | * '''change''' — изменение полей маркеров | ||
* '''deduplicate''' — объединение дублирующихся маркеров. У маркеров, подходящих под правило, | * '''deduplicate''' — объединение дублирующихся маркеров. У маркеров, подходящих под правило, объединяются уникальные трассы и остается только один маркер с наименьшим порядковым номером предупреждения (local_id) в файле результатов анализа. Остальные маркеры удаляются. | ||
Все операции происходят на стороне клиента до загрузки данных на сервер. При импорте результатов Svace, а также sarif (без указания флага --upload) изменяется .svacer-dir. Директория .svace-dir остается неизменной. Снимок остается неизменным при импорте. | Все операции происходят на стороне клиента до загрузки данных на сервер. При импорте результатов Svace, а также sarif (без указания флага --upload) изменяется .svacer-dir. Директория .svace-dir остается неизменной. Снимок остается неизменным при импорте. | ||
Данный функционал работает со снимками, созданными Svacer версии 7-0-0 и новее. Если у вас более старый снимок, то импортируйте и экспортируйте его для возможности работы с edit-markers. | |||
== Использование == | == Использование == | ||
=== Импорт результатов Svace === | === Импорт результатов Svace === | ||
<code>svacer import --edit-markers <файл_правил.json> [другие опции]</code> | <code>svacer import --edit-markers <файл_правил.json> [другие опции]</code> | ||
Применяет правила редактирования к маркерам при импорте результатов анализа Svace. | Применяет правила редактирования к маркерам при импорте результатов анализа Svace. | ||
| Line 43: | Line 45: | ||
... | ... | ||
{ | { | ||
"action": "skip", | |||
"rules": "file == 'test.cpp' and line > 100" | |||
} | } | ||
... | ... | ||
| Line 52: | Line 54: | ||
... | ... | ||
{ | { | ||
"action": "change", | |||
"rules": "warnclass == 'UNREACHABLE_CODE'", | |||
"change": { | |||
"warnclass": "IGNORED", | |||
"msg": "Код помечен как недостижимый" | |||
} | |||
} | } | ||
... | ... | ||
| Line 63: | Line 65: | ||
==== deduplicate — Дедупликация ==== | ==== deduplicate — Дедупликация ==== | ||
Объединяет маркеры с одинаковыми значениями указанных полей. | Объединяет маркеры с одинаковыми значениями указанных полей. Один маркер выбирается случайно, все trace от остальных маркеров добавляются к нему. | ||
... | ... | ||
{ | { | ||
| Line 77: | Line 79: | ||
В условиях можно использовать следующие поля: | В условиях можно использовать следующие поля: | ||
* <code>file</code> — путь к файлу (строка) | * <code>file</code> — полный путь к файлу (строка) | ||
* <code>line</code> — номер строки (число) | * <code>line</code> — номер строки (число) | ||
* <code>function</code> — имя функции (строка) | * <code>function</code> — имя функции (строка) | ||
| Line 110: | Line 112: | ||
== Примеры == | == Примеры == | ||
Часть примеров используют снимок [https://svacer.ispras.ru/mediawiki/images/6/66/Bash.zip bash]. Детекторы в данном снимке выглядят так: | |||
[[File:Edit-markers-1.png|center|thumb|967x967px]] | |||
=== Пропуск | === Пропуск файлов === | ||
В данном примере будут пропущены все файлы, которые находятся в папке <code>/.build/lib</code> | |||
[ | [ | ||
{ | { | ||
"action": "skip", | "action": "skip", | ||
"rules": " | "rules": "file contains '/.build/lib'" | ||
} | } | ||
] | ] | ||
Сравнивая исходный снимок и снимок, где было применено edit-markers можно увидеть 215 пропущенных детекторов. Все они находятся в папке <code>/.build/lib</code> | |||
[[File:Edit-markers-2.png|center|thumb|983x983px]] | |||
Если необходимо указать название не зависимо от регистра, то можно использовать функцию <code>icontains</code>: | |||
<code>[ { "action": "skip", "rules": "icontains(file, '/.build/lib')" } ]</code> | |||
Также после применения edit-markers в информации о снимке указывается, какие правила были применены | |||
[[File:Edit-marker.png|center|thumb|971x971px]] | |||
=== Изменение класса предупреждений === | === Изменение класса предупреждений === | ||
При необходимости возможно изменение полей маркера. В данном примере изменим warnclass маркеров у которых в названии есть <code>UNREACHABLE_CODE</code> и находящиеся после 1000 строки, но детектор <code>UNREACHABLE_CODE</code> изменять не будем. | |||
[ | [ | ||
{ | { | ||
"action": "change", | "action": "change", | ||
"rules": "warnclass | "rules": "warnclass contains 'UNREACHABLE_CODE' and line > 1000", | ||
"change": { | "change": { | ||
"warnclass": " | "warnclass": "UNREACHABLE", | ||
"msg": " | "msg": "Изменено правилами edit markers" | ||
} | } | ||
} | } | ||
] | ] | ||
[[File:Edit-markers-3.png|center|thumb|955x955px]] | |||
Указанные маркеры изменили свой детектор и описание. | |||
{{Note|text=Серьезность, Надежность и CWE привязаны к названию warnclass (детектора), поэтому, если указать''' '''несуществующий warnclass, то данные поля пропадут.}} | |||
=== Удаление дубликатов === | === Удаление дубликатов === | ||
Если необходимо объединить несколько детекторов в один по одинаковым полям, то возможно сделать следующее действие (в качестве полей rules можно указать 8 возможных значений, см. описание deduplicate). | |||
Например, в снимке содержится множество одинаковых детекторов в одном файле на одной строке. | |||
[[File:Edit-markers-dedup.png|center|thumb|933x933px]] | |||
Применив следующее правило все маркеры, которые находятся в одном файле, с одним детектором и на одной строке объединятся в один: выберется один с наименьшим порядковым номером предупреждения в файле результатов анализа (local_id) и у него будет объединенные уникальные трассы всех остальных маркеров. | |||
[ | [ | ||
{ | { | ||
"action": "deduplicate", | "action": "deduplicate", | ||
"rules": "file,line | "rules": "file,warnclass,line" | ||
} | } | ||
] | ] | ||
[[File:Edit-markers-dedup2.png|center|thumb|948x948px]] | |||
В данном примере у всех маркеров <code>UNUSED_FIELD</code> на строке 11 в файле <code>AddInstruction.cs</code> была трасса состоящая из трёх ролей: detected, info, Current function name. Роль detected полностью совпадала во всех маркерах, она была включена один раз, а все остальные роли добавились в объединенный маркер. Оставшиеся дублирующие маркеры были удалены. | |||
=== Комплексный пример === | === Комплексный пример === | ||
В данном примере пропускаются все маркеры, у которых инструмент равен <code>CSA</code>, а маркеры, которые имеют детекторы <code>'BAD_COPY_PASTE', 'DEREF_AFTER_NULL', 'UNUSED_VALUE'</code> или имеют в описании подстроку <code>unsafe</code> в любом регистре, меняют детектор и описание. | |||
[ | [ | ||
{ | { | ||
"action": "skip", | "action": "skip", | ||
"rules": " | "rules": "tool == 'CSA'" | ||
}, | }, | ||
{ | { | ||
"action": "change", | "action": "change", | ||
"rules": "warnclass in [' | "rules": "warnclass in ['BAD_COPY_PASTE', 'DEREF_AFTER_NULL', 'UNUSED_VALUE'] or icontains(msg, 'unsafe')", | ||
"change": { | "change": { | ||
"warnclass": " | "warnclass": "HIGH_PRIORITY", | ||
"msg": " | "msg": "Высокоприоритетное предупреждение" | ||
} | } | ||
} | } | ||
] | ] | ||
При сравнении с исходным снимком можно заметить, что 91 предупреждение, у которых инструмент был <code>CSA</code>, удалены из измененного снимка. | |||
[[File:Edit-markers-5.png|center|thumb|979x979px]] | |||
Также были изменены маркеры, в соответствии с правилами. | |||
[[File:Edit-markers-51.png|center|thumb|980x980px]] | |||
=== Изменение приоритета для определенных классов === | === Изменение приоритета для определенных классов === | ||
Изменение детекторов: | |||
[ | [ | ||
{ | { | ||
"action": "change", | "action": "change", | ||
"rules": "warnclass in ['UNREACHABLE_CODE. | "rules": "warnclass in ['UNREACHABLE_CODE.TERMINATION', 'UNREACHABLE_CODE.RET', 'UNREACHABLE_CODE.ENUM']", | ||
"change": { | "change": { | ||
"warnclass": "UNREACHABLE_CODE" | "warnclass": "UNREACHABLE_CODE" | ||
| Line 181: | Line 202: | ||
{ | { | ||
"action": "skip", | "action": "skip", | ||
"rules": "contains | "rules": "file contains 'generated' or hasPrefix(file, 'vendor/')" | ||
} | } | ||
] | ] | ||
| Line 199: | Line 220: | ||
=== Работа с регулярными выражениями === | === Работа с регулярными выражениями === | ||
В данном примере будут пропущены маркеры, путь к файлу которых НЕ соответствует регулярному выражению. В результате в снимке останутся только маркеры из файлов с расширениями <code>.c</code>, <code>.cpp</code>, <code>.h</code> или <code>.hpp</code>, находящихся в директории <code>/.build/builtins</code>. В данном случае мы дважды экранируем: сначала слэш, а потом точку. | |||
[ | [ | ||
{ | { | ||
"action": "skip", | "action": "skip", | ||
"rules": " | "rules": "nregex(file, \"^/\\\\.build/builtins/.*\\\\.(c|cpp|h|hpp)$\")" | ||
} | } | ||
] | ] | ||
В результате у нас остаются только подходящие маркеры: | |||
[[File:Edit-markers-8.png|center|thumb|979x979px]] | |||
== Дополнительные опции == | == Дополнительные опции == | ||
| Line 211: | Line 234: | ||
=== Сохранение отредактированного снимка === | === Сохранение отредактированного снимка === | ||
При импорте снимка можно сохранить результат применения правил: | При импорте снимка можно сохранить результат применения правил: | ||
svacer server import | svacer server import --edit-markers rules.json --save-edited-snapshot result.snap ... | ||
Обязательно должно быть расширение <code>.snap</code> для сохранения. | Обязательно должно быть расширение <code>.snap</code> для сохранения. | ||
| Line 221: | Line 244: | ||
# '''Логирование''' — результат применения правил выводится в лог (количество обработанных и удаленных маркеров) | # '''Логирование''' — результат применения правил выводится в лог (количество обработанных и удаленных маркеров) | ||
# '''Поле line в change''' — должно быть строкой с неотрицательным числом | # '''Поле line в change''' — должно быть строкой с неотрицательным числом | ||
# '''Поле warnclass в change''' — может принимать только русские | # '''Поле warnclass в change''' — может принимать только русские и английские буквы, цифры, а также специальные символы, которые находятся на цифровой панели клавиатуры (и печатаются через Shift) | ||
Latest revision as of 12:05, 19 November 2025
Обзор
Функциональность edit-markers позволяет автоматически обрабатывать маркеры при импорте данных с помощью правил, заданных в JSON-файле. Поддерживаются три типа операций:
- skip — пропуск (удаление) маркеров, соответствующих условию
- change — изменение полей маркеров
- deduplicate — объединение дублирующихся маркеров. У маркеров, подходящих под правило, объединяются уникальные трассы и остается только один маркер с наименьшим порядковым номером предупреждения (local_id) в файле результатов анализа. Остальные маркеры удаляются.
Все операции происходят на стороне клиента до загрузки данных на сервер. При импорте результатов Svace, а также sarif (без указания флага --upload) изменяется .svacer-dir. Директория .svace-dir остается неизменной. Снимок остается неизменным при импорте.
Данный функционал работает со снимками, созданными Svacer версии 7-0-0 и новее. Если у вас более старый снимок, то импортируйте и экспортируйте его для возможности работы с edit-markers.
Использование
Импорт результатов Svace
svacer import --edit-markers <файл_правил.json> [другие опции]
Применяет правила редактирования к маркерам при импорте результатов анализа Svace.
Импорт SARIF
svacer sarif2 import --edit-markers <файл_правил.json> [другие опции]
Применяет правила при импорте SARIF-файлов.
Импорт снимка с редактированием
svacer server import --edit-markers <файл_правил.json> [другие опции]
Применяет правила к снимку при импорте. Дополнительно можно сохранить отредактированный снимок:
svacer server import --edit-markers rules.json --save-edited-snapshot edited_snapshot.snap
Формат файла правил
Правила задаются в виде JSON-файла, содержащего массив объектов правил:
[
{
"action": "тип_действия",
"rules": "условие_или_список_полей",
"change": { /* только для action: "change" */ }
},
...
]
Типы действий
skip — Пропуск маркеров
Удаляет маркеры, соответствующие условию.
...
{
"action": "skip",
"rules": "file == 'test.cpp' and line > 100"
}
...
change — Изменение маркеров
Изменяет указанные поля маркеров.
...
{
"action": "change",
"rules": "warnclass == 'UNREACHABLE_CODE'",
"change": {
"warnclass": "IGNORED",
"msg": "Код помечен как недостижимый"
}
}
...
Доступные поля для изменения: warnclass, msg, lang, tool, file, details, line, mtid, function.
deduplicate — Дедупликация
Объединяет маркеры с одинаковыми значениями указанных полей. Один маркер выбирается случайно, все trace от остальных маркеров добавляются к нему.
...
{
"action": "deduplicate",
"rules": "file,line,warnclass"
}
...
Поля для группировки (можно указать от 1 до 8): file, line, function, warnclass, lang, tool, mtid, details.
Доступные поля и операторы
Поля маркеров
В условиях можно использовать следующие поля:
file— полный путь к файлу (строка)line— номер строки (число)function— имя функции (строка)warnclass— класс предупреждения (строка)lang— язык программирования (строка)tool— инструмент анализа (строка)mtid— ID типа маркера (строка)msg— сообщение маркера (строка)details— детали маркера (строка)
Операторы сравнения
==,!=— равно, не равно>,>=,<,<=— сравнение чиселand,or,&&,||— логические операторыnot,!— логическое НЕin— проверка вхождения в список (например:warnclass in ['ERROR', 'WARNING'])contains— проверка вхождения подстроки
Функции для работы со строками
icontains(s, substring)— содержит подстроку (без учета регистра)hasPrefix(s, prefix)— начинается с префиксаhasSuffix(s, suffix)— заканчивается суффиксомequalsFold(a, b)— сравнение строк без учета регистраlower(s)— преобразование в нижний регистрupper(s)— преобразование в верхний регистрtrim(s)— удаление пробелов в начале и конце строкиreplace(s, old, new)— замена всех вхождений подстрокиregex(s, pattern)— проверка соответствия регулярному выражениюnregex(s, pattern)— проверка НЕсоответствия регулярному выражению
Примеры
Часть примеров используют снимок bash. Детекторы в данном снимке выглядят так:

Пропуск файлов
В данном примере будут пропущены все файлы, которые находятся в папке /.build/lib
[
{
"action": "skip",
"rules": "file contains '/.build/lib'"
}
]
Сравнивая исходный снимок и снимок, где было применено edit-markers можно увидеть 215 пропущенных детекторов. Все они находятся в папке /.build/lib

Если необходимо указать название не зависимо от регистра, то можно использовать функцию icontains:
[ { "action": "skip", "rules": "icontains(file, '/.build/lib')" } ]
Также после применения edit-markers в информации о снимке указывается, какие правила были применены

Изменение класса предупреждений
При необходимости возможно изменение полей маркера. В данном примере изменим warnclass маркеров у которых в названии есть UNREACHABLE_CODE и находящиеся после 1000 строки, но детектор UNREACHABLE_CODE изменять не будем.
[
{
"action": "change",
"rules": "warnclass contains 'UNREACHABLE_CODE' and line > 1000",
"change": {
"warnclass": "UNREACHABLE",
"msg": "Изменено правилами edit markers"
}
}
]

Указанные маркеры изменили свой детектор и описание.
Удаление дубликатов
Если необходимо объединить несколько детекторов в один по одинаковым полям, то возможно сделать следующее действие (в качестве полей rules можно указать 8 возможных значений, см. описание deduplicate). Например, в снимке содержится множество одинаковых детекторов в одном файле на одной строке.

Применив следующее правило все маркеры, которые находятся в одном файле, с одним детектором и на одной строке объединятся в один: выберется один с наименьшим порядковым номером предупреждения в файле результатов анализа (local_id) и у него будет объединенные уникальные трассы всех остальных маркеров.
[
{
"action": "deduplicate",
"rules": "file,warnclass,line"
}
]

В данном примере у всех маркеров UNUSED_FIELD на строке 11 в файле AddInstruction.cs была трасса состоящая из трёх ролей: detected, info, Current function name. Роль detected полностью совпадала во всех маркерах, она была включена один раз, а все остальные роли добавились в объединенный маркер. Оставшиеся дублирующие маркеры были удалены.
Комплексный пример
В данном примере пропускаются все маркеры, у которых инструмент равен CSA, а маркеры, которые имеют детекторы 'BAD_COPY_PASTE', 'DEREF_AFTER_NULL', 'UNUSED_VALUE' или имеют в описании подстроку unsafe в любом регистре, меняют детектор и описание.
[
{
"action": "skip",
"rules": "tool == 'CSA'"
},
{
"action": "change",
"rules": "warnclass in ['BAD_COPY_PASTE', 'DEREF_AFTER_NULL', 'UNUSED_VALUE'] or icontains(msg, 'unsafe')",
"change": {
"warnclass": "HIGH_PRIORITY",
"msg": "Высокоприоритетное предупреждение"
}
}
]
При сравнении с исходным снимком можно заметить, что 91 предупреждение, у которых инструмент был CSA, удалены из измененного снимка.

Также были изменены маркеры, в соответствии с правилами.

Изменение приоритета для определенных классов
Изменение детекторов:
[
{
"action": "change",
"rules": "warnclass in ['UNREACHABLE_CODE.TERMINATION', 'UNREACHABLE_CODE.RET', 'UNREACHABLE_CODE.ENUM']",
"change": {
"warnclass": "UNREACHABLE_CODE"
}
}
]
Обработка сгенерированных файлов
Пропускаем все маркеры в сгенерированных файлах:
[
{
"action": "skip",
"rules": "file contains 'generated' or hasPrefix(file, 'vendor/')"
}
]
Дедупликация с последующей фильтрацией
Сначала объединяем дубликаты, потом удаляем ненужные:
[
{
"action": "deduplicate",
"rules": "file,line,warnclass,function"
},
{
"action": "skip",
"rules": "icontains(file, 'third_party') or icontains(file, 'external')"
}
]
Работа с регулярными выражениями
В данном примере будут пропущены маркеры, путь к файлу которых НЕ соответствует регулярному выражению. В результате в снимке останутся только маркеры из файлов с расширениями .c, .cpp, .h или .hpp, находящихся в директории /.build/builtins. В данном случае мы дважды экранируем: сначала слэш, а потом точку.
[
{
"action": "skip",
"rules": "nregex(file, \"^/\\\\.build/builtins/.*\\\\.(c|cpp|h|hpp)$\")"
}
]
В результате у нас остаются только подходящие маркеры:

Дополнительные опции
Сохранение отредактированного снимка
При импорте снимка можно сохранить результат применения правил:
svacer server import --edit-markers rules.json --save-edited-snapshot result.snap ...
Обязательно должно быть расширение .snap для сохранения.
Важные замечания
- Порядок правил — правила применяются последовательно в порядке их описания в файле
- Валидация — при загрузке правил проверяется корректность JSON и соответствие полей
- Формат файла — файл правил должен иметь расширение
.json - Логирование — результат применения правил выводится в лог (количество обработанных и удаленных маркеров)
- Поле line в change — должно быть строкой с неотрицательным числом
- Поле warnclass в change — может принимать только русские и английские буквы, цифры, а также специальные символы, которые находятся на цифровой панели клавиатуры (и печатаются через Shift)