PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Usa sa pinakabag-o nga mga senaryo sa paggamit sa PVS-Studio analyzer mao ang pag-integrate niini sa mga sistema sa CI. Ug bisan kung ang pag-analisar sa usa ka proyekto sa PVS-Studio gikan sa hapit bisan unsang padayon nga sistema sa panagsama mahimong matukod sa pipila ra nga mga mando, padayon namon nga gihimo kini nga proseso nga labi ka dali. Ang PVS-Studio karon adunay suporta alang sa pag-convert sa analisador nga output ngadto sa format para sa TeamCity - TeamCity Inspections Type. Atong tan-awon kon sa unsang paagi kini molihok.

Impormasyon bahin sa software nga gigamit

PVS Studio β€” usa ka static analyzer sa C, C++, C# ug Java code, nga gidisenyo aron mapadali ang tahas sa pagpangita ug pagtul-id sa lainlaing mga lahi sa mga sayup. Ang analista mahimong magamit sa Windows, Linux ug macOS. Niini nga artikulo aktibo natong gamiton dili lamang ang analista mismo, kondili usab ang pipila ka mga utilities gikan sa pag-apod-apod niini.

CLMonitor - usa ka monitoring server nga nagmonitor sa mga paglansad sa compiler. Kinahanglang ipadagan dayon kini sa dili pa magsugod sa pagtukod sa imong proyekto. Sa snooping mode, ang server makapugong sa mga dagan sa tanan nga gisuportahan nga mga compiler. Angay nga hinumdoman nga kini nga utility magamit lamang sa pag-analisar sa mga proyekto sa C / C ++.

PlogConverter – usa ka gamit sa pag-convert sa mga report sa analisador ngadto sa lain-laing mga format.

Impormasyon bahin sa proyekto nga gitun-an

Atong sulayan kini nga gamit sa usa ka praktikal nga pananglitan - atong analisahon ang proyekto sa OpenRCT2.

OpenRCT2 - usa ka bukas nga pagpatuman sa dula nga RollerCoaster Tycoon 2 (RCT2), pagpalapad niini sa mga bag-ong function ug pag-ayo sa mga bug. Ang dula nagtuyok sa pagtukod ug pagmentinar sa usa ka amusement park nga adunay mga rides, tindahan, ug pasilidad. Ang magdudula kinahanglang maningkamot nga makaganansya ug mamentinar ang maayong reputasyon sa parke samtang malipayon ang mga bisita. Gitugotan ka sa OpenRCT2 nga magdula sa parehas nga senaryo ug sandbox. Ang mga senaryo nagkinahanglan sa magdudula sa pagkompleto sa usa ka piho nga buluhaton sulod sa gitakda nga panahon, samtang ang Sandbox nagtugot sa magdudula sa pagtukod og usa ka mas flexible nga parke nga walay bisan unsang mga pagdili o panalapi.

kausaban

Aron makadaginot sa oras, lagmit laktawan nako ang proseso sa pag-install ug magsugod gikan sa higayon nga ako adunay server sa TeamCity nga nagdagan sa akong kompyuter. Kinahanglan nga moadto kami sa: localhost: {port nga gitakda sa panahon sa proseso sa pag-install} (sa akong kaso, localhost: 9090) ug pagsulod sa datos sa pagtugot. Human sa pagsulod kita gitimbaya ni:

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Pag-klik sa button sa Paghimo Project. Sunod, pilia ang Manwal ug pun-a ang mga uma.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Human sa pagpindot sa buton Paghimo, giabiabi kami sa usa ka bintana nga adunay mga setting.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Atong i-klik Paghimo pagtukod configuration.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Pun-a ang mga uma ug i-klik Paghimo. Nakita namon ang usa ka bintana nga naghangyo kanimo sa pagpili sa usa ka sistema sa pagkontrol sa bersyon. Tungod kay ang mga tinubdan nahimutang na sa lokal, i-klik Laktaw.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Sa katapusan, nagpadayon kami sa mga setting sa proyekto.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Atong idugang ang mga lakang sa asembliya, aron mahimo kini nga pag-klik: Pagtukod mga lakang -> Pagdugang lakang sa pagtukod.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Dinhi atong pilion:

  • Runner type -> Command Line
  • Pagdagan -> Custom nga Script

Tungod kay maghimo kami ug pagtuki sa panahon sa paghugpong sa proyekto, ang asembliya ug pagtuki kinahanglan usa ka lakang, busa pun-a ang uma Custom Script:

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Atong tan-awon ang tagsa-tagsa nga mga lakang sa ulahi. Importante nga ang pagkarga sa analisador, pag-assemble sa proyekto, pag-analisar niini, pag-output sa report ug pag-format niini nagkinahanglan lamang ug onse ka linya sa code.

Ang katapusan nga butang nga kinahanglan natong buhaton mao ang pagbutang sa mga variable sa palibot, nga akong gilatid ang pipila ka mga paagi aron mapauswag ang ilang pagkabasa. Aron mahimo kini, magpadayon kita: Mga Parameter -> Pagdugang bag-ong parameter ug idugang ang tulo ka mga variable:

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Ang kinahanglan nimong buhaton mao ang pagpindot sa buton run sa ibabaw nga tuo nga suok. Samtang ang proyekto gitigum ug gisusi, isulti ko kanimo ang bahin sa script.

Direkta nga script

Una, kinahanglan natong i-download ang pinakabag-o nga pag-apod-apod sa PVS-Studio. Alang niini among gigamit ang Chocolatey package manager. Para sa mga gusto makahibalo ug dugang bahin niini, adunay katugbang nga artikulo:

choco install pvs-studio -y

Sunod, atong ilunsad ang CLMonitor project build tracking utility.

%CLmon% monitor –-attach

Dayon atong tukoron ang proyekto isip usa ka variable sa palibot MSB mao ang dalan sa bersyon sa MSBuild nga kinahanglan nakong tukuron

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

Atong isulod ang login ug license key para sa PVS-Studio:

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

Human makompleto ang pagtukod, padagana pag-usab ang CLMonitor aron makamugna og preprocessed files ug static analysis:

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

Unya mugamit mi ug laing utility gikan sa among distribution. Ang PlogConverter nag-convert sa usa ka report gikan sa usa ka standard nga format ngadto sa usa ka TeamCity-specific nga format. Salamat niini, mahimo namong tan-awon kini direkta sa bintana sa pagtukod.

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

Ang katapusang lakang mao ang pagpakita sa giporma nga report sa stdout, diin kini kuhaon sa TeamCity parser.

type "C:tempptest.plog_TeamCity.txt"

Bug-os nga script code:

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"

Sa kasamtangan, ang asembliya ug pag-analisar sa proyekto malampuson nga nahuman, makaadto kami sa tab mga proyekto ug siguroha kini.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Karon atong i-klik sa Total nga Inspeksyonaron moadto sa pagtan-aw sa report sa analisador:

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Ang mga pasidaan gi-grupo sa mga numero sa lagda sa diagnostic. Aron maka-navigate sa code, kinahanglan nimo nga i-klik ang numero sa linya nga adunay pasidaan. Ang pag-klik sa marka sa pangutana sa taas nga tuo nga suok magbukas kanimo usa ka bag-ong tab nga adunay dokumentasyon. Mahimo ka usab nga mag-navigate sa code pinaagi sa pag-klik sa numero sa linya nga adunay pasidaan sa analisador. Ang pag-navigate gikan sa usa ka hilit nga kompyuter posible kung gamiton SourceTreeRoot marker. Bisan kinsa nga interesado sa kini nga paagi sa operasyon sa analisador mahimong pamilyar sa katugbang nga seksyon dokumentasyon.

Pagtan-aw sa mga resulta sa analisador

Karon nga nahuman na kita sa pag-deploy ug pag-configure sa pagtukod, atong tan-awon ang pipila ka makapaikag nga mga pasidaan nga makita sa proyekto nga atong gitan-aw.

Pasidaan N1

V773 [CWE-401] Ang eksepsiyon gilabay nga wala ipagawas ang 'result' pointer. Posible ang pagtulo sa memorya. 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;
}

Namatikdan sa analisador ang usa ka sayup nga pagkahuman sa dinamikong paggahin sa memorya sa CreateObject, kung adunay mahitabo nga eksepsiyon, ang memorya dili ma-clear, ug ang usa ka memory leak mahitabo.

Pasidaan N2

V501 Adunay managsama nga mga sub-ekspresyon '(1ULL << WIDX_MONTH_BOX)' sa wala ug sa tuo sa '|' 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),
  ....
};

Pipila ka mga tawo gawas sa usa ka static analyzer ang makapasar sa kini nga pagsulay sa pagkaatentibo. Kini nga pananglitan sa pagkopya-paste maayo alang niini nga hinungdan.

Mga Pasidaan N3

V703 Talagsaon nga ang field nga 'flag' sa nakuha nga klase nga 'RCT12BannerElement' nag-overwrite sa field sa base nga klase nga 'RCT12TileElementBase'. Susiha ang mga linya: RCT12.h:570, RCT12.h:259. libopenrct2 RCT12.h 570

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

Siyempre, ang paggamit sa usa ka variable nga adunay parehas nga ngalan sa base nga klase ug sa kaliwat dili kanunay usa ka sayup. Bisan pa, ang teknolohiya sa kabilin mismo nagtuo nga ang tanan nga mga natad sa klase sa ginikanan naa sa klase sa bata. Pinaagi sa pagpahayag sa mga uma nga adunay parehas nga ngalan sa manununod, gipaila namon ang kalibog.

Pasidaan N4

V793 Talagsaon nga ang resulta sa 'imageDirection / 8' nga pahayag usa ka bahin sa kondisyon. Tingali, kini nga pahayag kinahanglan nga itandi sa lain nga butang. libopenrct2 ObservationTower.cpp 38

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

Atong tan-awon pag-ayo. Pagpahayag hulagwayDireksiyon/8 mahimong bakak kon Direksyon sa imahe anaa sa han-ay gikan sa -7 ngadto sa 7. Ikaduhang bahin: (Direksiyon sa hulagway / 8) != 3 mga tseke Direksyon sa imahe kay naa sa gawas sa range: gikan sa -31 hangtod -24 ug gikan sa 24 hangtod 31, matag usa. Morag katingad-an alang kanako ang pagsusi sa mga numero alang sa paglakip sa usa ka piho nga sakup sa kini nga paagi ug, bisan kung wala’y sayup sa kini nga piraso sa code, irekomenda ko nga isulat pag-usab kini nga mga kondisyon aron mahimong labi ka klaro. Kini makahimo sa kinabuhi nga mas sayon ​​alang sa mga tawo nga mobasa ug magpadayon niini nga code.

Pasidaan N5

V587 Usa ka katingad-an nga han-ay sa mga buluhaton sa kini nga matang: A = B; B = A;. Susiha ang mga linya: 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;
      ....
  }
  ....
}

Kini nga tipik sa code lagmit nakuha pinaagi sa pag-decompilation. Unya, sa paghukom sa komento nga nahabilin, ang bahin sa non-working code gikuha. Bisan pa, adunay nahabilin nga duha nga mga operasyon cursorId, nga dili usab kaayo masabtan.

Pasidaan N6

V1004 [CWE-476] Ang 'player' pointer gigamit nga dili luwas human kini mapamatud-an batok sa nullptr. Susiha ang mga linya: 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);                    // <=
  }
  ....
}

Kini nga code sayon ​​​​ra nga matul-id; kinahanglan nimo nga susihon kini sa ikatulo nga higayon player sa usa ka null pointer, o idugang kini sa lawas sa conditional statement. Isugyot nako ang ikaduha nga kapilian:

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);
    }
  }
  ....
}

Pasidaan N7

V547 [CWE-570] Ang ekspresyong 'ngalan == nullptr' kanunay bakak. 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));
    ....
  }
  ....
}

Mahimo nimong tangtangon ang usa ka lisud basahon nga linya sa code sa usa ka pagdagan ug sulbaron ang problema sa pagsusi sa nullptr. Gisugyot ko nga usbon ang code sama sa mosunod:

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);
    ....
  }
  ....
}

Pasidaan N8

V1048 [CWE-1164] Ang variable nga 'ColumnHeaderPressedCurrentState' gi-assign sa parehas nga kantidad. libopenrct2ui CustomListView.cpp 510

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

Ang kodigo morag katingad-an. Para nako adunay typo sa kondisyon o kung gi-assign pag-usab ang variable ColumnHeaderPressedCurrentState mga mithi bakak nga mga.

konklusyon

Sama sa among nakita, ang pag-integrate sa PVS-Studio static analyzer sa imong proyekto sa TeamCity yano ra. Aron mahimo kini, igo na ang pagsulat sa usa ka gamay nga file sa pag-configure. Ang pagsusi sa code magtugot kanimo sa pag-ila sa mga problema diha-diha dayon pagkahuman sa asembliya, nga makatabang sa pagwagtang niini kung ang pagkakomplikado ug gasto sa mga pagbag-o gamay pa.

PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto Open RollerCoaster Tycoon 2
Kung gusto nimong ipaambit kini nga artikulo sa usa ka tigpaminaw nga nagsultig English, palihug gamita ang link sa paghubad: Vladislav Stolyarov. PVS-Studio ug Padayon nga Paghiusa: TeamCity. Pagtuki sa proyekto sa Open RollerCoaster Tycoon 2.

Source: www.habr.com

Idugang sa usa ka comment