PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Wieħed mill-aktar xenarji attwali għall-użu tal-analizzatur PVS-Studio huwa l-integrazzjoni tiegħu mas-sistemi CI. U għalkemm l-analiżi ta 'proġett PVS-Studio minn kważi kull sistema ta' integrazzjoni kontinwa tista 'tinbena fi ftit kmandi biss, aħna nkomplu nagħmlu dan il-proċess saħansitra aktar konvenjenti. PVS-Studio issa għandu appoġġ għall-konverżjoni tal-output tal-analizzatur f'format għal TeamCity - TeamCity Spezzjonijiet Tip. Ejja naraw kif taħdem.

Informazzjoni dwar is-softwer użat

PVS-Istudjo — analizzatur statiku għall-kodiċi C, C++, C#, u Java, iddisinjat biex jiffaċilita l-kompitu li jinstabu u jiġu rranġati diversi tipi ta' żbalji. L-analizzatur jista' jintuża f' Windows, Linux и macOSF'dan l-artikolu, se nużaw b'mod attiv mhux biss l-analizzatur innifsu, iżda wkoll xi utilitajiet mid-distribuzzjoni tiegħu.

CLMonitor — huwa server ta' monitoraġġ li jimmonitorja t-tnedija tal-kompilaturi. Għandu jitmexxa immedjatament qabel ma tibda tibni l-proġett tiegħek. Fil-modalità snooping, is-server se jinterċetta ġirjiet tal-kompilaturi kollha appoġġjati. Ta 'min jinnota li din l-utilità tista' tintuża biss biex tanalizza proġetti C/C++.

PlogConverter – utilità għall-konverżjoni tar-rapporti tal-analizzaturi f'formati differenti.

Informazzjoni dwar il-proġett taħt studju

Ejja nippruvaw din il-funzjonalità fuq eżempju prattiku - ejja nanalizzaw il-proġett OpenRCT2.

OpenRCT2 - implimentazzjoni miftuħa tal-logħba RollerCoaster Tycoon 2 (RCT2), tespandiha b'funzjonijiet ġodda u tiffissa bugs. Il-logħba ddur madwar il-bini u ż-żamma ta' park tad-divertiment li jkun fih karozzini, ħwienet u faċilitajiet. Il-plejer irid jipprova jagħmel profitt u jżomm ir-reputazzjoni tajba tal-park filwaqt li jżomm lill-mistednin kuntenti. OpenRCT2 jippermettilek tilgħab kemm fix-xenarju kif ukoll f'sandbox. Xenarji jirrikjedu li l-plejer iwettaq kompitu speċifiku fi żmien stabbilit, filwaqt li Sandbox jippermetti lill-plejer jibni park aktar flessibbli mingħajr ebda restrizzjoni jew finanzi.

aġġustament

Sabiex niffranka l-ħin, probabbilment se naqbeż il-proċess ta 'installazzjoni u nibda mill-mument meta jkolli s-server TeamCity jaħdem fuq il-kompjuter tiegħi. Irridu mmorru għal: localhost:{port speċifikat matul il-proċess ta' installazzjoni} (fil-każ tiegħi, localhost:9090) u daħħal id-dejta tal-awtorizzazzjoni. Wara li nidħlu niġu milqugħa minn:

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Ikklikkja fuq il-buttuna Oħloq Proġett. Sussegwentement, agħżel Manwalment u imla l-oqsma.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Wara li tagħfas il-buttuna Oħloq, aħna milqugħa minn tieqa b'settings.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Ejja ikklikkja Oħloq konfigurazzjoni tal-bini.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Imla l-oqsma u kklikkja Oħloq. Naraw tieqa titlobek tagħżel sistema ta 'kontroll tal-verżjoni. Peress li s-sorsi diġà jinsabu lokalment, ikklikkja Aqbeż.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Fl-aħħarnett, nimxu fuq is-settings tal-proġett.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Ejja nżidu l-passi tal-assemblaġġ, biex nagħmlu dan ikklikkja: Ibni passi -> Żid il-pass tal-bini.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Hawnhekk nagħżlu:

  • Tip ta' runner -> Linja tal-Kmand
  • Mexxi -> Custom Script

Peress li aħna se nwettqu analiżi waqt il-kumpilazzjoni tal-proġett, l-assemblaġġ u l-analiżi għandhom ikunu pass wieħed, għalhekk imla l-qasam Skript Custom:

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Se nħarsu lejn passi individwali aktar tard. Huwa importanti li t-tagħbija tal-analizzatur, l-assemblaġġ tal-proġett, l-analiżi tiegħu, il-ħruġ tar-rapport u l-ifformattjar jieħu biss ħdax-il linja ta 'kodiċi.

L-aħħar ħaġa li rridu nagħmlu hija li nissettjaw il-varjabbli ambjentali, li stajt spjegajt xi modi kif intejbu l-leġibbiltà tagħhom. Biex tagħmel dan, ejja nkomplu: Parametri -> Żid parametru ġdid u żid tliet varjabbli:

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Kull ma trid tagħmel hu li tagħfas il-buttuna Mexxi fir-rokna ta’ fuq tal-lemin. Waqt li l-proġett qed jiġi mmuntat u analizzat, jien ngħidlek dwar l-iskript.

Direttament b'kitba

L-ewwel, għandna bżonn tniżżel l-aħħar distribuzzjoni PVS-Studio. Għal dan nużaw il-maniġer tal-pakketti Chocolatey. Għal dawk li jridu jkunu jafu aktar dwar dan, hemm korrispondenti artikolu:

choco install pvs-studio -y

Sussegwentement, ejja nniedu l-utilità ta 'traċċar tal-bini tal-proġett CLMonitor.

%CLmon% monitor –-attach

Imbagħad se nibnu l-proġett bħala varjabbli ambjentali MSB hija t-triq għall-verżjoni tal-MSBuild li għandi bżonn nibni

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

Ejja daħħal il-login u ċ-ċavetta tal-liċenzja għal PVS-Studio:

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

Wara li titlesta l-bini, erġa ħaddem CLMonitor biex tiġġenera fajls ipproċessati minn qabel u analiżi statika:

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

Imbagħad se nużaw utilità oħra mid-distribuzzjoni tagħna. PlogConverter jikkonverti rapport minn format standard għal format speċifiku għal TeamCity. Grazzi għal dan, inkunu nistgħu narawha direttament fit-tieqa tal-bini.

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

L-aħħar pass huwa li turi r-rapport ifformattjat fi stdout, fejn se jinġabar mill-parser ta' TeamCity.

type "C:tempptest.plog_TeamCity.txt"

Kodiċi tal-iskript sħiħ:

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"

Sadanittant, l-assemblaġġ u l-analiżi tal-proġett tlestiet b'suċċess, nistgħu mmorru fit-tab proġetti u kun żgur minnha.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Issa ejja ikklikkja fuq Spezzjonijiet Totalbiex tmur tara r-rapport tal-analizzatur:

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
It-twissijiet huma miġbura skond in-numri tar-regoli dijanjostiċi. Biex tinnaviga permezz tal-kodiċi, trid tikklikkja fuq in-numru tal-linja bit-twissija. Meta tikklikkja fuq il-marka tal-mistoqsija fir-rokna ta' fuq tal-lemin tiftaħlek tab ġdida bid-dokumentazzjoni. Tista 'wkoll tinnaviga permezz tal-kodiċi billi tikklikkja fuq in-numru tal-linja bit-twissija tal-analizzatur. In-navigazzjoni minn kompjuter remot hija possibbli meta tuża SourceTreeRoot markatur. Kull min huwa interessat f'dan il-mod ta 'tħaddim tal-analizzatur jista' jiffamiljarizza ruħu mat-taqsima korrispondenti dokumentazzjoni.

Ara r-riżultati tal-analizzatur

Issa li lestejna l-iskjerament u l-konfigurazzjoni tal-bini, ejja nagħtu ħarsa lejn xi twissijiet interessanti misjuba fil-proġett li qed inħarsu lejh.

Twissija N1

V773 [CWE-401] L-eċċezzjoni ġiet mitfugħa mingħajr ma ħarġet il-pointer tar-'riżultat'. Tnixxija tal-memorja hija possibbli. 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;
}

L-analizzatur innota żball li wara li alloka b'mod dinamiku l-memorja Oħloq Oġġett, meta sseħħ eċċezzjoni, il-memorja ma titnaddafx, u sseħħ tnixxija tal-memorja.

Twissija N2

V501 Hemm subespressjonijiet identiċi '(1ULL << WIDX_MONTH_BOX)' fuq ix-xellug u fuq il-lemin tal-'|' operatur. 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),
  ....
};

Ftit nies minbarra analizzatur statiku jistgħu jgħaddu minn dan it-test ta 'attenzjoni. Dan l-eżempju copy-paste huwa tajjeb preċiżament għal din ir-raġuni.

Twissijiet N3

V703 Huwa stramb li l-qasam 'bnadar' fil-klassi derivata 'RCT12BannerElement' jissostitwixxi l-qasam fil-klassi bażi 'RCT12TileElementBase'. Iċċekkja linji: RCT12.h:570, RCT12.h:259. libopenrct2 RCT12.h 570

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

Naturalment, l-użu ta 'varjabbli bl-istess isem fil-klassi bażi u fid-dixxendent mhux dejjem huwa żball. Madankollu, it-teknoloġija tal-wirt nnifisha tassumi li l-oqsma kollha tal-klassi ġenitur huma preżenti fil-klassi tifel. Billi niddikjaraw oqsma bl-istess isem fil-werriet, noħolqu konfużjoni.

Twissija N4

V793 Huwa stramb li r-riżultat tad-dikjarazzjoni 'imageDirection / 8' huwa parti mill-kundizzjoni. Forsi, din id-dikjarazzjoni kellha tiġi mqabbla ma 'xi ħaġa oħra. libopenrct2 ObservationTower.cpp 38

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

Ejja nagħtu ħarsa aktar mill-qrib. Espressjoni imageDirection/8 se jkun falz jekk imageDirection hija fil-medda minn -7 sa 7. It-tieni parti: (Direzzjoni tal-immaġni / 8) != 3 kontrolli imageDirection talli tkun barra mill-medda: minn -31 sa -24 u minn 24 sa 31, rispettivament. Jidhirli pjuttost stramba li niċċekkja n-numri għall-inklużjoni f'ċerta firxa b'dan il-mod u, anke jekk ma jkun hemm l-ebda żball f'din il-biċċa tal-kodiċi, nirrakkomanda li nikteb mill-ġdid dawn il-kundizzjonijiet biex tkun aktar espliċita. Dan jagħmel il-ħajja ħafna aktar faċli għan-nies li jaqraw u jżommu dan il-kodiċi.

Twissija N5

V587 Sekwenza fard ta' assenjazzjonijiet ta' dan it-tip: A = B; B = A;. Iċċekkja linji: 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;
      ....
  }
  ....
}

Dan il-framment tal-kodiċi x'aktarx inkiseb permezz ta' dekompilazzjoni. Imbagħad, meta wieħed jiġġudika mill-kumment li jitħalla, tneħħiet parti mill-kodiċi li ma taħdemx. Madankollu, għad fadal ftit operazzjonijiet cursorId, li wkoll ma tantx jagħmlu sens.

Twissija N6

V1004 [CWE-476] Il-pointer tal-'player' intuża b'mod mhux sikur wara li ġie vverifikat kontra nullptr. Iċċekkja linji: 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);                    // <=
  }
  ....
}

Dan il-kodiċi huwa pjuttost faċli biex tikkoreġi; attur għal pointer null, jew żidha mal-korp tad-dikjarazzjoni kondizzjonali. Nissuġġerixxi t-tieni għażla:

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

Twissija N7

V547 [CWE-570] L-espressjoni 'name == nullptr' hija dejjem falza. 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));
    ....
  }
  ....
}

Tista 'teħles minn linja ta' kodiċi diffiċli biex tinqara f'daqqa waħda u ssolvi l-problema bil-verifika għal nullptr. Nissuġġerixxi li tinbidel il-kodiċi kif ġej:

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

Twissija N8

V1048 [CWE-1164] Il-varjabbli 'ColumnHeaderPressedCurrentState' ġiet assenjata l-istess valur. libopenrct2ui CustomListView.cpp 510

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

Il-kodiċi jidher pjuttost stramba. Jidhirli li kien hemm typo jew fil-kundizzjoni jew meta rri-assenja l-varjabbli ColumnHeaderPressedCurrentState valuri falza.

Output

Kif nistgħu naraw, l-integrazzjoni tal-analizzatur statiku PVS-Studio fil-proġett TeamCity tiegħek hija pjuttost sempliċi. Biex tagħmel dan, huwa biżżejjed li tikteb fajl ta 'konfigurazzjoni żgħir wieħed biss. L-iċċekkjar tal-kodiċi jippermettilek tidentifika l-problemi immedjatament wara l-assemblaġġ, li tgħin biex teliminahom meta l-kumplessità u l-ispiża tal-bidliet ikunu għadhom baxxi.

PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2
Jekk trid taqsam dan l-artikolu ma 'udjenza li titkellem bl-Ingliż, jekk jogħġbok uża l-link tat-traduzzjoni: Vladislav Stolyarov. PVS-Studio u Integrazzjoni Kontinwa: TeamCity. Analiżi tal-proġett Open RollerCoaster Tycoon 2.

Sors: www.habr.com

Ixtri hosting affidabbli għal siti bi protezzjoni DDoS, servers VPS VDS 🔥 Ixtri hosting ta' websajts affidabbli bi protezzjoni DDoS, servers VPS VDS | ProHoster