ืืื ืืชืจืืืฉืื ืืขืืื ืืื ืืืืชืจ ืืฉืืืืฉ ืื ืชื PVS-Studio ืืื ืืฉืืืื ืฉืื ืขื ืืขืจืืืช CI. ืืืืจืืช ืฉื ืืชื ืืื ืืช ืืช ืื ืืชืื ืฉื ืคืจืืืงื PVS-Studio ืืืขื ืืื ืืขืจืืช ืืื ืืืจืฆืื ืจืฆืืคื ืืืื ืคืงืืืืช ืืืื, ืื ื ืืืฉืืืื ืืืคืื ืืช ืืชืืืื ืืื ืื ืื ืขืื ืืืชืจ. ื-PVS-Studio ืืฉ ืืขืช ืชืืืื ืืืืจืช ืคืื ืื ืชื ืืคืืจืื ืขืืืจ TeamCity - TeamCity Inspections Type. ืืื ื ืจืื ืืื ืื ืขืืื.
ืืืืข ืขื ืืชืืื ื ืฉืื ื ืขืฉื ืฉืืืืฉ
ืืืืข ืขื ืืคืจืืืงื ืื ืืืง
ืืืื ื ื ืกื ืืช ืืคืื ืงืฆืืื ืืืืช ืืื ืขื ืืืืื ืืขืฉืืช - ืืืื ื ื ืชื ืืช ืคืจืืืงื OpenRCT2.
ืืชืืื
ืืื ืืืกืื ืืื, ืื ื ืื ืจืื ืืืืชืจ ืขื ืชืืืื ืืืชืงื ื ืืืชืืื ืืืจืืข ืฉืื ืฉืจืช TeamCity ืคืืขื ืืืืฉื ืฉืื. ืขืืื ื ืืขืืืจ ืื: localhost:{port ืฉืฆืืื ืืืืื ืชืืืื ืืืชืงื ื} (ืืืงืจื ืฉืื, localhost:9090) ืืืืืื ื ืชืื ื ืืจืฉืื. ืืืืจ ืืื ืืกื ืืงืืื ืืช ืคื ืื ื:
ืืืฅ ืขื ืืคืชืืจ ืฆืืจ ืคืจืืืืงื. ืืืืจ ืืื, ืืืจ ืืืืคื ืืื ื ืืืื ืืช ืืฉืืืช.
ืืืืจ ืืืืฆื ืขื ืืืคืชืืจ ืฆืืจ, ืืช ืคื ืื ื ืืงืื ืืืื ืขื ืืืืจืืช.
ืืื ื ืงืืืง ืฆืืจ ืชืฆืืจืช ืื ืืื.
ืืื ืืช ืืฉืืืช ืืืืฅ ืฆืืจ. ืื ื ืจืืืื ืืืื ืืืืงืฉ ืืื ืืืืืจ ืืขืจืืช ืืงืจืช ืืจืกืืืช. ืืืืืื ืฉืืืงืืจืืช ืืืจ ืืืืงืืื ืืงืืืืช, ืืืฅ ืืืื.
ืืืกืืฃ, ื ืขืืืจ ืืืืืจืืช ืืคืจืืืงื.
ืืืื ื ืืกืืฃ ืฉืืื ืืจืืื, ืืื ืืขืฉืืช ืืืช ืืืฅ: ืฉืืื ืื ืืื -> ืืืกืฃ ืฉืื ืื ืืื.
ืืื ืื ื ืืืืจืื:
- ืกืื ืจืฅ -> ืฉืืจืช ืคืงืืื
- ืืคืขืื -> ืกืงืจืืคื ืืืชืื ืืืฉืืช
ืืืืืื ืฉืื ื ื ืืฆืข ื ืืชืื ืืืืื ืืืืืจ ืืคืจืืืงื, ืืืจืืื ืืื ืืชืื ืฆืจืืืื ืืืืืช ืฉืื ืืื, ืื ืืืื ืืช ืืฉืื ืกืงืจืืคื ืืืชืื ืืืฉืืช:
ื ืืื ืฆืขืืื ืืืืืื ืืืืฉื. ืืฉืื ืฉืืขืื ืช ืื ืชื, ืืจืืืช ืืคืจืืืงื, ื ืืชืืื, ืืคืื ืฉื ืืืื ืืขืืฆืืื ืืืงื ืจืง ืืืช ืขืฉืจื ืฉืืจืืช ืงืื.
ืืืืจ ืืืืจืื ืฉืขืืื ื ืืขืฉืืช ืืื ืืืืืืจ ืืช ืืฉืชื ื ืืกืืืื, ืฉืชืืืจืชื ืืื ืืจืืื ืืฉืืคืืจ ืืงืจืืืืช ืฉืืื. ืืื ืืขืฉืืช ืืืช, ืืืื ื ืืฉืื: ืคืจืืืจืื -> ืืืกืฃ ืคืจืืืจ ืืืฉ ืืืืืกืืฃ ืฉืืืฉื ืืฉืชื ืื:
ืื ืฉืขืืืื ืืขืฉืืช ืืื ืืืืืฅ ืขื ืืืคืชืืจ ืืคืขืื ืืคืื ื ืืืื ืืช ืืขืืืื ื. ืืืื ืืืจืืื ืืื ืืชืื ืฉื ืืคืจืืืงื, ืืกืคืจ ืืื ืขื ืืชืกืจืื.
ืชืกืจืื ืืฉืืจ
ืจืืฉืืช, ืขืืื ื ืืืืจืื ืืช ืืืคืฆื ืืขืืื ืืช ืืืืชืจ ืฉื PVS-Studio. ืืฉื ืื ืื ื ืืฉืชืืฉืื ืืื ืื ืืืืืืช ืืฉืืงืืื. ืืื ืฉืจืืฆื ืืืขืช ืืืชืจ ืขื ืื, ืืฉ ืืืืขื ืืงืืืื
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"
ืืื ืชืืื ืืืจืืื ืืื ืืชืื ืฉื ืืคืจืืืงื ืืกืชืืืื ืืืฆืืื, ื ืืื ืืขืืืจ ืืืฉืื ืืช ืคืจืืืงืืื ืืืืืื ืืช ืื.
ืขืืฉืื ืืืื ื ืืืฅ ืขื ืืืืงืืช ืกื ืืืืืื ืืขืืืจ ืืฆืคืืื ืืืื ืื ืชื:
ืืืืจืืช ืืงืืืฆืืช ืืคื ืืกืคืจื ืืื ืืืืื. ืืื ืื ืืื ืืงืื, ืขืืื ืืืืืฅ ืขื ืืกืคืจ ืืฉืืจื ืขื ืืืืืจื. ืืืืฆื ืขื ืกืืื ืืฉืืื ืืคืื ื ืืืื ืืช ืืขืืืื ื ืชืคืชื ืื ืืฉืื ืืช ืืืฉื ืขื ืชืืขืื. ืืชื ืืืื ืื ืื ืืื ืืงืื ืขื ืืื ืืืืฆื ืขื ืืกืคืจ ืืฉืืจื ืขื ืืืืจืช ืื ืชื. ื ืืืื ืืืืฉื ืืจืืืง ืืคืฉืจื ืืขืช ืืฉืืืืฉ SourceTreeRoot ืกึทืึธื. ืื ืื ืฉืืขืื ืืื ืืืฆื ืคืขืืื ืื ืฉื ืื ืชื ืืืื ืืืืืจ ืืช ืืกืขืืฃ ืืืงืืื
ืฆืคืืื ืืชืืฆืืืช ืื ืชื
ืืขืช, ืืืืจ ืฉืกืืืื ื ืืคืจืืก ืืืืืืืจ ืืช ื-build, ืืืื ื ืกืชืื ืขื ืืื ืืืืจืืช ืืขื ืืื ืืช ืฉื ืืฆืื ืืคืจืืืงื ืฉืื ื ืืืื ืื.
ืืืืจื 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)
{
....
}
....
}
ืืืื ื ืกืชืื ืืงืจืื. ืืืืื imageDirection/8 ืืืื ืฉืงืจ ืื imageDirection ืืื ืืืืื ืฉืืื -7 ื-7. ืืืง ืฉื ื: (imageDirection / 8) != 3 ืฆ'ืงืื imageDirection ืืืืืช ืืืืฅ ืืืืื: ื-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;
....
}
....
}
ืงืืข ืงืื ืื ืืืฉื ืืื ืื ืจืื ืขื ืืื ืื-ืงืืืคืืืฆืื. ืืืืจ ืืื, ืื ืืฉืคืื ืืคื ืืืขืจื ืฉื ืฉืืจื, ืืืง ืืืงืื ืฉืืื ื ืขืืื ืืืกืจ. ืขื ืืืช, ื ืืชืจื ืขืื ืืื ื ืืชืืืื cursorId, ืฉืื ืื ืื ืืืืื ื ืืืืืื.
ืืืืจื 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); // <=
}
....
}
ืื ืงื ืืชืงื ืืช ืืงืื ืืื; ืืชื ืจืง ืฆืจืื ืืืืืง ืืืชื ืคืขื ืฉืืืฉืืช ืฉืืงื ืืืฆืืืข ืจืืง, ืื ืืืกืฃ ืืืชื ืืืืฃ ืืืฆืืจื ืืืืชื ืืช. ืืืืชื ืืฆืืข ืืช ืืืคืฉืจืืช ืืฉื ืืื:
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 ืขืจืืื ืฉืงืจ.
ืคืื
ืืคื ืฉืื ื ืืืืืื ืืจืืืช, ืฉืืืื ืืื ืชื ืืกืืื PVS-Studio ืืคืจืืืงื TeamCity ืฉืื ืืื ืื ืคืฉืื. ืืื ืืขืฉืืช ืืืช, ืื ืืกืคืืง ืืื ืืืชืื ืจืง ืงืืืฅ ืชืฆืืจื ืงืื ืืื. ืืืืงืช ืืงืื ืชืืคืฉืจ ืื ืืืืืช ืืขืืืช ืืื ืืืืจ ืืืจืืื, ืื ืฉืืขืืืจ ืืืขืืื ืืืชื ืืืฉืจ ืืืืจืืืืช ืืืขืืืช ืฉื ืืฉืื ืืืื ืขืืืื ื ืืืืื.
ืื ืืจืฆืื ื ืืฉืชืฃ ืืืืจ ืื ืขื ืงืื ืืืืจ ืื ืืืืช, ืื ื ืืฉืชืืฉ ืืงืืฉืืจ ืืชืจืืื: ืืืืืกืื ืกืืืืืืจืื.
ืืงืืจ: www.habr.com