статический анализ кода

  • View
    888

  • Download
    0

Embed Size (px)

DESCRIPTION

 

Transcript

  • 1. ..-.., MVP, : www.viva64.comE-Mail: karpov@viva64.com

2. - (TDD) 3. 4. (code-review).: ; ; ; ; , . 5. Cppcheck ; Visual Studio; Intel Parallel Studio; PC-Lint $389 $3500 10, ; PVS-Studio 3500 5 , ; Klocwork 30000 + 20 ; Coverity . 6. TDD? ; , ; (undefinedbehavior, ); -: ; ; ; . 7. void checkFormatConversion::Test(...){eLynxSDK...static struct { bool _b1, _b2; } ms_2boolean[] = {{ false, false },{ false, true },{ true, false },{ true, true }};const int b2size =sizeof(ms_2boolean) / sizeof(ms_2boolean);...}V501 There are identical sub-expressions sizeof (ms_2boolean) tothe left and to the right of the / operator. 8. , void idBrushBSP::FloodThroughPortals_r(idBrushBSPNode *node, ....){...if ( node->occupied ) {common->Error("FloodThroughPortals_r: node already occupiedn");}if ( !node ) {common->Error("FloodThroughPortals_r: NULL noden");}...} V595 The node pointer was utilized before it was verified against nullptr. Check lines: 1421, 1424. 9. (undefined behavior, )sagabool CLine_Simplification::Simplify(CSG_Shape *pLine, int iPart, bool *Keep){...Keep[iFloater--] = iAnchor == 0 &&iFloater == pLine->Get_Point_Count(iPart) - 1;...}V567 Undefined behavior. The iFloater variable is modified whilebeing used twice between sequence points. 10. -: : 11. -: #include void test(){const size_t Gbyte = 1024 * 1024 * 1024;size_t i;char *Pointers[3];// Allocatefor (i = 0; i != 3; ++i)Pointers[i] = (char *)malloc(Gbyte);// Usefor (i = 0; i != 3; ++i)Pointers[i][0] = 1;// Freefor (i = 0; i != 3; ++i)free(Pointers[i]);} 12. malloc Pointers[i] = (char *)malloc(Gbyte); mov rcx,qword ptr [Gbyte] call qword ptr [__imp_malloc (14000A518h)] movrcx,qword ptr [i] movqword ptr Pointers[rcx*8],rax malloc Pointers[i] = (char *)malloc(Gbyte); movrcx,qword ptr [Gbyte] call malloc (1400011A6h) cdqe movrcx,qword ptr [i] movqword ptr Pointers[rcx*8],rax 13. -: int JoiningProc(HWND hwnd,UINT uMsg, Fennec Media ProjectWPARAM wParam,LPARAM lParam){...OPENFILENAME lofn;memset(&lofn, 0, sizeof(lofn));...lofn.lpstrFilter = uni("All Files (*.*)0*.*");...}V540 Member lpstrFilter should point to string terminated bytwo 0 characters. 14. -: void AccessibleContainsAccessible(...){...auto_ptr child_array(new VARIANT[child_count]);...}V554 Incorrect use of auto_ptr. The memory allocated with new []will be cleaned using delete. 15. ! 16. . N1.( . !) Dolphinvoid drawShadedTexSubQuad(...,const MathUtil::Rectangle* rDest, ...){...if (stsq_observer ||memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest))!=0 ||tex_sub_quad_data.u1!=u1 || tex_sub_quad_data.v1!=v1 ||tex_sub_quad_data.u2!=u2 || tex_sub_quad_data.v2!=v2 ||tex_sub_quad_data.G != G)...} 17. . N1.( . !)Dolphinvoid drawShadedTexSubQuad(...,const MathUtil::Rectangle* rDest, ...){...if (stsq_observer ||memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest))!=0 ||tex_sub_quad_data.u1!=u1 || tex_sub_quad_data.v1!=v1 ||tex_sub_quad_data.u2!=u2 || tex_sub_quad_data.v2!=v2 ||tex_sub_quad_data.G != G)...} V579 The memcmp function receives the pointer and its size as arguments. It is possibly a mistake. Inspect the third argument. 18. . N2.bool ots_gdef_parse(...) {...const unsigned gdef_header_end =static_cast(8) +gdef->version_2 ? static_cast(2) :static_cast(0);...} 19. . N2.bool ots_gdef_parse(...) {...const unsigned gdef_header_end =static_cast(8) +gdef->version_2 ? static_cast(2) :static_cast(0);...}V502 Perhaps the ?: operator works in a different way than it was expected. The ?:operator has a lower priority than the + operator. 20. . N3.int EditStreamPadSilence(....)vscap{...if (hr = AVIFileGetStream(pfileSilence, &paviSilence, streamtypeAUDIO , 0)!= AVIERR_OK){ErrMsg("Unable to load silence stream");return hr;}...} 21. . N3.int EditStreamPadSilence(....) vscap{...if (hr = AVIFileGetStream(pfileSilence, &paviSilence, streamtypeAUDIO , 0)!= AVIERR_OK){ErrMsg("Unable to load silence stream");return hr;}...}V593 Consider reviewing the expression of the A = B != C kind. Theexpression is calculated as following: A = (B != C). 22. . N4.void Sys_GetCurrentMemoryStatus(sysMemoryStats_t &stats ) {...memset( &statex, sizeof( statex ), 0 );...} 23. . N4.void Sys_GetCurrentMemoryStatus(sysMemoryStats_t &stats ) {...memset( &statex, sizeof( statex ), 0 );...}V575 The memset function processes 0 elements. Inspect the third argument. 24. . N5.void CAST256::Base::UncheckedSetKey(const byte *userKey,unsigned int keylength, const NameValuePairs &){ AssertValidKeyLength(keylength); word32 kappa[8]; ... memset(kappa, 0, sizeof(kappa));} 25. . N5.void CAST256::Base::UncheckedSetKey(const byte *userKey,unsigned int keylength, const NameValuePairs &){ AssertValidKeyLength(keylength); word32 kappa[8]; ... memset(kappa, 0, sizeof(kappa));}V597 The compiler could delete the memset function call, which isused to flush kappa buffer. The RtlSecureZeroMemory() functionshould be used to erase the private data. 26. . N6.#define FILE_ATTRIBUTE_DIRECTORY 0x00000010bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {...info->is_directory =file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;...} 27. . N6.#define FILE_ATTRIBUTE_DIRECTORY 0x00000010bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {...info->is_directory =file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;...} V564 The & operator is applied to bool type value. Youve probably forgotten to include parentheses or intended to use the && operator. 28. . N7. void BCMenu::InsertSpaces(void) { BCmenu if(IsLunaMenuStyle()) if(!xp_space_accelerators)return; else if(!original_space_accelerators)return; ... } 29. . N7. void BCMenu::InsertSpaces(void) {BCmenu if(IsLunaMenuStyle()) if(!xp_space_accelerators) return; else if(!original_space_accelerators) return; ... }V563 It is possible that this else branch must apply to the previous ifstatement. 30. . N8.BOOL TortoiseBlame::OpenFile(const TCHAR *fileName){...char * utf8CheckBuf = lineptr;while ((bUTF8)&&(*utf8CheckBuf)){if ((*utf8CheckBuf == 0xC0)||(*utf8CheckBuf == 0xC1)||(*utf8CheckBuf >= 0xF5)){bUTF8 = false;break;}...} 31. . N8.BOOL TortoiseBlame::OpenFile(const TCHAR *fileName){...char * utf8CheckBuf = lineptr;while ((bUTF8)&&(*utf8CheckBuf)){if ((*utf8CheckBuf == 0xC0)||(*utf8CheckBuf == 0xC1)||(*utf8CheckBuf >= 0xF5)){bUTF8 = false;break;}...}V547 Expression * utf8CheckBuf == 0xC0 is always false. Thevalue range of signed char type: [-128, 127]. 32. . N9.inlinevoid elxLuminocity(const PixelRGBi& iPixel, LuminanceCell< PixelRGBi >& oCell){oCell._luminance = 2220 * iPixel._red + 7067 * iPixel._blue +eLynxSDK 0713 * iPixel._green;oCell._pixel = iPixel;} 33. . N9.inlinevoid elxLuminocity(const PixelRGBi& iPixel, LuminanceCell< PixelRGBi >& oCell){oCell._luminance = 2220 * iPixel._red + 7067 * iPixel._blue +eLynxSDK 0713 * iPixel._green;oCell._pixel = iPixel;}V536 Be advised that the utilized constant value is represented by anoctal form. Oct: 0713, Dec: 459. 34. . N10.STDMETHODIMP CShellExt::Initialize(....){...ignoredprops.empty();for (int p=0; p 0.0 && aXResolution > 0.0)) { return NS_ERROR_ILLEGAL_VALUE; } ... }V501 There are identical sub-expressions to the left and to the right ofthe && operator: aXResolution > 0.0 && aXResolution > 0.0 ? 41. ++ - ; , . 42. PVS-Studio:http://www.viva64.com/ru/pvs-studio/ Twitter: https://twitter.com/Code_Analysis E-Mail: karpov@viva64.com .: +7 (4872) 38-59-95 (GMT + 03:00)