PVS-Studio, a solution for resource intensive applications development
1. PVS-Studio,
a solution for developers of modern
resource-intensive applications
OOO “Program Verification Systems” (Co Ltd)
www.viva64.com
2. PVS-Studio Overview
PVS-Studio is a static analyzer that
detects errors in source code of C, C++,
C#.
There are sets of rules included into PVS-
Studio:
1. General-purpose diagnosis
2. Detection of possible optimizations
3. Diagnosis of 64-bit errors (Viva64)
4. Priority of & and ! operations
Return to Castle Wolfenstein – computer game, first
person shooter, developed by id Software company. Game
engine is available under GPL license.
#define SVF_CASTAI 0x00000010
if ( !ent->r.svFlags & SVF_CASTAI )
if ( ! (ent->r.svFlags & SVF_CASTAI) )
5. Usage of && instead of &
#define REO_INPLACEACTIVE (0x02000000L)
#define REO_OPEN (0x04000000L)
if (reObj.dwFlags && REO_INPLACEACTIVE)
m_pRichEditOle->InPlaceDeactivate();
if(reObj.dwFlags && REO_OPEN)
hr = reObj.poleobj->Close(OLECLOSE_NOSAVE);
Stickies – yellow sticky notes, just only on your
monitor.
6. Last line effect
public void SavePassword(IMember member, string password)
{
....
member.RawPasswordValue = result.RawPasswordValue;
member.LastPasswordChangeDate = result.LastPasswordChangeDate;
member.UpdateDate = member.UpdateDate;
}
Umbraco is an open-source content
management system platform for publishing
content on the World Wide Web and intranets.
Last line effect - http://www.viva64.com/en/b/0260/
7. Undefined behavior
while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') {
Miranda IM (Miranda Instant Messenger) –
instant messaging software for Microsoft
Windows.
8. Usage of `delete` for an array
auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
~auto_ptr() {
delete _Myptr;
}
Chromium – open source web browser developed by
Google. The development of Google Chrome browser is
based upon Chromium.
You should not use auto_ptr with arrays. Only one element is destroyed inside
auto_ptr destructor:
For example you can use boost::scoped_array as an alternative.
9. Condition is always true
WinDjView is fast and small app for viewing
files of DjVu format.
inline bool IsValidChar(int c)
{
return c == 0x9 || 0xA || c == 0xD || c >= 0x20 && c <= 0xD7FF
|| c >= 0xE000 && c <= 0xFFFD || c >= 0x10000 && c <= 0x10FFFF;
}
10. Code formatting differs from it’s own
logic
if(pushval != 0)
if(pushval) v->GetUp(-1) = t;
else
v->Pop(1);
Squirrel – interpreted programming
language, which is developed to be used as
a scripting language in real time
applications such as computer games.
v->Pop(1); - will never be reached
11. Incidental local variable declaration
FCE Ultra – open source Nintendo Entertainment
System console emulator
int iNesSaveAs(char* name)
{
...
fp = fopen(name,"wb");
int x = 0;
if (!fp)
int x = 1;
...
}
12. Using char as unsigned char
// check each line for illegal utf8 sequences.
// If one is found, we treat the file as ASCII,
// otherwise we assume an UTF8 file.
char * utf8CheckBuf = lineptr;
while ((bUTF8)&&(*utf8CheckBuf))
{
if ((*utf8CheckBuf == 0xC0)||
(*utf8CheckBuf == 0xC1)||
(*utf8CheckBuf >= 0xF5))
{
bUTF8 = false;
break;
}
TortoiseSVN — client of Subversion revision control system,
implemented as Windows shell extension.
13. Incidental use of octal values
oCell._luminance = uint16(0.2220f*iPixel._red +
0.7067f*iPixel._blue +
0.0713f*iPixel._green);
....
oCell._luminance = 2220*iPixel._red +
7067*iPixel._blue +
0713*iPixel._green;
eLynx Image Processing SDK and Lab
14. One variable is used for two loops
static int i,j,k,l,m;
...
for(j=0; j<numrepeats; j++){
...
for(i=0; i<num_joints; i++){
...
for(j=0;j<num_joints;j++){
if(joints[j].locked)freely=0;
}
...
}
...
}
Lugaru — first commercial game developed by
Wolfire Games independent team.
15. Array overrun
#define SBMAX_l 22
int l[1+SBMAX_l];
for (r0 = 0; r0 < 16; r0++) {
...
for (r1 = 0; r1 < 8; r1++) {
int a2 = gfc->scalefac_band.l[r0 + r1 + 2];
LAME – free app for MP3 audio encoding.
16. Priority of * and ++ operations
STDMETHODIMP CCustomAutoComplete::Next(...,
ULONG *pceltFetched)
{
...
if (pceltFetched != NULL)
*pceltFetched++;
...
}
(*pceltFetched)++;
eMule is a client for ED2K file sharing network.
17. Comparison mistake
BUFFERTYPE m_nBufferType[2];
...
// Handle unnamed buffers
if ((m_nBufferType[nBuffer] == BUFFER_UNNAMED) ||
(m_nBufferType[nBuffer] == BUFFER_UNNAMED))
nSaveErrorCode = SAVE_NO_FILENAME;
WinMerge — free open source software intended for
the comparison and synchronization of files and
directories.
By reviewing the code close by, this should contain:
(m_nBufferType[0] == BUFFER_UNNAMED) ||
(m_nBufferType[1] == BUFFER_UNNAMED)
18. Forgotten array index
IPP Samples are samples demonstrating how to
work with Intel Performance Primitives Library
7.0.
void lNormalizeVector_32f_P3IM(..., Ipp32s* mask, ...) {
Ipp32s i;
Ipp32f norm;
for(i=0; i<len; i++) {
if(mask<0) continue;
...
}
}
if(mask[i]<0) continue;
19. Identical source code branches
Notepad++ - free text editor for Windows supporting
syntax highlight for a variety of programming languages.
if (!_isVertical)
Flags |= DT_VCENTER;
else
Flags |= DT_BOTTOM;
if (!_isVertical)
Flags |= DT_BOTTOM;
else
Flags |= DT_BOTTOM;
20. Calling incorrect function with similar
name
/** Deletes all previous field specifiers.
* This should be used when dealing
* with clients that send multiple NEP_PACKET_SPEC
* messages, so only the last PacketSpec is taken
* into account. */
int NEPContext::resetClientFieldSpecs(){
this->fspecs.empty();
return OP_SUCCESS;
} /* End of resetClientFieldSpecs() */
What a beautiful comment. But it is sad that here we’re doing not what was
intended.
Nmap Security Scanner – free utility intended for
diverse customizable scanning of IP-networks with
any number of objects and for identification of the
statuses of the objects belonging to the network
which is being scanned.
21. Dangerous ?: operator
Newton Game Dynamics – a well known physics
engine which allows for reliable and fast simulation
of environmental object’s physical behavior.
den = dgFloat32 (1.0e-24f) *
(den > dgFloat32(0.0f)) ? dgFloat32(1.0f) : dgFloat32(-1.0f);
The priority of ?: is lower than that of multiplication operator *.
22. And so on, and so on…
FCE Ultra
if((t=(char *)realloc(
next->name, strlen(name+1))))
if((t=(char *)realloc(
next->name, strlen(name)+1)))
minX=max(0,minX+mcLeftStart-2);
minY=max(0,minY+mcTopStart-2);
maxX=min((int)width,maxX+mcRightEnd-1);
maxY=min((int)height,maxX+mcBottomEnd-1);
minX=max(0,minX+mcLeftStart-2);
minY=max(0,minY+mcTopStart-2);
maxX=min((int)width,maxX+mcRightEnd-1);
maxY=min((int)height,maxY+mcBottomEnd-1);
25. Low level memory management
operations
dgInt32 faceOffsetHitogram[256];
dgSubMesh* mainSegmenst[256];
memset (faceOffsetHitogram, 0, sizeof (faceOffsetHitogram));
memset (mainSegmenst, 0, sizeof (faceOffsetHitogram));
This code was duplicated but was not entirely corrected. As a result the
size of pointer will not be equal to the size of dgInt32 type on Win64 and
we will flush only a fraction of mainSegmenst array.
A beautiful example of 64-bit error:
27. Low level memory management
operations
Yes, at present
this is not a
mistake.
But it is a
landmine!
Real w, x, y, z;
...
inline Quaternion(Real* valptr)
{
memcpy(&w, valptr, sizeof(Real)*4);
}
OGRE — open source Object-Oriented Graphics
Rendering Engine written in C++.
28. And a whole lot of other errors in well
known projects
• Qt 5
• Unreal Engine 4
• Analysis of Microsoft Code Contracts
• Wine
• LibreOffice
• Linux kernel
• ReactOS
Here are the links to the articles containing descriptions of the errors:
http://www.viva64.com/en/a/0084/
29. Types of detectable errors
• copy-paste errors;
• Incorrect formatting strings (printf);
• buffer overflow;
• Incorrect utilization of STL, WinAPI;
• ...
• errors concerning the migration of 32-bit
applications to 64-bit systems (Viva64);
31. PVS-Studio Features
• Incremental Analysis – verification of newly compiled files;
• Verification of files which were recently modified several days ago;
• Verification of files by their filenames from within the text file list;
• continuous integration systems support;
• version control systems integration;
• ability to operate fro m command line interface;
• «False Alarms» marking;
• saving and loading of analysis results;
• utilizing all available cores and processors;
• IncrediBuild support;
• interactive filters;
• Russian and English online documentation;
• Pdf documentation;
33. Incremental Analysis – verification of newly
compiled files
• you just work with Visual Studio as usual;
• compile by F7;
• the verification of newly compiled files will start in
background automatically;
• At the end of verification the notification will appear,
allowing you to inspect detected errors;
34. VCS and CI support
(revision control, continuous integration)
• launching from command line:
• sending the results by mail:
• commands for launching from CruiseControl.Net,
Hudson, Microsoft TFS are readily available
"C:Program Files (x86)PVS-Studiox64PVS-Studio.exe"
--sln-file "C:UsersevgDocuments OmniSampleOmniSample (vs2008).sln"
--plog-file "C:UsersevgDocumentsresult.plog"
--vcinstalldir "C:Program Files (x86)Microsoft Visual Studio 9.0VC"
--platform "x64"
--configuration "Release”
cmd.exe /c type result-log.plog.only_new_messages.txt
35. Interactive filters
• filtering messages without restarting the
analysis
• Filtering by errors’ code, by filenames
(including masks), by messages’ text, by
warning levels;
• displaying/hiding false alarms.