Edit markers (command line): Difference between revisions

From Svacer Wiki
Line 110: Line 110:


== Примеры ==
== Примеры ==
Все примеры используют снимок [./Https://svacer.ispras.ru/mediawiki/images/6/66/Bash.zip bash]. Детекторы в данном снимке выглядят так:
Все примеры используют снимок [https://svacer.ispras.ru/mediawiki/images/6/66/Bash.zip bash]. Детекторы в данном снимке выглядят так:
[[File:Edit-markers-1.png|center|thumb|967x967px]]
[[File:Edit-markers-1.png|center|thumb|967x967px]]



Revision as of 18:42, 17 November 2025

Обзор

Функциональность edit-markers позволяет автоматически обрабатывать маркеры при импорте данных с помощью правил, заданных в JSON-файле. Поддерживаются три типа операций:

  • skip — пропуск (удаление) маркеров, соответствующих условию
  • change — изменение полей маркеров
  • deduplicate — объединение дублирующихся маркеров. У маркеров, подходящих под правило, объединяется трасса и остается только один (случайный) маркер с объединенной трассой, остальные маркеры удаляются.

Все операции происходят на стороне клиента до загрузки данных на сервер. При импорте результатов Svace, а также sarif (без указания флага --upload) изменяется .svacer-dir. Директория .svace-dir остается неизменной. Снимок остается неизменным при импорте.

Использование

Импорт результатов 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')" } ]

Изменение класса предупреждений

При необходимости возможно изменение полей маркера. В данном примере изменим warnclass маркеров у которых в названии есть UNREACHABLE_CODE и находящиеся после 1000 строки, но детектор UNREACHABLE_CODE изменять не будем.

[
 {
   "action": "change",
   "rules": "warnclass contains 'UNREACHABLE_CODE' and line > 1000",
   "change": {
     "warnclass": "UNREACHABLE",
     "msg": "Изменено правилами edit markers"
   }
 }
]

Указанные маркеры изменили свой детектор и описание.

Серьезность, Надежность и CWE привязаны к названию warnclass (детектора), поэтому, если указать несуществующий warnclass, то данные поля пропадут.

Удаление дубликатов

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

[
 {
   "action": "deduplicate",
   "rules": "file,warnclass"
 }
]

Тогда все маркеры, которые находятся в одном файле и с одним warnclass объединятся в один (случайным образом выберется один) и у него будет объединенный trace всех остальным маркеров.

Для данного примера видно, что все маркеры из файла /.build/alias.c объединились в один (так как у них был один warnclass) и их trace содержит все записи других маркеров. Аналогично произошло и с остальными маркерами, которые находились в одном файле и имели одинаковые warnclass.

Комплексный пример

В данном примере пропускаются все маркеры, у которых инструмент равен 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')"
 }
]

Работа с регулярными выражениями

Фильтрация по сложным паттернам путей. В данном случае будут пропущены маркеры, которые НЕ находятся в /.build/builtins, а также у них расширение не c, cpp, h, hpp (то есть оставляем только те маркеры, которые находятся в папке /.build/builtins с расширением c, cpp, h, hpp). В данном случае мы дважды экранируем: сначала слэш, а потом точку.

[
 {
   "action": "skip",
   "rules": "nregex(file, \"^/\\\\.build/builtins/.*\\\\.(c|cpp|h|hpp)$\")"
 }
]

В результате у нас остаются только подходящие маркеры:

Дополнительные опции

Сохранение отредактированного снимка

При импорте снимка можно сохранить результат применения правил:

 svacer server import  --edit-markers rules.json --save-edited-snapshot result.snap ...

Обязательно должно быть расширение .snap для сохранения.

Важные замечания

  1. Порядок правил — правила применяются последовательно в порядке их описания в файле
  2. Валидация — при загрузке правил проверяется корректность JSON и соответствие полей
  3. Формат файла — файл правил должен иметь расширение .json
  4. Логирование — результат применения правил выводится в лог (количество обработанных и удаленных маркеров)
  5. Поле line в change — должно быть строкой с неотрицательным числом
  6. Поле warnclass в change — может принимать только русские, английский буквы, цифры, а также специальные символы, которые находятся на цифровой панели клавиатуры (и печатаются через Shift)