Edit markers (command line)
Обзор
Функциональность 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)