PVS-Studio ã¢ãã©ã€ã¶ãŒã䜿çšããããã®ææ°ã®ã·ããªãªã® XNUMX ã€ã¯ãCI ã·ã¹ãã ãšã®çµ±åã§ãã ãŸããã»ãšãã©ãã¹ãŠã®ç¶ç¶ççµ±åã·ã¹ãã ããã® PVS-Studio ãããžã§ã¯ãã®åæã¯ããããæ°åã®ã³ãã³ãã«çµã¿èŸŒãããšãã§ããŸãããç§ãã¡ã¯ãã®ããã»ã¹ãããã«äŸ¿å©ã«ããããã«ç¶ç¶çã«åãçµãã§ããŸãã PVS-Studio ã¯ãã¢ãã©ã€ã¶ãŒåºåã TeamCity (TeamCity Inspections Type) ã®åœ¢åŒã«å€æããæ©èœããµããŒãããããã«ãªããŸããã ã©ã®ããã«æ©èœããããèŠãŠã¿ãŸãããã
䜿çšãããŠãããœãããŠã§ã¢ã«é¢ããæ å ±
ç 究äžã®ãããžã§ã¯ãã«é¢ããæ å ±
å®éã®äŸã§ãã®æ©èœãè©ŠããŠã¿ãŸããããOpenRCT2 ãããžã§ã¯ããåæããŠã¿ãŸãããã
調æŽ
æéãç¯çŽããããã«ãããããã€ã³ã¹ããŒã«ããã»ã¹ãã¹ãããããã³ã³ãã¥ãŒã¿ãŒäžã§ TeamCity ãµãŒããŒãå®è¡ããŠããæç¹ããéå§ããã§ãããã localhost:{ã€ã³ã¹ããŒã«ããã»ã¹äžã«æå®ãããããŒã} (ç§ã®å Žåãlocalhost:9090) ã«ç§»åããèªèšŒããŒã¿ãå ¥åããå¿ èŠããããŸãã å ¥ããšæ¬¡ã®ãããªæè¿ãåããŸãã
ããããžã§ã¯ãã®äœæããã¿ã³ãã¯ãªãã¯ããŸãã 次ã«ããæåããéžæããŠãã£ãŒã«ãã«å
¥åããŸãã
ãã¿ã³ãæŒããåŸ åµé ãã, èšå®ãå«ããŠã£ã³ããŠã衚瀺ãããŸãã
ã¯ãªãã¯ããŸããã ãã«ãæ§æã®äœæ.
ãã£ãŒã«ãã«å
¥åããŠã¯ãªãã¯ããŸã åµé ããã ããŒãžã§ã³ç®¡çã·ã¹ãã ã®éžæãæ±ãããŠã£ã³ããŠã衚瀺ãããŸãã ãœãŒã¹ã¯ãã§ã«ããŒã«ã«ã«é
眮ãããŠããããã ã¹ããã.
æåŸã«ããããžã§ã¯ãã®èšå®ã«é²ã¿ãŸãã
çµã¿ç«ãŠæé ãè¿œå ããŸãããããããè¡ãã«ã¯ã次ãã¯ãªãã¯ããŸãã ãã«ãã¹ããã -> ãã«ãã¹ãããã®è¿œå .
ããã§ã¯æ¬¡ã®ããšãéžæããŸãã
- ã©ã³ããŒã¿ã€ã -> ã³ãã³ãã©ã€ã³
- å®è¡ -> ã«ã¹ã¿ã ã¹ã¯ãªãã
ãããžã§ã¯ãã®ã³ã³ãã€ã«äžã«åæãå®è¡ãããããçµã¿ç«ãŠãšåæ㯠XNUMX ã€ã®ã¹ãããã§ããå¿ èŠãããããããã£ãŒã«ãã«èšå ¥ããŸãã ã«ã¹ã¿ã ã¹ã¯ãªãã:
åã
ã®ã¹ãããã«ã€ããŠã¯åŸã§èŠãŠãããŸãã ã¢ãã©ã€ã¶ãŒã®ããŒãããããžã§ã¯ãã®çµã¿ç«ãŠãåæãã¬ããŒãã®åºåãããã³ãã©ãŒãããèšå®ã«å¿
èŠãªã³ãŒãã¯ããã XNUMX è¡ã§ããããšãéèŠã§ãã
æåŸã«è¡ãå¿ èŠãããã®ã¯ãç°å¢å€æ°ãèšå®ããããšã§ããããã«ã€ããŠã¯ãèªã¿ããããåäžãããããã€ãã®æ¹æ³ãæŠèª¬ããŸããã ãããè¡ãã«ã¯ã次ã«é²ã¿ãŸãããã ãã©ã¡ãŒã¿ -> æ°ãããã©ã¡ãŒã¿ãè¿œå ãã㊠XNUMX ã€ã®å€æ°ãè¿œå ããŸãã
ãã¿ã³ãæŒãã ãã§ã ã©ã³ å³äžé
ã«ãããŸãã ãããžã§ã¯ããçµã¿ç«ãŠãããåæãããŠããéã«ãã¹ã¯ãªããã«ã€ããŠèª¬æããŸãã
çŽæ¥ã¹ã¯ãªãããäœæãã
ãŸããææ°ã® PVS-Studio ãã£ã¹ããªãã¥ãŒã·ã§ã³ãããŠã³ããŒãããå¿
èŠããããŸãã ãã®ããã«ãChocolatey ããã±ãŒãž ãããŒãžã£ãŒã䜿çšããŸãã ããã«ã€ããŠããã«è©³ããç¥ããã人ã®ããã«ã察å¿ãããã®ããããŸã
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"
æåŸã®ã¹ãããã§ã¯ããã©ãŒããããããã¬ããŒãã衚瀺ããŸãã (Linuxã§èšããšããã®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"
ãããŸã§ã®éããããžã§ã¯ãã®çµã¿ç«ãŠãšåæã¯æ£åžžã«å®äºããã¿ãã«ç§»åã§ããŸãã ãããžã§ã¯ã ãããŠããã確ãããŠãã ããã
ãããã¯ãªãã¯ããŠã¿ãŸããã æ€æ»åèšã¢ãã©ã€ã¶ãŒ ã¬ããŒãã®è¡šç€ºã«ç§»åããã«ã¯ã次ã®ããã«ããŸãã
èŠåã¯èšºæã«ãŒã«çªå·ããšã«ã°ã«ãŒãåãããŠããŸãã ã³ãŒãå
ã移åããã«ã¯ãèŠåã®ããè¡çªå·ãã¯ãªãã¯ããå¿
èŠããããŸãã å³äžé
ã«ããçå笊ãã¯ãªãã¯ãããšãããã¥ã¡ã³ããå«ãæ°ããã¿ããéããŸãã ã¢ãã©ã€ã¶ãŒã®èŠåã®ããè¡çªå·ãã¯ãªãã¯ããŠãã³ãŒãå
ã移åããããšãã§ããŸãã ã䜿çšãããšããªã¢ãŒã ã³ã³ãã¥ãŒã¿ããã®ããã²ãŒã·ã§ã³ãå¯èœã«ãªããŸã ãœãŒã¹ããªãŒã«ãŒã ããŒã«ãŒã ã¢ãã©ã€ã¶ãŒã®ãã®åäœã¢ãŒãã«èå³ããã人ã¯ã察å¿ããã»ã¯ã·ã§ã³ãããç解ããŠãã ããã
ã¢ãã©ã€ã¶ãŒã®çµæã®è¡šç€º
ãã«ãã®ãããã€ãšæ§æãå®äºããã®ã§ã泚ç®ããŠãããããžã§ã¯ãã§èŠã€ãã£ãããã€ãã®èå³æ·±ãèŠåãèŠãŠã¿ãŸãããã
èŠåN1
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
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
struct RCT12SpriteBase
{
....
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};
ãã¡ãããåºæ¬ã¯ã©ã¹ãšåå«ã§åãååã®å€æ°ã䜿çšããããšãåžžã«ãšã©ãŒã«ãªãããã§ã¯ãããŸããã ãã ããç¶æ¿ãã¯ãããžèªäœã¯ã芪ã¯ã©ã¹ã®ãã¹ãŠã®ãã£ãŒã«ããåã¯ã©ã¹ã«ååšããããšãåæãšããŠããŸãã ç¶æ¿å ã§åãååã®ãã£ãŒã«ãã宣èšãããšãæ··ä¹±ãçããŸãã
èŠåN4
void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
if ((imageDirection / 8) && (imageDirection / 8) != 3)
{
....
}
....
}
詳ããèŠãŠã¿ãŸãããã è¡šçŸ ç»åæ¹å/8 ã®å Žå㯠false ã«ãªããŸã ç»åæ¹å ç¯å²ã¯ -7 ïœ 7 ã§ãã XNUMX çªç®ã®éšå: (imageDirection / 8) != 3 å°åæ ç»åæ¹å ç¯å²å€ã®å Žå: ãããã -31 ïœ -24 ãš 24 ïœ 31ã ãã®æ¹æ³ã§ç¹å®ã®ç¯å²ã«å«ãŸããæ°å€ããã§ãã¯ããã®ã¯éåžžã«å¥åŠã«æããŸããããšããã®ã³ãŒãã«ãšã©ãŒããªããšããŠãããããã®æ¡ä»¶ãããæ瀺çã«æžãçŽãããšããå§ãããŸãã ããã«ããããã®ã³ãŒããèªãã§ä¿å®ãã人ã«ãšã£ãŠäœæ¥ãã¯ããã«ç°¡åã«ãªããŸãã
èŠåN5
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;
....
}
....
}
ãã®ã³ãŒãæçã¯ãããããéã³ã³ãã€ã«ã«ãã£ãŠååŸããããã®ã§ãã ãã®åŸãæ®ãããã³ã¡ã³ãããå€æãããšãæ©èœããªãã³ãŒãã®äžéšãåé€ãããŸããã ãã ãããŸã ããã€ãã®æè¡ãæ®ã£ãŠããŸã ã«ãŒãœã«IDããããããŸãæå³ããããŸããã
èŠåN6
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); // <=
}
....
}
ãã®ã³ãŒãã¯ä¿®æ£ãéåžžã«ç°¡åã§ãXNUMX å確èªããã ãã§æžã¿ãŸãã ãã¬ã€ã€ãŒ null ãã€ã³ã¿ãŒã«è¿œå ããããæ¡ä»¶æã®æ¬äœã«è¿œå ããŸãã ç§ã¯ XNUMX çªç®ã®ãªãã·ã§ã³ããå§ãããŸãã
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
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
void CustomListView::MouseUp(....)
{
....
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
ColumnHeaderPressedCurrentState = false;
Invalidate();
}
}
ã³ãŒãã¯ããªãå¥åŠã«èŠããŸãã æ¡ä»¶ãŸãã¯å€æ°ã®åä»£å ¥æã«ã¿ã€ããã¹ããã£ãããã«æããŸã ColumnHeaderPressedCurrentState æå³ false.
åºå
ã芧ã®ãšãããPVS-Studio éçã¢ãã©ã€ã¶ãŒã TeamCity ãããžã§ã¯ãã«çµ±åããã®ã¯éåžžã«ç°¡åã§ãã ãããè¡ãã«ã¯ãå°ããªæ§æãã¡ã€ã«ã XNUMX ã€äœæããã ãã§ååã§ãã ã³ãŒãããã§ãã¯ãããšãã¢ã»ã³ããªçŽåŸã«åé¡ãç¹å®ã§ãããããå€æŽã®è€éããšã³ã¹ãããŸã äœããã¡ã«åé¡ã解決ã§ããŸãã
ãã®èšäºãè±èªåã®èªè
ãšå
±æãããå Žåã¯ã翻蚳ãªã³ã¯ã䜿çšããŠãã ãã: Vladislav Stolyarovã
åºæïŒ habr.com