Professional Documents
Culture Documents
PVS-Studio and Continuous Integration - TeamCity. Analysis of The Open RollerCoaster Tycoon 2 Project - PVS-Studio Corporate Blog - Habr PDF
PVS-Studio and Continuous Integration - TeamCity. Analysis of The Open RollerCoaster Tycoon 2 Project - PVS-Studio Corporate Blog - Habr PDF
All streams Development Administrating Design Management Marketing PopSci Log in Sign up
151.42
Rating
PVS-Studio
Static Code Analysis for C, C++, C# and Java
One of the most relevant scenarios for using the PVS-Studio analyzer is its integration into CI systems. Even though a project analysis by
PVS-Studio can already be embedded with just a few commands into almost any continuous integration system, we continue to make
this process even more convenient. PVS-Studio now supports converting the analyzer output to the TeamCity format-TeamCity
Inspections Type. Let's see how it works.
CLMonitor is a monitoring server that performs monitoring of compiler runs. It has to be run immediately before building a project. In
monitoring mode, the server will intercept runs of all supported compilers. It is worth noting that this utility can only be used for
analyzing C/C++ projects.
PlogConverter is a utility for converting the analyzer report into different formats.
OpenRCT2 is an open implementation of the RollerCoaster Tycoon 2 (RCT2) game, expanding it with new features and fixed bugs. The
gameplay revolves around the construction and maintenance of an amusement park that houses rides, stores, and facilities. The player
has to try to make profit and maintain the good reputation of the park, while keeping the guests happy. OpenRCT2 allows you to play
both by following the script and in the sandbox. Scenarios require a player to complete a specific task in a set time, while the sandbox
allows a player to build a more flexible park without any restrictions or finances.
Configuration
https://habr.com/en/company/pvs-studio/blog/511770/ 1/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
In order to save time, I will probably skip the installation process and start from the point when the TeamCity server is running on my
computer. We need to go to: localhost:{the port specified during installation}(in my case, localhost:9090) and enter the authorization
data. After entering we will get:
Click on Create Project. Next, select Manually and fill in the fields.
https://habr.com/en/company/pvs-studio/blog/511770/ 2/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
https://habr.com/en/company/pvs-studio/blog/511770/ 3/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
Fill in the fields and click Create. We see the window suggesting to select a version control system. Since the sources are already located
locally, click Skip.
https://habr.com/en/company/pvs-studio/blog/511770/ 4/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
https://habr.com/en/company/pvs-studio/blog/511770/ 5/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
We'll add the build steps. To do this, click: Build steps -> Add build step.
https://habr.com/en/company/pvs-studio/blog/511770/ 6/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
Here we choose:
Since we will perform analysis during the project compilation, the build and analysis must be one step, therefore we will fill in the
Custom Script field:
https://habr.com/en/company/pvs-studio/blog/511770/ 7/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
We will focus on individual steps later. It is important that loading the analyzer, building the project, analyzing it, the report output, and
formatting it should take only eleven lines of code.
The last thing we need to do is to set environment variables, which, in my case, outline some ways to improve their readability. To do
this, go to: Parameters -> Add new parameter and add three variables:
https://habr.com/en/company/pvs-studio/blog/511770/ 8/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
Just click on Run in the upper-right corner. While the project is being built and analyzed, let me will tell you about the script.
Then we will build the project. The MSB environment variable represents the path to the MSBuild version that I need to build.
https://habr.com/en/company/pvs-studio/blog/511770/ 9/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
After the build is complete, we will run CLMonitor again to generate preprocessed files and perform static analysis:
After that, we will use another utility from our distribution. PlogConverter converts a report from standard to a TeamCity-specific format.
This allows us to view it directly in the build window.
The last action is to output the formatted report to stdout, where it will be picked up by the TeamCity parser.
type "C:\temp\ptest.plog_TeamCity.txt"
In the meantime, the build and analysis of the project has been completed successfully, so we can go to the Projects tab and make sure
of it.
https://habr.com/en/company/pvs-studio/blog/511770/ 10/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
https://habr.com/en/company/pvs-studio/blog/511770/ 11/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
Warnings are grouped by diagnostic rule numbers. To navigate along the code, click on the line number with the warning. Clicking on
the question mark in the upper-right corner will open a new tab with documentation. You can also navigate along the code by clicking
on the line number with the analyzer warning. Navigation from a remote computer is possible when using the SourceTreeRoot marker.
Those who are interested in this mode of the analyzer operation are welcome to read the related documentation section.
Warning 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");
}
....
}
https://habr.com/en/company/pvs-studio/blog/511770/ 12/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
{
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;
}
The analyzer noticed the error that after dynamic memory allocation in CreateObject, when an exception occurs, the memory is not
cleared, and consequently, a memory leak occurs.
Warning 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
Few, but a static code analyzer would be able to pass this test for attention. It is diligence that this example of copy paste checks.
Warnings 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
{
....
https://habr.com/en/company/pvs-studio/blog/511770/ 13/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};
Of course, using the same name variable both in the base and derived classes is not always an error. However, inheritance technology
itself assumes that all fields of the parent class are present in the child class. By declaring a field with the same name in the derived
class, we create confusion.
Warning 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
Let's look at it in more detail. The imageDirection / 8 expression will be false if imageDirection is in the range from -7 to 7. Second part:
(imageDirection / 8) != 3 checks imageDirection for being outside the range: from -31 to -24 and from 24 to 31, respectively. It seems
rather strange to check numbers for falling into a certain range in this way, and even if there is no error in this code fragment, I would
recommend rewriting these conditions to more explicit ones. This would significantly simplify the lives of people who will read and
maintain this code afterwards.
Warning 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;
....
}
....
}
This code fragment was most likely obtained by decompilation. Then, judging by the comment left, a part of the non-working code was
deleted. However, there is still a couple of operations on cursorId that also don't make much sense.
https://habr.com/en/company/pvs-studio/blog/511770/ 14/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
Warning 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); // <=
}
....
}
This code is quite simple to correct — one either needs to check player for a null pointer for the third time, or add it to the body of the
conditional operator. I would suggest the second option:
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);
}
}
....
}
Warning 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
https://habr.com/en/company/pvs-studio/blog/511770/ 15/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
{
....
entry.name = (name == nullptr ? "" : json_string_value(name));
....
}
....
}
You can get rid of a hard-to-read line of code in one fell swoop and solve the problem with checking for nullptr. I would change the
code as follows:
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);
....
}
....
}
Warning N8
V1048 [CWE-1164] The 'ColumnHeaderPressedCurrentState' variable was assigned the same value. libopenrct2ui CustomListView.cpp
510
void CustomListView::MouseUp(....)
{
....
TOP POSTS
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
Day Week Month
ColumnHeaderPressedCurrentState = false;
Invalidate();
Памятка
} для пострадавшего от слезоточивого газа/перцового баллона
}
+132 47.2k 251 110
TheAudio
code over
looksBluetooth: mostI think
quite strange. detailed information
there was a typo about
either profiles, codecs,or
in the condition and devices
when reassigning the false value to the
ColumnHeaderPressedCurrentStatevariable.
+22 112k 10 8
Conclusion
Technical analysis of the checkm8 exploit
+22 59.6k 5 4
As we can see, it is quite easy to integrate the PVS-Studio static analyzer into your TeamCity project. To do this, you just need to write
one small configuration file. For its part, checking the code will allow you to detect problems immediately after the build, which will help
Java vs .Net: Who will Reign in the Future?
you fix them when the complexity and cost of edits are still small.
+3 6.2k 5 2
Tags: c, c++, static code analysis, static code analyzer, TeamCity, pvs-studio, open source, continious integration, Open RollerCoaster Tycoon,
game development, gamedev
https://habr.com/en/company/pvs-studio/blog/511770/ 16/17
8/15/2020 PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerCoaster Tycoon 2 project / PVS-Studio corporate blo…
SIMILAR POSTS
Getting Started with the PVS-Studio Static Analyzer for C++ Development under Linux
+21 745 1 0
How to quickly check out interesting warnings given by the PVS-Studio analyzer for C and C++ code?
+22 523 1 0
Comments 0
Only users with full accounts can post comments. Log in, please.
https://habr.com/en/company/pvs-studio/blog/511770/ 17/17