PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
Один ΠΈΠ· самых Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… сцСнариСв использования Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° PVS-Studio β€” Π΅Π³ΠΎ интСграция с CI систСмами. И хотя Π°Π½Π°Π»ΠΈΠ· ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° PVS-Studio практичСски ΠΈΠ·-ΠΏΠΎΠ΄ любой continuous integration систСмы ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ всСго Π² нСсколько ΠΊΠΎΠΌΠ°Π½Π΄, ΠΌΡ‹ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ этот процСсс Π΅Ρ‰Ρ‘ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅. Π’ PVS-Studio появилась ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° прСобразования Π²Ρ‹Π²ΠΎΠ΄Π° Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ для TeamCity β€” TeamCity Inspections Type. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΊΠ°ΠΊ это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎΠ± ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΌ ПО

PVS-Studio β€” статичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π‘, Π‘++, C# ΠΈ Java ΠΊΠΎΠ΄Π°, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹ΠΉ для облСгчСния Π·Π°Π΄Π°Ρ‡ΠΈ поиска ΠΈ исправлСния Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° ошибок. Анализатор ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Windows, Linux ΠΈ macOS. Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сам Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€, Π½ΠΎ ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹ ΠΈΠ· Π΅Π³ΠΎ дистрибутива.

CLMonitor β€” прСдставляСт собой сСрвСр ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ осущСствляСт отслСТиваниС запусков компиляторов. Π•Π³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ нСпосрСдствСнно ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ сборки вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π’ Ρ€Π΅ΠΆΠΈΠΌΠ΅ отслСТивания сСрвСр Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ запуски всСх ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… компиляторов. Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½ΡƒΡŽ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π°Π½Π°Π»ΠΈΠ·Π° C/Π‘++ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ².

PlogConverter – ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° для ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ ΠΎΡ‚Ρ‡Ρ‘Ρ‚Π° Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° Π² Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹.

Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎΠ± исслСдуСмом ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅

Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Π΄Π°Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π½Π° практичСском ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ – ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ OpenRCT2.

OpenRCT2 β€” открытая рСализация ΠΈΠ³Ρ€Ρ‹ RollerCoaster Tycoon 2 (RCT2), Ρ€Π°ΡΡˆΠΈΡ€ΡΡŽΡ‰Π°Ρ Π΅Ρ‘ Π½ΠΎΠ²Ρ‹ΠΌΠΈ функциями ΠΈ ΠΈΡΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π°Ρ ошибки. Π˜Π³Ρ€ΠΎΠ²ΠΎΠΉ процСсс вращаСтся Π²ΠΎΠΊΡ€ΡƒΠ³ ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΡΡ‚Π²Π° ΠΈ содСрТания ΠΏΠ°Ρ€ΠΊΠ° Ρ€Π°Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠΉ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ находятся Π°Ρ‚Ρ‚Ρ€Π°ΠΊΡ†ΠΈΠΎΠ½Ρ‹, ΠΌΠ°Π³Π°Π·ΠΈΠ½Ρ‹ ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Π˜Π³Ρ€ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΡΡ‚Π°Ρ€Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ±Ρ‹Π»ΡŒ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΡƒΡŽ Ρ€Π΅ΠΏΡƒΡ‚Π°Ρ†ΠΈΡŽ ΠΏΠ°Ρ€ΠΊΠ°, сохраняя ΠΏΡ€ΠΈ этом гостСй счастливыми. OpenRCT2 позволяСт ΠΈΠ³Ρ€Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π² сцСнарии, Ρ‚Π°ΠΊ ΠΈ Π² пСсочницС. Π‘Ρ†Π΅Π½Π°Ρ€ΠΈΠΈ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ» ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ Π² установлСнноС врСмя, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ пСсочница позволяСт ΠΈΠ³Ρ€ΠΎΠΊΡƒ ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΏΠ°Ρ€ΠΊ Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ финансов.

Настройка

Π’ цСлях экономии Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ я, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, ΠΎΠΏΡƒΡ‰Ρƒ процСсс установки ΠΈ Π½Π°Ρ‡Π½Ρƒ с Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° Ρƒ мСня Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅ Π·Π°ΠΏΡƒΡ‰Π΅Π½ сСрвСр TeamCity. Нам Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ: localhost:{ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π² процСссС установки ΠΏΠΎΡ€Ρ‚}(Π² ΠΌΠΎΡ‘ΠΌ случаС, localhost:9090) ΠΈ ввСсти Π΄Π°Π½Π½Ρ‹Π΅ для Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ. ПослС Π²Ρ…ΠΎΠ΄Π° нас встрСтит:

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
НаТмём Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ Create Project. Π”Π°Π»Π΅Π΅ Π²Ρ‹Π±Π΅Ρ€Π΅ΠΌ Manually, Π·Π°ΠΏΠΎΠ»Π½ΠΈΠΌ поля.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
ПослС наТатия Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ Create, нас встрСчаСт ΠΎΠΊΠ½ΠΎ с настройками.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
НаТмём Create build configuration.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
ЗаполняСм поля, Π½Π°ΠΆΠΈΠΌΠ°Π΅ΠΌ Create. ΠœΡ‹ Π²ΠΈΠ΄ΠΈΠΌ ΠΎΠΊΠ½ΠΎ с ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π²Ρ‹Π±ΠΎΡ€Π° систСмы контроля вСрсий. Π’Π°ΠΊ ΠΊΠ°ΠΊ исходники ΡƒΠΆΠ΅ Π»Π΅ΠΆΠ°Ρ‚ локально, ΠΆΠΌΡ‘ΠΌ Skip.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
НаконСц, ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊ настройкам ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
Π”ΠΎΠ±Π°Π²ΠΈΠΌ шаги сборки, для этого ΠΆΠΌΡ‘ΠΌ: Build steps -> Add build step.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
Π’ΡƒΡ‚ Π²Ρ‹Π±Π΅Ρ€Π΅ΠΌ:

  • Runner type -> Command Line
  • Run -> Custom Script

Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ· Π²ΠΎ врСмя компиляции ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, сборка ΠΈ Π°Π½Π°Π»ΠΈΠ· Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄Π½ΠΈΠΌ шагом, поэтому Π·Π°ΠΏΠΎΠ»Π½ΠΈΠΌ ΠΏΠΎΠ»Π΅ Custom Script:

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
На ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΡˆΠ°Π³Π°Ρ… ΠΌΡ‹ остановимся ΠΏΠΎΠ·ΠΆΠ΅. Π’Π°ΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, сборка ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π΅Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·, Π²Ρ‹Π²ΠΎΠ΄ ΠΎΡ‚Ρ‡Ρ‘Ρ‚Π° ΠΈ Π΅Π³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ заняло всСго ΠΎΠ΄ΠΈΠ½Π½Π°Π΄Ρ†Π°Ρ‚ΡŒ строк ΠΊΠΎΠ΄Π°.

ПослСднСС, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, β€” ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ я ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΠ» Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ ΠΈΡ… Ρ‡ΠΈΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Для этого ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Ρ‘ΠΌ: Parameters -> Add new parameter ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Ρ‚Ρ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅:

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
ΠžΡΡ‚Π°Ρ‘Ρ‚ΡΡ Π½Π°ΠΆΠ°Ρ‚ΡŒ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ Run Π² ΠΏΡ€Π°Π²ΠΎΠΌ Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ ΡƒΠ³Π»Ρƒ. Пока ΠΈΠ΄Ρ‘Ρ‚ сборка ΠΈ Π°Π½Π°Π»ΠΈΠ· ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° расскаТу Π²Π°ΠΌ ΠΎ скриптС.

НСпосрСдствСнно скрипт

Для Π½Π°Ρ‡Π°Π»Π° Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΠΊΠ°Ρ‡Π°Ρ‚ΡŒ свСТий дистрибутив PVS-Studio. Для этого ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚Π½Ρ‹ΠΉ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ Π‘hocolatey. Для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ Ρ…ΠΎΡ‡Π΅Ρ‚ ΡƒΠ·Π½Π°Ρ‚ΡŒ ΠΎΠ± этом ΠΏΠΎΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ ΡΡ‚Π°Ρ‚ΡŒΡ:

choco install pvs-studio -y

Π”Π°Π»Π΅Π΅ запустим ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρƒ отслСТивания сборки ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° CLMonitor.

%CLmon% monitor –-attach

ΠŸΠΎΡ‚ΠΎΠΌ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Ρ‘ΠΌ сборку ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π² качСствС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ окруТСния MSB выступаСт ΠΏΡƒΡ‚ΡŒ ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΉ ΠΌΠ½Π΅ для сборки вСрсии MSBuild

%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable

Π’Π²Π΅Π΄Ρ‘ΠΌ Π»ΠΎΠ³ΠΈΠ½ ΠΈ ΠΊΠ»ΡŽΡ‡ Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ PVS-Studio:

%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%

ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ сборки Π΅Ρ‰Ρ‘ Ρ€Π°Π· запустим CLMonitor для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ прСпроцСссированных Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ статичСского Π°Π½Π°Π»ΠΈΠ·Π°:

%CLmon% analyze -l "c:ptest.plog"

ПослС Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½ΠΎΠΉ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚ΠΎΠΉ ΠΈΠ· нашСго дистрибутива. PlogConverter ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΎΡ‚Ρ‡Ρ‘Ρ‚ ΠΈΠ· стандартного Π² спСцифичный для TeamCity Ρ„ΠΎΡ€ΠΌΠ°Ρ‚. Благодаря этому ΠΌΡ‹ смоТСм ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π΅Π³ΠΎ прямо Π² ΠΎΠΊΠ½Π΅ сборки.

%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"

ПослСдним дСйствиСм Π²Ρ‹Π²Π΅Π΄Π΅ΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΡ‚Ρ‡Ρ‘Ρ‚ Π² stdout, Π³Π΄Π΅ Π΅Π³ΠΎ ΠΏΠΎΠ΄Ρ…Π²Π°Ρ‚ΠΈΡ‚ парсСр TeamCity.

type "C:tempptest.plog_TeamCity.txt"

ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ скрипта:

choco install pvs-studio -y
%CLmon% monitor --attach
set platform=x64
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
%CLmon% analyze -l "c:ptest.plog"
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
type "C:tempptest.plog_TeamCity.txt"

Π’Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ, сборка ΠΈ Π°Π½Π°Π»ΠΈΠ· ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΠΈΡΡŒ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π½Π° Π²ΠΊΠ»Π°Π΄ΠΊΡƒ Projects ΠΈ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² этом.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΊΠ»ΠΈΠΊΠ½Π΅ΠΌ Π½Π° Inspections Total, Ρ‡Ρ‚ΠΎΠ± ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ просмотру ΠΎΡ‚Ρ‡Ρ‘Ρ‚Π° Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°:

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΡ сгруппированы ΠΏΠΎ Π½ΠΎΠΌΠ΅Ρ€Π°ΠΌ диагностичСских ΠΏΡ€Π°Π²ΠΈΠ». Для осущСствлСния Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ Π½ΡƒΠΆΠ½ΠΎ ΠΊΠ»ΠΈΠΊΠ½ΡƒΡ‚ΡŒ Π½Π° Π½ΠΎΠΌΠ΅Ρ€ строки с ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ. НаТатиС Π½Π° Π·Π½Π°ΠΊ вопроса Π² ΠΏΡ€Π°Π²ΠΎΠΌ Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ ΡƒΠ³Π»Ρƒ ΠΎΡ‚ΠΊΡ€ΠΎΠ΅Ρ‚ Π²Π°ΠΌ Π½ΠΎΠ²ΡƒΡŽ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ с Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ. Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΈΡ‚ΡŒ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ, Π½Π°ΠΆΠ°Π² Π½Π° Π½ΠΎΠΌΠ΅Ρ€ строки с ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°. Навигация с ΡƒΠ΄Π°Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ΠΏΡ€ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ SourceTreeRoot ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π°. Π’ΠΎΡ‚, ΠΊΠΎΠΌΡƒ интСрСсСн Π΄Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ Ρ€Π°Π·Π΄Π΅Π»ΠΎΠΌ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°

ПослС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΌΡ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ с Ρ€Π°Π·Π²Ρ‘Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ΠΌ ΠΈ настройкой сборки, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ интСрСсныС прСдупрСТдСния, ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Π΅ Π² исслСдуСмом ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅.

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N1

V773 [CWE-401] The exception was thrown without releasing the 'result' pointer. A memory leak is possible. libopenrct2 ObjectFactory.cpp 443

Object* CreateObjectFromJson(....)
{
  Object* result = nullptr;
  ....
  result = CreateObject(entry);
  ....
  if (readContext.WasError())
  {
    throw std::runtime_error("Object has errors");
  }
  ....
}

Object* CreateObject(const rct_object_entry& entry)
{
  Object* result;
  switch (entry.GetType())
  {
    case OBJECT_TYPE_RIDE:
      result = new RideObject(entry);
      break;
    case OBJECT_TYPE_SMALL_SCENERY:
      result = new SmallSceneryObject(entry);
      break;
    case OBJECT_TYPE_LARGE_SCENERY:
      result = new LargeSceneryObject(entry);
      break;
    ....
    default:
      throw std::runtime_error("Invalid object type");
  }
  return result;
}

Анализатор Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ» ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π·Π°ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΡƒΡŽΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ послС динамичСского выдСлСния памяти Π² CreateObject, ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ очищаСтся, соотвСтствСнно, Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΡƒΡ‚Π΅Ρ‡ΠΊΠ° памяти.

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N2

V501 There are identical sub-expressions '(1ULL << WIDX_MONTH_BOX)' to the left and to the right of the '|' operator. libopenrct2ui Cheats.cpp 487

static uint64_t window_cheats_page_enabled_widgets[] = 
{
  MAIN_CHEAT_ENABLED_WIDGETS |
  (1ULL << WIDX_NO_MONEY) |
  (1ULL << WIDX_ADD_SET_MONEY_GROUP) |
  (1ULL << WIDX_MONEY_SPINNER) |
  (1ULL << WIDX_MONEY_SPINNER_INCREMENT) |
  (1ULL << WIDX_MONEY_SPINNER_DECREMENT) |
  (1ULL << WIDX_ADD_MONEY) |
  (1ULL << WIDX_SET_MONEY) |
  (1ULL << WIDX_CLEAR_LOAN) |
  (1ULL << WIDX_DATE_SET) |
  (1ULL << WIDX_MONTH_BOX) |  // <=
  (1ULL << WIDX_MONTH_UP) |
  (1ULL << WIDX_MONTH_DOWN) |
  (1ULL << WIDX_YEAR_BOX) |
  (1ULL << WIDX_YEAR_UP) |
  (1ULL << WIDX_YEAR_DOWN) |
  (1ULL << WIDX_DAY_BOX) |
  (1ULL << WIDX_DAY_UP) |
  (1ULL << WIDX_DAY_DOWN) |
  (1ULL << WIDX_MONTH_BOX) |  // <=
  (1ULL << WIDX_DATE_GROUP) |
  (1ULL << WIDX_DATE_RESET),
  ....
};

Мало ΠΊΡ‚ΠΎ, ΠΊΡ€ΠΎΠΌΠ΅ статичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, смог Π±Ρ‹ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ Π΄Π°Π½Π½Ρ‹ΠΉ тСст Π½Π° Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. Π”Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ копипасты Ρ…ΠΎΡ€ΠΎΡˆ ΠΈΠΌΠ΅Π½Π½ΠΎ этим.

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΡ N3

V703 It is odd that the 'flags' field in derived class 'RCT12BannerElement' overwrites field in base class 'RCT12TileElementBase'. Check lines: RCT12.h:570, RCT12.h:259. libopenrct2 RCT12.h 570

struct RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};
struct rct1_peep : RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, использованиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ с ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ классС ΠΈ Π² наслСдникС Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ всСгда являСтся ошибкой. Однако тСхнология наслСдования сама ΠΏΠΎ сСбС ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ всСх ΠΏΠΎΠ»Π΅ΠΉ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ класса Π² Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌ. Объявив ΠΆΠ΅ Π² наслСдникС поля с Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΠΌΡ‹ вносим ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Ρƒ.

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N4

V793 It is odd that the result of the 'imageDirection / 8' statement is a part of the condition. Perhaps, this statement should have been compared with something else. libopenrct2 ObservationTower.cpp 38

void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
  if ((imageDirection / 8) && (imageDirection / 8) != 3)
  {
    ....
  }
  ....
}

Π”Π°Π²Π°ΠΉΡ‚Π΅ разбСрёмся ΠΏΠΎΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅. Π’Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ imageDirection / 8 Π±ΡƒΠ΄Π΅Ρ‚ false Π² Ρ‚ΠΎΠΌ случаС, Ссли imageDirection находится Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ ΠΎΡ‚ -7 Π΄ΠΎ 7. Вторая Ρ‡Π°ΡΡ‚ΡŒ: (imageDirection / 8) != 3 провСряСт imageDirection Π½Π° Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π²Π½Π΅ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°: ΠΎΡ‚ -31 Π΄ΠΎ -24 ΠΈ ΠΎΡ‚ 24 Π΄ΠΎ 31 соотвСтствСнно. МнС каТСтся довольно странным ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ числа Π½Π° Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΉ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ Ρ‚Π°ΠΊΠΈΠΌ способом ΠΈ, Π΄Π°ΠΆΠ΅ Ссли Π² Π΄Π°Π½Π½ΠΎΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ ΠΊΠΎΠ΄Π° Π½Π΅Ρ‚ ошибки, я Π±Ρ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π» ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ условия Π½Π° Π±ΠΎΠ»Π΅Π΅ явныС. Π­Ρ‚ΠΎ сущСствСнно упростило Π±Ρ‹ Тизнь людям, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ этот ΠΊΠΎΠ΄.

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N5

V587 An odd sequence of assignments of this kind: A = B; B = A;. Check lines: 1115, 1118. libopenrct2ui MouseInput.cpp 1118

void process_mouse_over(....)
{
  ....
  switch (window->widgets[widgetId].type)
  {
    case WWT_VIEWPORT:
      ebx = 0;
      edi = cursorId;                                 // <=
      // Window event WE_UNKNOWN_0E was called here,
      // but no windows actually implemented a handler and
      // it's not known what it was for
      cursorId = edi;                                 // <=
      if ((ebx & 0xFF) != 0)
      {
        set_cursor(cursorId);
        return;
      }
      break;
      ....
  }
  ....
}

Π”Π°Π½Π½Ρ‹ΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π°, скорСС всСго, Π±Ρ‹Π» ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΏΡƒΡ‚Π΅ΠΌ дСкомпиляции. Π—Π°Ρ‚Π΅ΠΌ, судя ΠΏΠΎ оставлСнному ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡŽ, Π±Ρ‹Π»Π° ΡƒΠ΄Π°Π»Π΅Π½Π° Ρ‡Π°ΡΡ‚ΡŒ Π½Π΅Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ ΠΊΠΎΠ΄Π°. Однако ΠΎΡΡ‚Π°Π»Π°ΡΡŒ ΠΏΠ°Ρ€Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π°Π΄ cursorId, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ нСсут особого смысла.

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N6

V1004 [CWE-476] The 'player' pointer was used unsafely after it was verified against nullptr. Check lines: 2085, 2094. libopenrct2 Network.cpp 2094

void Network::ProcessPlayerList()
{
  ....
  auto* player = GetPlayerByID(pendingPlayer.Id);
  if (player == nullptr)
  {
    // Add new player.
    player = AddPlayer("", "");
    if (player)                                          // <=
    {
      *player = pendingPlayer;
       if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
       {
         _serverConnection->Player = player;
       }
    }
    newPlayers.push_back(player->Id);                    // <=
  }
  ....
}

Π”Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ довольно просто, Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ»ΠΈ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ Ρ€Π°Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ player Π½Π° Π½ΡƒΠ»Π΅Π²ΠΎΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, Π»ΠΈΠ±ΠΎ внСсти Π΅Π³ΠΎ Π² Ρ‚Π΅Π»ΠΎ условного ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°. Π― Π±Ρ‹ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈΠ» Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚:

void Network::ProcessPlayerList()
{
  ....
  auto* player = GetPlayerByID(pendingPlayer.Id);
  if (player == nullptr)
  {
    // Add new player.
    player = AddPlayer("", "");
    if (player)
    {
      *player = pendingPlayer;
      if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
      {
        _serverConnection->Player = player;
      }
      newPlayers.push_back(player->Id);
    }
  }
  ....
}

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N7

V547 [CWE-570] Expression 'name == nullptr' is always false. libopenrct2 ServerList.cpp 102

std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
  auto name = json_object_get(server, "name");
  .....
  if (name == nullptr || version == nullptr)
  {
    ....
  }
  else
  {
    ....
    entry.name = (name == nullptr ? "" : json_string_value(name));
    ....
  }
  ....
}

МоТно ΠΎΠ΄Π½ΠΈΠΌ ΠΌΠ°Ρ…ΠΎΠΌ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΉ строки ΠΊΠΎΠ΄Π° ΠΈ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ с ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΎΠΉ Π½Π° nullptr. ΠŸΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
  auto name = json_object_get(server, "name");
  .....
  if (name == nullptr || version == nullptr)
  {
    name = ""
    ....
  }
  else
  {
    ....
    entry.name = json_string_value(name);
    ....
  }
  ....
}

ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ N8

V1048 [CWE-1164] The 'ColumnHeaderPressedCurrentState' variable was assigned the same value. libopenrct2ui CustomListView.cpp 510

void CustomListView::MouseUp(....)
{
  ....
  if (!ColumnHeaderPressedCurrentState)
  {
    ColumnHeaderPressed = std::nullopt;
    ColumnHeaderPressedCurrentState = false;
    Invalidate();
  }
}

Код выглядит довольно странно. МнС каТСтся, ΠΈΠΌΠ΅Π»Π° мСсто Π±Ρ‹Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° Π»ΠΈΠ±ΠΎ Π² условии, Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΌ присвоСнии ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ColumnHeaderPressedCurrentState значСния false.

Π’Ρ‹Π²ΠΎΠ΄

Как ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ статичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ PVS-Studio Π² свой ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π½Π° TeamCity довольно просто. Для этого достаточно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ всСго ΠΎΠ΄ΠΈΠ½ малСнький Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΊΠΎΠ΄Π° ΠΆΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π²Ρ‹ΡΠ²Π»ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ сразу послС сборки, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Ρ€Π°Π½ΡΡ‚ΡŒ ΠΈΡ… Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈ ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ ΠΏΡ€Π°Π²ΠΎΠΊ Π΅Ρ‰Ρ‘ ΠΌΠ°Π»Ρ‹.

PVS-Studio ΠΈ Continuous Integration: TeamCity. Анализ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Open RollerCoaster Tycoon 2
Если Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ΠΉ с англоязычной Π°ΡƒΠ΄ΠΈΡ‚ΠΎΡ€ΠΈΠ΅ΠΉ, Ρ‚ΠΎ ΠΏΡ€ΠΎΡˆΡƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ссылку Π½Π° ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄: Vladislav Stolyarov. PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ