Edit markers (command line): Difference between revisions

From Svacer Wiki
(more describe about edit-markers)
(edit-markers change descriptions to more correct description)
 
(10 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 28: Line 30:
== Формат файла правил ==
== Формат файла правил ==
Правила задаются в виде JSON-файла, содержащего массив объектов правил:
Правила задаются в виде JSON-файла, содержащего массив объектов правил:
   [{
[
   {
     "action": "тип_действия",
     "action": "тип_действия",
     "rules": "условие_или_список_полей",
     "rules": "условие_или_список_полей",
     "change": { /* только для action: "change" */ }
     "change": { /* только для action: "change" */ }
   }]
   },
  ...
]


=== Типы действий ===
=== Типы действий ===
Line 38: Line 43:
==== skip — Пропуск маркеров ====
==== skip — Пропуск маркеров ====
Удаляет маркеры, соответствующие условию.
Удаляет маркеры, соответствующие условию.
...
  {
  {
  "action": "skip",
  "action": "skip",
  "rules": "file == 'test.cpp' and line > 100"
  "rules": "file == 'test.cpp' and line > 100"
  }
  }
...


==== change — Изменение маркеров ====
==== change — Изменение маркеров ====
Изменяет указанные поля маркеров.
Изменяет указанные поля маркеров.
  {
...
<nowiki> </nowiki>"action": "change",
{
<nowiki> </nowiki>"rules": "warnclass == 'UNREACHABLE_CODE'",
  "action": "change",
<nowiki> </nowiki>"change": {
  "rules": "warnclass == 'UNREACHABLE_CODE'",
<nowiki> </nowiki>  "warnclass": "IGNORED",
  "change": {
<nowiki> </nowiki>  "msg": "Код помечен как недостижимый"
    "warnclass": "IGNORED",
  <nowiki> </nowiki>}}
    "msg": "Код помечен как недостижимый"
  }
  }
...
Доступные поля для изменения: <code>warnclass</code>, <code>msg</code>, <code>lang</code>, <code>tool</code>, <code>file</code>, <code>details</code>, <code>line</code>, <code>mtid</code>, <code>function</code>.
Доступные поля для изменения: <code>warnclass</code>, <code>msg</code>, <code>lang</code>, <code>tool</code>, <code>file</code>, <code>details</code>, <code>line</code>, <code>mtid</code>, <code>function</code>.


==== deduplicate — Дедупликация ====
==== deduplicate — Дедупликация ====
Объединяет маркеры с одинаковыми значениями указанных полей.
Объединяет маркеры с одинаковыми значениями указанных полей. Один маркер выбирается случайно, все trace от остальных маркеров добавляются к нему.
...
  {
  {
   "action": "deduplicate",
   "action": "deduplicate",
   "rules": "file,line,warnclass"
   "rules": "file,line,warnclass"
  }
  }
...
Поля для группировки (можно указать от 1 до 8): <code>file</code>, <code>line</code>, <code>function</code>, <code>warnclass</code>, <code>lang</code>, <code>tool</code>, <code>mtid</code>, <code>details</code>.
Поля для группировки (можно указать от 1 до 8): <code>file</code>, <code>line</code>, <code>function</code>, <code>warnclass</code>, <code>lang</code>, <code>tool</code>, <code>mtid</code>, <code>details</code>.


Line 67: Line 79:
В условиях можно использовать следующие поля:
В условиях можно использовать следующие поля:


* <code>file</code> — путь к файлу (строка)
* <code>file</code> — полный путь к файлу (строка)
* <code>line</code> — номер строки (число)
* <code>line</code> — номер строки (число)
* <code>function</code> — имя функции (строка)
* <code>function</code> — имя функции (строка)
Line 100: 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": "icontains(file, 'test') or icontains(file, 'spec')"
     "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 == 'UNREACHABLE_CODE' and icontains(file, 'generated')",
     "rules": "warnclass contains 'UNREACHABLE_CODE' and line > 1000",
     "change": {
     "change": {
       "warnclass": "INFO",
       "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,warnclass"
     "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": "file == '.build/src/generated.c'"
     "rules": "tool == 'CSA'"
  },
  {
    "action": "deduplicate",
    "rules": "file,line,function"
   },
   },
   {
   {
     "action": "change",
     "action": "change",
     "rules": "warnclass in ['DEBUG', 'TRACE', 'INFO'] and line > 1000",
     "rules": "warnclass in ['BAD_COPY_PASTE', 'DEREF_AFTER_NULL', 'UNUSED_VALUE'] or icontains(msg, 'unsafe')",
     "change": {
     "change": {
       "warnclass": "LOW_PRIORITY",
       "warnclass": "HIGH_PRIORITY",
       "msg": "Низкоприоритетное предупреждение в длинном файле"
       "msg": "Высокоприоритетное предупреждение"
     }
     }
  },
  {
    "action": "skip",
    "rules": "regex(file, \".*_test\\\\.(c|cpp)$\")"
   }
   }
  ]
  ]
При сравнении с исходным снимком можно заметить, что 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.ENUM', 'UNREACHABLE_CODE.RET', 'UNUSED_VALUE.PARAM_ASSIGN']",
     "rules": "warnclass in ['UNREACHABLE_CODE.TERMINATION', 'UNREACHABLE_CODE.RET', 'UNREACHABLE_CODE.ENUM']",
     "change": {
     "change": {
       "warnclass": "UNREACHABLE_CODE"
       "warnclass": "UNREACHABLE_CODE"
Line 171: Line 202:
   {
   {
     "action": "skip",
     "action": "skip",
     "rules": "contains(file, 'generated') or contains(file, '.build') or hasPrefix(file, 'vendor/')"
     "rules": "file contains 'generated' or hasPrefix(file, 'vendor/')"
   }
   }
  ]
  ]
Line 189: Line 220:


=== Работа с регулярными выражениями ===
=== Работа с регулярными выражениями ===
Фильтрация по сложным паттернам путей:
В данном примере будут пропущены маркеры, путь к файлу которых НЕ соответствует регулярному выражению. В результате в снимке останутся только маркеры из файлов с расширениями <code>.c</code>, <code>.cpp</code>, <code>.h</code> или <code>.hpp</code>, находящихся в директории <code>/.build/builtins</code>. В данном случае мы дважды экранируем: сначала слэш, а потом точку.
  [
  [
   {
   {
     "action": "skip",
     "action": "skip",
     "rules": "regex(file, \"^(tests?|spec|mock|stub)/.*$\") or nregex(file, \"^src/.*\\.(c|cpp|h|hpp)$\")"
     "rules": "nregex(file, \"^/\\\\.build/builtins/.*\\\\.(c|cpp|h|hpp)$\")"
   }
   }
  ]
  ]
В результате у нас остаются только подходящие маркеры:
[[File:Edit-markers-8.png|center|thumb|979x979px]]


== Дополнительные опции ==
== Дополнительные опции ==
Line 201: Line 234:
=== Сохранение отредактированного снимка ===
=== Сохранение отредактированного снимка ===
При импорте снимка можно сохранить результат применения правил:
При импорте снимка можно сохранить результат применения правил:
   svacer server import --edit-markers rules.json --save-edited-snapshot result.snap ...
   svacer server import --edit-markers rules.json --save-edited-snapshot result.snap ...
Обязательно должно быть расширение <code>.snap</code> для сохранения.
Обязательно должно быть расширение <code>.snap</code> для сохранения.


Line 211: Line 244:
# '''Логирование''' — результат применения правил выводится в лог (количество обработанных и удаленных маркеров)
# '''Логирование''' — результат применения правил выводится в лог (количество обработанных и удаленных маркеров)
# '''Поле line в change''' — должно быть строкой с неотрицательным числом
# '''Поле line в change''' — должно быть строкой с неотрицательным числом
# '''Поле warnclass в change''' — может принимать только русские, английский буквы, цифры, а также специальные символы, которые находятся на цифровой панели клавиатуры (и печатаются через Shift)
# '''Поле 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"
   }
 }
]

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

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

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

Если необходимо объединить несколько детекторов в один по одинаковым полям, то возможно сделать следующее действие (в качестве полей 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 для сохранения.

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

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