├── .gitignore ├── 3rdparty ├── 3rdparty.cmake └── json.hpp ├── CMakeLists.txt ├── LICENSE ├── README.md ├── README_en.md ├── buildscript └── buildwithcmd.bat ├── catch_benchmarks ├── CMakeLists.txt └── main.cpp ├── detector_core ├── CMakeLists.txt ├── common │ ├── codeconversion.cpp │ ├── codeconversion.h │ ├── common.cmake │ ├── filehelp.cpp │ ├── filehelp.h │ ├── filepath.cpp │ ├── filepath.h │ ├── filepathhelper.h │ ├── ifile.h │ ├── ipath.h │ ├── maphelp.cpp │ ├── maphelp.h │ ├── pathHelper.h │ ├── reflecter.h │ ├── stringhelper.cpp │ └── stringhelper.h ├── detector_core.cmake ├── detector_global.h ├── detectorcommon │ ├── bracehelper.cpp │ ├── bracehelper.h │ ├── classdefinition.cpp │ ├── classdefinition.h │ ├── codefilter.cpp │ ├── codefilter.h │ ├── cpppath.cpp │ ├── cpppath.h │ ├── detectorcommon.cmake │ ├── detectorcommon.cpp │ ├── detectorcommon.h │ ├── detectorhelp.cpp │ ├── detectorhelp.h │ ├── fordefinition.cpp │ ├── fordefinition.h │ ├── functiondefinition.cpp │ ├── functiondefinition.h │ ├── ifdefinition.cpp │ ├── ifdefinition.h │ ├── jsonparsehelper.h │ ├── msgrestorer.cpp │ ├── msgrestorer.h │ ├── variabledefinition.cpp │ └── variabledefinition.h ├── detectorcontext │ ├── detectorcontext.cmake │ ├── detectorcontext.cpp │ ├── detectorcontext.h │ ├── detectorcontextcore.cpp │ ├── detectorcontextcore.h │ ├── multiprocessdetectorcontext.cpp │ ├── multiprocessdetectorcontext.h │ ├── multithreaddetectorcontext.cpp │ ├── multithreaddetectorcontext.h │ ├── singlethreaddetectorcontext.cpp │ └── singlethreaddetectorcontext.h └── detectors │ ├── accesscontrol │ ├── accesscontrol.cmake │ ├── accesscontroldetector.h │ ├── accesscontrolrule_membervariable.cpp │ └── accesscontrolrule_membervariable.h │ ├── array │ ├── array.cmake │ ├── arraydetector.h │ ├── arrayrule_bufferoverflow.cpp │ ├── arrayrule_bufferoverflow.h │ ├── arrayrule_indexcheckdefectively.cpp │ ├── arrayrule_indexcheckdefectively.h │ ├── arrayrule_indexoutofbounds.cpp │ ├── arrayrule_indexoutofbounds.h │ ├── arrayrule_indexoutofboundsfromfunc.cpp │ ├── arrayrule_indexoutofboundsfromfunc.h │ ├── arrayrule_indexoutofboundsinloop.cpp │ ├── arrayrule_indexoutofboundsinloop.h │ ├── arrayrule_indexusedbeforecheck.cpp │ ├── arrayrule_indexusedbeforecheck.h │ ├── arrayrule_memsetzerobyte.cpp │ ├── arrayrule_memsetzerobyte.h │ ├── arrayrulehelper.cpp │ └── arrayrulehelper.h │ ├── class │ ├── class.cmake │ ├── classdetector.h │ ├── classrule_pairofconstructorandassignment.cpp │ └── classrule_pairofconstructorandassignment.h │ ├── confused │ ├── confused.cmake │ ├── confuseddetector.h │ ├── confusedrule_assignmentinassertorif.cpp │ ├── confusedrule_assignmentinassertorif.h │ ├── confusedrule_break.cpp │ ├── confusedrule_break.h │ ├── confusedrule_casewithoutbreak.cpp │ ├── confusedrule_casewithoutbreak.h │ ├── confusedrule_conditionrepeat.cpp │ ├── confusedrule_conditionrepeat.h │ ├── confusedrule_constructor.cpp │ ├── confusedrule_constructor.h │ ├── confusedrule_diffvariablewithinitandcondition.cpp │ ├── confusedrule_diffvariablewithinitandcondition.h │ ├── confusedrule_nothandlefuncreturn.cpp │ ├── confusedrule_nothandlefuncreturn.h │ ├── confusedrule_priority.cpp │ ├── confusedrule_priority.h │ ├── confusedrule_prioritywithassignmentandcompare.cpp │ ├── confusedrule_prioritywithassignmentandcompare.h │ ├── confusedrule_returnbool.cpp │ ├── confusedrule_returnbool.h │ ├── confusedrule_semicolon.cpp │ ├── confusedrule_semicolon.h │ ├── confusedrule_statementOutsideOfcase.cpp │ ├── confusedrule_statementOutsideOfcase.h │ ├── confusedrule_switchwihtoutdefault.cpp │ └── confusedrule_switchwihtoutdefault.h │ ├── detector.h │ ├── detectors.cmake │ ├── dynamic │ ├── dynamic.cmake │ ├── dynamicdetector.h │ ├── dynamicrule_inline.cpp │ ├── dynamicrule_inline.h │ ├── dynamicrule_localstatic.cpp │ ├── dynamicrule_localstatic.h │ ├── dynamicrulehelper.cpp │ └── dynamicrulehelper.h │ ├── idetector.h │ ├── inline │ ├── inline.cmake │ ├── inlinedetector.h │ ├── inlinerule_complexfunction.cpp │ ├── inlinerule_complexfunction.h │ ├── inlinerule_recursion.cpp │ ├── inlinerule_recursion.h │ ├── inlinerule_specialclassmethod.cpp │ ├── inlinerule_specialclassmethod.h │ ├── inlinerule_tenlines.cpp │ └── inlinerule_tenlines.h │ ├── iterator │ ├── iterator.cmake │ ├── iteratordetector.h │ ├── iteratorrule_invaliddereference.cpp │ ├── iteratorrule_invaliddereference.h │ ├── iteratorrule_outofbound.cpp │ └── iteratorrule_outofbound.h │ ├── lambda │ ├── lambda.cmake │ ├── lambdadetector.h │ ├── lambdarule_catchbyreference.cpp │ └── lambdarule_catchbyreference.h │ ├── logic │ ├── logic.cmake │ ├── logicdetector.h │ ├── logicrule_assignself.cpp │ ├── logicrule_assignself.h │ ├── logicrule_basevalue.cpp │ ├── logicrule_basevalue.h │ ├── logicrule_expressionrepetition.cpp │ ├── logicrule_expressionrepetition.h │ ├── logicrule_incorrectoperation.cpp │ ├── logicrule_incorrectoperation.h │ ├── logicrule_stringfind.cpp │ └── logicrule_stringfind.h │ ├── loop │ ├── loop.cmake │ ├── loopdetector.h │ ├── looprule_helper.cpp │ ├── looprule_helper.h │ ├── looprule_outofbounds.cpp │ ├── looprule_outofbounds.h │ ├── looprule_suggestauto.cpp │ ├── looprule_suggestauto.h │ ├── looprule_wrongstepdirection.cpp │ ├── looprule_wrongstepdirection.h │ ├── looprule_wrongvariable.cpp │ └── looprule_wrongvariable.h │ ├── memleak │ ├── memleak.cmake │ ├── memleakdetector.h │ ├── memleakrule_destructor.cpp │ ├── memleakrule_destructor.h │ ├── memleakrule_filehandle.cpp │ ├── memleakrule_filehandle.h │ ├── memleakrule_mallocfree.cpp │ ├── memleakrule_mallocfree.h │ ├── memleakrule_newwithoutdelete.cpp │ ├── memleakrule_newwithoutdelete.h │ ├── memleakrule_realloc.cpp │ └── memleakrule_realloc.h │ ├── operation │ ├── operation.cmake │ ├── operationdetector.h │ ├── operationrule_arithmeticwithbool.cpp │ ├── operationrule_arithmeticwithbool.h │ ├── operationrule_bitwiseshifttonegative.cpp │ ├── operationrule_bitwiseshifttonegative.h │ ├── operationrule_bitwisewithbool.cpp │ ├── operationrule_bitwisewithbool.h │ ├── operationrule_float.cpp │ ├── operationrule_float.h │ ├── operationrule_module.cpp │ ├── operationrule_module.h │ ├── operationrule_unsignedlessthanzero.cpp │ ├── operationrule_unsignedlessthanzero.h │ ├── operationrule_zerodivision.cpp │ └── operationrule_zerodivision.h │ ├── pointer │ ├── pointer.cmake │ ├── pointerdetector.h │ ├── pointerrule_checkafternew.cpp │ ├── pointerrule_checkafternew.h │ ├── pointerrule_helper.cpp │ ├── pointerrule_helper.h │ ├── pointerrule_ifnulldefect.cpp │ ├── pointerrule_ifnulldefect.h │ ├── pointerrule_localvariable.cpp │ ├── pointerrule_localvariable.h │ ├── pointerrule_notcheck.cpp │ ├── pointerrule_notcheck.h │ ├── pointerrule_nullptr.cpp │ ├── pointerrule_nullptr.h │ ├── pointerrule_returnnull.cpp │ ├── pointerrule_returnnull.h │ ├── pointerrule_useddanglingpointer.cpp │ ├── pointerrule_useddanglingpointer.h │ ├── pointerrule_usedinsideofnullcheck.cpp │ ├── pointerrule_usedinsideofnullcheck.h │ ├── pointerrule_usednull.cpp │ ├── pointerrule_usednull.h │ ├── pointerrule_usedoutsideofcheck.cpp │ ├── pointerrule_usedoutsideofcheck.h │ ├── pointerrule_useduninitialized.cpp │ ├── pointerrule_useduninitialized.h │ ├── pointerrule_useduninitializedornull.cpp │ └── pointerrule_useduninitializedornull.h │ ├── rule.h │ ├── singleton │ ├── singleton.cmake │ ├── singletondetector.h │ ├── singletonrule_threadsafety.cpp │ └── singletonrule_threadsafety.h │ ├── sizeof │ ├── sizeof.cmake │ ├── sizeofdetector.h │ ├── sizeofrule_funcparameter.cpp │ ├── sizeofrule_funcparameter.h │ ├── sizeofrule_pointer.cpp │ ├── sizeofrule_pointer.h │ ├── sizeofrule_repetition.cpp │ ├── sizeofrule_repetition.h │ ├── sizeofrule_withnumber.cpp │ └── sizeofrule_withnumber.h │ ├── uninit │ ├── uninit.cmake │ ├── uninitdetector.h │ ├── uninitrule_helper.cpp │ ├── uninitrule_helper.h │ ├── uninitrule_pointer.cpp │ ├── uninitrule_pointer.h │ ├── uninitrule_var.cpp │ └── uninitrule_var.h │ └── variable │ ├── variable.cmake │ ├── variabledetector.h │ ├── variablerule_global.cpp │ └── variablerule_global.h ├── main.cpp ├── release └── windows_x64 │ ├── checklastpush.bat │ ├── checklastpushcore.bat │ ├── config │ ├── detectorRuleContents.json │ ├── detectorRuleNames.json │ └── exceptionconfig.json │ ├── cppdetector │ ├── api-ms-win-crt-convert-l1-1-0.dll │ ├── api-ms-win-crt-filesystem-l1-1-0.dll │ ├── api-ms-win-crt-heap-l1-1-0.dll │ ├── api-ms-win-crt-locale-l1-1-0.dll │ ├── api-ms-win-crt-math-l1-1-0.dll │ ├── api-ms-win-crt-runtime-l1-1-0.dll │ ├── api-ms-win-crt-stdio-l1-1-0.dll │ ├── api-ms-win-crt-string-l1-1-0.dll │ ├── cppdetector.exe │ ├── detector_core.dll │ ├── msvcp140.dll │ ├── msvcp140_atomic_wait.dll │ ├── vcruntime140.dll │ └── vcruntime140_1.dll │ ├── readme.md │ ├── run.bat │ └── runcore.bat ├── supporting ├── badcodesamples │ ├── acrossdynamicsample.h │ ├── acrossdynamicsample2.h │ ├── arraysample.h │ ├── arraysample2.h │ ├── classsample.h │ ├── confusedsample.h │ ├── iteratorsample.h │ ├── lambdasample.h │ ├── logicsample.h │ ├── loopsample.h │ ├── memleaksample.h │ ├── operationsample.h │ ├── pointersample.h │ ├── pointersample2.h │ ├── singletonsample.cpp │ ├── singletonsample.h │ ├── sizeofsample.h │ └── uninitsample.h └── exceptionconfig.json └── unit_tests ├── CMakeLists.txt ├── common ├── common.cmake └── stringhelper_tests.cpp ├── detectorcommon ├── bracehelper_tests.cpp ├── classdefinition_tests.cpp ├── detectorcommon.cmake ├── detectorhelp_tests.cpp ├── fordefinition_tests.cpp ├── functiondefinition_tests.cpp ├── ifdefinition_tests.cpp └── variabledefinition_tests.cpp ├── detectors ├── accesscontrol │ ├── accesscontrol.cmake │ └── accesscontrolrule_membervariable_tests.cpp ├── array │ ├── array.cmake │ ├── arrayrule_bufferoverflow_tests.cpp │ ├── arrayrule_indexcheckdefectively_tests.cpp │ ├── arrayrule_indexoutofbounds_tests.cpp │ ├── arrayrule_indexoutofboundsfromfunc_tests.cpp │ ├── arrayrule_indexoutofboundsinloop_tests.cpp │ ├── arrayrule_indexusedbeforecheck_tests.cpp │ └── arrayrule_memsetzerobyte_tests.cpp ├── class │ ├── class.cmake │ └── classrule_pairofconstructorandassignment_tests.cpp ├── confused │ ├── confused.cmake │ ├── confusedrule_assignmentinassertorif_tests.cpp │ ├── confusedrule_break_tests.cpp │ ├── confusedrule_casewithoutbreak_tests.cpp │ ├── confusedrule_conditionrepeat_tests.cpp │ ├── confusedrule_constructor_tests.cpp │ ├── confusedrule_diffvariablewithinitandcondition_tests.cpp │ ├── confusedrule_nothandlefuncreturn_tests.cpp │ ├── confusedrule_priority_tests.cpp │ ├── confusedrule_prioritywithassignmentandcompare_tests.cpp │ ├── confusedrule_returnbool_tests.cpp │ ├── confusedrule_semicolon_tests.cpp │ ├── confusedrule_statementoutsideofcase_tests.cpp │ └── confusedrule_switchwihtoutdefault_tests.cpp ├── detectors.cmake ├── dynamic │ ├── dynamic.cmake │ ├── dynamicrule_inline_tests.cpp │ └── dynamicrule_localstatic_tests.cpp ├── inline │ ├── inline.cmake │ ├── inlinerule_complexfunction_tests.cpp │ ├── inlinerule_recursion_tests.cpp │ ├── inlinerule_specialclassmethod_tests.cpp │ └── inlinerule_tenlines_tests.cpp ├── iterator │ ├── iterator.cmake │ ├── iteratorrule_invaliddereference_tests.cpp │ └── iteratorrule_outofbound_tests.cpp ├── lambda │ ├── lambda.cmake │ └── lambdarule_catchbyreference_tests.cpp ├── logic │ ├── logic.cmake │ ├── logicrule_assignself_tests.cpp │ ├── logicrule_basevalue_tests.cpp │ ├── logicrule_expressionrepetition_tests.cpp │ ├── logicrule_incorrectoperation_tests.cpp │ └── logicrule_stringfind_tests.cpp ├── loop │ ├── loop.cmake │ ├── looprule_helper_tests.cpp │ ├── looprule_outofbounds_tests.cpp │ ├── looprule_suggestauto_tests.cpp │ ├── looprule_wrongstepdirection_tests.cpp │ ├── looprule_wrongvariable_tests.cpp │ └── loopruleoutofbounds_tests.cpp ├── memleak │ ├── memleak.cmake │ ├── memleakrule_destructor_tests.cpp │ ├── memleakrule_filehandle_tests.cpp │ ├── memleakrule_mallocfree_tests.cpp │ ├── memleakrule_newwithoutdelete_tests.cpp │ └── memleakrule_realloc_tests.cpp ├── nanobench_tests.cpp ├── operation │ └── operation.cmake ├── pointer │ ├── pointer.cmake │ ├── pointerrule_notcheck_tests.cpp │ ├── pointerrule_usedinsideofnullcheck_tests.cpp │ └── pointerrule_usednull_tests.cpp ├── singleton │ └── singleton.cmake ├── sizeof │ └── sizeof.cmake ├── uninit │ └── uninit.cmake └── variable │ ├── variable.cmake │ └── variablerule_global_tests.cpp ├── doctest.h ├── nanobench.h └── unit_tests.cmake /.gitignore: -------------------------------------------------------------------------------- 1 | # dir 2 | bin/ 3 | *build*/ 4 | 5 | # Mac 6 | *.DS_Store 7 | *.idea 8 | 9 | # Prerequisites 10 | *.d 11 | 12 | # Compiled Object files 13 | *.slo 14 | *.lo 15 | *.o 16 | *.obj 17 | 18 | # Precompiled Headers 19 | *.gch 20 | *.pch 21 | 22 | # Compiled Dynamic libraries 23 | *.so 24 | *.dylib 25 | *.dll 26 | 27 | # Fortran module files 28 | *.mod 29 | *.smod 30 | 31 | # Compiled Static libraries 32 | *.lai 33 | *.la 34 | *.a 35 | *.lib 36 | 37 | # Executables 38 | *.exe 39 | *.out 40 | *.app 41 | -------------------------------------------------------------------------------- /3rdparty/3rdparty.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME 3rdparty) 2 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 3 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 4 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 5 | SET(SOURCES 6 | ${SOURCES} 7 | ${RECURSE_H} 8 | ) 9 | SET(HEADERS 10 | ${HEADERS} 11 | ${RECURSE_CPP} 12 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 zhlongfj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /buildscript/buildwithcmd.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | set curdir=%~dp0 3 | set rootdir=%curdir%.. 4 | cd %rootdir% 5 | echo %rootdir% 6 | set builddir=%rootdir%\build 7 | if exist %builddir% ( 8 | rd /s /q %builddir% 9 | ) 10 | 11 | mkdir build 12 | cd build 13 | 14 | ::setting vcpkg when using breakpad with vcpkg 15 | ::cmake .. -DUSE_VCPKG=on -DVCPKG_ROOT=F:/git/vcpkg 16 | 17 | cmake .. 18 | cmake --build . -target all --config RelWithDebInfo -------------------------------------------------------------------------------- /catch_benchmarks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | 3 | set(VCPKG_CMAKE ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) 4 | set(CMAKE_TOOLCHAIN_FILE ${VCPKG_CMAKE}) 5 | 6 | project(catch_benchmarks_run) 7 | set(CMAKE_CXX_STANDARD 17) 8 | 9 | SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin) 10 | 11 | set(SOURCE_FILES main.cpp) 12 | 13 | #add_definitions(-DBUILD_STATIC) 14 | 15 | find_package(benchmark CONFIG REQUIRED) 16 | link_libraries(benchmark::benchmark benchmark::benchmark_main) 17 | 18 | add_executable(catch_benchmarks_run ${SOURCE_FILES}) 19 | 20 | target_link_libraries(catch_benchmarks_run detector_core) -------------------------------------------------------------------------------- /catch_benchmarks/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | void SomeFunction() 4 | { 5 | std::cout << 10 << std::endl; 6 | } 7 | static void BM_SomeFunction(benchmark::State& state) { 8 | // Perform setup here 9 | for (auto _ : state) { 10 | // This code gets timed 11 | SomeFunction(); 12 | } 13 | } 14 | // Register the function as a benchmark 15 | BENCHMARK(BM_SomeFunction); 16 | // Run the benchmark 17 | BENCHMARK_MAIN(); -------------------------------------------------------------------------------- /detector_core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(detector_core) 2 | #add_definitions(-DBUILD_STATIC) 3 | add_definitions(-DDETECTOR_LIB) 4 | 5 | SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin) 6 | 7 | set(HEADER_FILES) 8 | 9 | set(SOURCE_FILES) 10 | 11 | INCLUDE(detector_core.cmake) 12 | 13 | #add_library(detector_core STATIC ${SOURCES} ${HEADERS}) 14 | add_library(detector_core SHARED ${SOURCES} ${HEADERS}) 15 | -------------------------------------------------------------------------------- /detector_core/common/codeconversion.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | #pragma once 5 | #include 6 | #include "detector_global.h" 7 | enum Encode { ANSI = 1, UTF16_LE, UTF16_BE, UTF8_BOM, UTF8 }; 8 | 9 | class DETECTOR_EXPORT CodeConversion final 10 | { 11 | public: 12 | static std::string gb2312_to_utf8(std::string const& strGb2312); 13 | static std::string utf8_to_gb2312(std::string const& strUtf8); 14 | static Encode checkCodeFormat(const uint8_t* data, size_t size); 15 | }; 16 | -------------------------------------------------------------------------------- /detector_core/common/common.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME common) 2 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 3 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 4 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 5 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 6 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 7 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) -------------------------------------------------------------------------------- /detector_core/common/filehelp.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | 5 | #include 6 | #include 7 | #include "filehelp.h" 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | bool FileHelp::write(const std::string& filePath, const std::string& content) 14 | { 15 | ofstream outFile(filePath); 16 | if (!outFile.is_open()) 17 | { 18 | return false; 19 | } 20 | outFile << content; 21 | return true; 22 | } 23 | 24 | string FileHelp::parse(const std::string& filePath) 25 | { 26 | m_fileData.clear(); 27 | m_lines.clear(); 28 | ifstream inFile(filePath); 29 | if (!inFile.is_open()) 30 | return ""; 31 | std::string line; 32 | while (std::getline(inFile, line)) 33 | m_fileData += line + "\n"; 34 | 35 | return m_fileData; 36 | } 37 | 38 | std::vector FileHelp::getLines() 39 | { 40 | if (!m_lines.empty()) 41 | { 42 | return m_lines; 43 | } 44 | 45 | std::istringstream iStream(m_fileData); 46 | std::string line; 47 | 48 | while (std::getline(iStream, line)) { 49 | m_lines.emplace_back(line); 50 | } 51 | return m_lines; 52 | } -------------------------------------------------------------------------------- /detector_core/common/filehelp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | #pragma once 5 | #include "detector_global.h" 6 | #include "ifile.h" 7 | 8 | class DETECTOR_EXPORT FileHelp final : public IFile { 9 | public: 10 | bool write(const std::string& filePath, const std::string& content) override; 11 | std::string parse(const std::string& filePath) override; 12 | std::vector getLines() override; 13 | }; 14 | -------------------------------------------------------------------------------- /detector_core/common/filepath.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | 5 | #include 6 | #include "filepath.h" 7 | 8 | using namespace std; 9 | 10 | vector traverseRecursive(const std::string& path, std::function func) 11 | { 12 | filesystem::path filePath(path); 13 | if (!exists(filePath)) { 14 | return vector(); 15 | } 16 | 17 | vector filePaths; 18 | filesystem::directory_entry entry(filePath); 19 | if (entry.status().type() != filesystem::file_type::directory) { 20 | if (func(entry)) { 21 | filePaths.emplace_back(entry.path().generic_string()); 22 | } 23 | return filePaths; 24 | } 25 | 26 | filesystem::directory_iterator fileList(filePath); 27 | for (const auto& item : fileList) { 28 | if (item.status().type() != filesystem::file_type::directory) { 29 | if (func(item)) { 30 | filePaths.emplace_back(item.path().generic_string()); 31 | } 32 | continue; 33 | } 34 | 35 | auto ret = traverseRecursive(item.path().generic_string(), func); 36 | filePaths.insert(filePaths.end(), ret.begin(), ret.end()); 37 | } 38 | return filePaths; 39 | } 40 | 41 | FilePath::FilePath(const std::string& path, std::function func) { 42 | m_filePaths = traverseRecursive(path, func); 43 | } -------------------------------------------------------------------------------- /detector_core/common/filepath.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "ipath.h" 11 | 12 | class FilePath final : public IPath { 13 | public: 14 | FilePath(const std::string& path, std::function func); 15 | }; 16 | -------------------------------------------------------------------------------- /detector_core/common/filepathhelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using namespace std; 4 | using namespace std::filesystem; 5 | class FilePathHelper final { 6 | public: 7 | explicit FilePathHelper(const std::string& path) 8 | : m_path(path) {} 9 | bool exist() 10 | { 11 | filesystem::path filePath(m_path); 12 | return exists(filePath); 13 | } 14 | 15 | file_type fileType() 16 | { 17 | filesystem::directory_entry entry(m_path); 18 | return entry.status().type(); 19 | } 20 | 21 | private: 22 | std::string m_path; 23 | }; 24 | -------------------------------------------------------------------------------- /detector_core/common/ifile.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | 5 | #pragma once 6 | #include 7 | #include 8 | 9 | class IFile { 10 | public: 11 | virtual bool write(const std::string& filePath, const std::string& content) = 0; 12 | virtual std::string parse(const std::string& filePath) = 0; 13 | virtual std::vector getLines() { return m_lines; } 14 | std::string getData() { return m_fileData; } 15 | virtual ~IFile() {}; 16 | protected: 17 | std::string m_fileData; 18 | std::vector m_lines; 19 | }; -------------------------------------------------------------------------------- /detector_core/common/ipath.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | #pragma once 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class IPath { 11 | public: 12 | std::vector getFilePaths() { return m_filePaths; } 13 | virtual ~IPath() {} 14 | protected: 15 | std::vector m_filePaths; 16 | }; 17 | -------------------------------------------------------------------------------- /detector_core/common/maphelp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | template 8 | class MapHelp final { 9 | public: 10 | explicit MapHelp(const map& elements) : m_elements(elements) {} 11 | map erase(const T& reference, function func) 12 | { 13 | for (auto iter = m_elements.begin(); iter != m_elements.end();) 14 | { 15 | if (func(iter->second, reference)) 16 | { 17 | m_elements.erase(iter++); 18 | } 19 | else 20 | { 21 | ++iter; 22 | } 23 | } 24 | return m_elements; 25 | } 26 | private: 27 | map m_elements; 28 | }; 29 | -------------------------------------------------------------------------------- /detector_core/common/maphelp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | template 8 | class MapHelp final { 9 | public: 10 | explicit MapHelp(const map& elements) : m_elements(elements) {} 11 | map erase(const T& reference, function func) 12 | { 13 | for (auto iter = m_elements.begin(); iter != m_elements.end();) 14 | { 15 | if (func(iter->second, reference)) 16 | { 17 | m_elements.erase(iter++); 18 | } 19 | else 20 | { 21 | ++iter; 22 | } 23 | } 24 | return m_elements; 25 | } 26 | private: 27 | map m_elements; 28 | }; 29 | -------------------------------------------------------------------------------- /detector_core/common/pathHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | class PathHelper final 11 | { 12 | public: 13 | static filesystem::path getCMakeListsDir() 14 | { 15 | filesystem::path detectorCommonPath(__FILE__); 16 | auto curDir = (detectorCommonPath.parent_path() / "../.."); 17 | #ifdef _WIN32 18 | //使用VS2019直接打开项目目录,__FILE__生成的是相对路径,如果把它转成绝对路径会发现,路径只想了main.cpp同级目录的out目录下,初步怀疑是VS的bug 19 | //detectorCommonPath = absolute(detectorCommonPath); 20 | //curDir = (detectorCommonPath.parent_path()); 21 | #endif 22 | return curDir.make_preferred().string(); 23 | } 24 | 25 | static filesystem::path getParentPath(const string& filePath) 26 | { 27 | filesystem::path parentPath(filePath); 28 | return parentPath.parent_path().make_preferred(); 29 | } 30 | 31 | static void removeDir(const string& filePath) { 32 | filesystem::remove_all(filePath); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /detector_core/common/reflecter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef void* (*Constructor)(); 6 | 7 | class CObjectFactory final 8 | { 9 | public: 10 | static void registerClass(std::string className, Constructor constructor) 11 | { 12 | constructors()[className] = constructor; 13 | } 14 | 15 | static void* createObject(const std::string& className) 16 | { 17 | Constructor constructor = nullptr; 18 | if (constructors().find(className) != constructors().end()) 19 | constructor = constructors().find(className)->second; 20 | 21 | if (constructor == nullptr) 22 | return nullptr; 23 | 24 | return (*constructor)(); 25 | } 26 | 27 | private: 28 | inline static std::map& constructors() 29 | { 30 | static std::map instance; 31 | return instance; 32 | } 33 | }; 34 | 35 | #define REGISTER_CLASS(class_name) \ 36 | class class_name##Helper{ \ 37 | public: \ 38 | class_name##Helper() \ 39 | { \ 40 | CObjectFactory::registerClass(#class_name, class_name##Helper::creatObjFunc); \ 41 | } \ 42 | static void* creatObjFunc() \ 43 | { \ 44 | return new class_name; \ 45 | } \ 46 | }; \ 47 | inline class_name##Helper class_name##helper; 48 | -------------------------------------------------------------------------------- /detector_core/common/stringhelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "detector_global.h" 5 | using namespace std; 6 | class DETECTOR_EXPORT StringHelper final 7 | { 8 | public: 9 | explicit StringHelper(const string& content) : m_content(content) {} 10 | vector getLines(); 11 | vector split(const string& delims); 12 | bool isDigit(); 13 | string replace(const string& source, const string& target); 14 | string removeSpaceAndTab(); 15 | string removeBeginSpaceAndTab(); 16 | string removeEndSpaceAndTab(); 17 | string trim(); 18 | string toLower(); 19 | size_t count(const char& target); 20 | string continuousCharactersFromStart(const string& characters); 21 | string removeFromStart(const string& characters); 22 | bool remove(const string& target); 23 | bool findCode(const string& target); 24 | std::size_t findIndexOfCode(const string& target); 25 | bool isNull(); 26 | bool isReturnNull(); 27 | bool betweenEdge(const string& target, const string& edge); 28 | size_t getIndexAfterTarget(const string& target); 29 | string getVariableFromSelfOperation(const string& selfOperation); 30 | string content() const { return m_content; } 31 | 32 | private: 33 | string m_content; 34 | }; 35 | -------------------------------------------------------------------------------- /detector_core/detector_core.cmake: -------------------------------------------------------------------------------- 1 | message(_HIBLUE_ "---Start---Configuring detector_core library:") 2 | 3 | include(../3rdparty/3rdparty.cmake) 4 | include(common/common.cmake) 5 | include(detectorcommon/detectorcommon.cmake) 6 | include(detectors/detectors.cmake) 7 | include(detectorcontext/detectorcontext.cmake) 8 | 9 | FILE(GLOB_RECURSE DETECTORS_CORE_H "*.h") 10 | FILE(GLOB_RECURSE DETECTORS_CORE_CPP "*.cpp") 11 | SET(SOURCES 12 | ${SOURCES} 13 | ${DETECTORS_CORE_CPP} 14 | ) 15 | SET(HEADERS 16 | ${HEADERS} 17 | ${DETECTORS_CORE_H} 18 | ) -------------------------------------------------------------------------------- /detector_core/detector_global.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // DARWIN 4 | #if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__)) 5 | #ifndef BUILD_STATIC 6 | # if defined(DETECTOR_LIB) 7 | # define DETECTOR_EXPORT __attribute__((visibility("default"))) 8 | # else 9 | # define DETECTOR_EXPORT __attribute__((visibility("default"))) 10 | # endif 11 | #else 12 | # define DETECTOR_EXPORT 13 | #endif 14 | // ANDROID 15 | #elif defined(__ANDROID__) || defined(ANDROID) 16 | #ifndef BUILD_STATIC 17 | #include 18 | # if defined(DETECTOR_LIB) 19 | # define DETECTOR_EXPORT Q_DECL_EXPORT 20 | # else 21 | # define DETECTOR_EXPORT Q_DECL_IMPORT 22 | # endif 23 | #else 24 | # define DETECTOR_EXPORT 25 | #endif 26 | 27 | // Windows 28 | #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) 29 | #include 30 | #ifndef BUILD_STATIC 31 | # if defined(DETECTOR_LIB) 32 | # define DETECTOR_EXPORT __declspec(dllexport) 33 | # else 34 | # define DETECTOR_EXPORT __declspec(dllimport) 35 | #endif 36 | #else 37 | # define DETECTOR_EXPORT 38 | #endif 39 | // LINUX 40 | #elif defined(__linux__) || defined(__linux) 41 | #include 42 | # if defined(DETECTOR_LIB) 43 | # define DETECTOR_EXPORT __attribute__((visibility("default"))) 44 | # else 45 | # define DETECTOR_EXPORT __attribute__((visibility("default"))) 46 | #endif 47 | #else 48 | # define DETECTOR_EXPORT 49 | #endif 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /detector_core/detectorcommon/bracehelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common/stringhelper.h" 4 | #include "detectorhelp.h" 5 | using namespace std; 6 | 7 | class DETECTOR_EXPORT BraceHelper final 8 | { 9 | public: 10 | int calculateCountOfOpenBrace(const string& code, const int line); 11 | bool findOpenBrace() { return m_findOpenBrace; } 12 | void resetData(); 13 | 14 | private: 15 | void reduceCountOfOpenBrace(const int line); 16 | bool openBraceAtBegin(const string& codeWithoutSpace); 17 | bool openBraceAfterCloseParenthesis(const string& codeWithoutSpace); 18 | bool closeBrace(const string& codeWithoutSpace); 19 | int m_countOfOpenBrace = 0; 20 | bool m_findOpenBrace = false; 21 | }; -------------------------------------------------------------------------------- /detector_core/detectorcommon/codefilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class CodeFilter final 6 | { 7 | public: 8 | std::string filterCode(const std::string& content); 9 | bool invalidCode(const std::string& content); 10 | std::string removeComment(const std::string& content); 11 | void resetData() 12 | { 13 | m_inComment = false; 14 | } 15 | 16 | private: 17 | bool isComment(const std::string& content); 18 | bool m_inComment = false; 19 | }; -------------------------------------------------------------------------------- /detector_core/detectorcommon/cpppath.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | 5 | #include 6 | #include 7 | #include "cpppath.h" 8 | #include "common/filepath.h" 9 | #include 10 | 11 | using namespace std; 12 | 13 | CPPPath::CPPPath(const std::string& path) { 14 | FilePath filePath(path, [](std::filesystem::directory_entry item) { 15 | if (item.status().type() != filesystem::file_type::regular) { 16 | return false; 17 | } 18 | 19 | return isCPPCodeFile(item.path().generic_string()); 20 | }); 21 | m_filePaths = filePath.getFilePaths(); 22 | map filePaths; 23 | for (const auto& item : m_filePaths) 24 | { 25 | filesystem::path pathIner(item); 26 | filePaths.insert({ pathIner.filename().string(), item }); 27 | } 28 | 29 | m_filePaths.clear(); 30 | for (auto iter = filePaths.rbegin(); iter != filePaths.rend(); iter++) 31 | { 32 | m_filePaths.push_back(iter->second); 33 | } 34 | //sort(m_filePaths.rbegin(), m_filePaths.rend()); 35 | } 36 | 37 | bool CPPPath::isCPPCodeFile(const std::string& filePath) 38 | { 39 | const auto& genericPath = filesystem::path(filePath).generic_string(); 40 | auto regValue = R"delimiter((\.h|\.cpp|\.cxx|\.cc|\.c\+\+|\.hpp|\.hxx|\.hh|\.tpp|\.txx)$)delimiter"; 41 | std::regex reg(regValue, regex_constants::icase); 42 | return std::regex_search(genericPath, reg); 43 | } 44 | -------------------------------------------------------------------------------- /detector_core/detectorcommon/cpppath.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/27. 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include "detector_global.h" 9 | #include "common/ipath.h" 10 | 11 | class DETECTOR_EXPORT CPPPath final : public IPath { 12 | public: 13 | explicit CPPPath(const std::string& path); 14 | static bool isCPPCodeFile(const std::string& filePath); 15 | }; 16 | -------------------------------------------------------------------------------- /detector_core/detectorcommon/detectorcommon.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectorcommon) 2 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 3 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 4 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 5 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 6 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 7 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) -------------------------------------------------------------------------------- /detector_core/detectorcommon/fordefinition.cpp: -------------------------------------------------------------------------------- 1 | #include "fordefinition.h" 2 | #include "detectorhelp.h" 3 | #include "common/stringhelper.h" 4 | 5 | bool ForDefinition::isFor(const std::string& content) 6 | { 7 | auto ret = DetectorHelper::checkFor1(content); 8 | if (ret.empty()) 9 | { 10 | return false; 11 | } 12 | 13 | //check "for (unsigned int ii = 0; ii <= foo.size(); ++ii)" or "for (unsigned int ii = 0; ii <= ss; ++ii)" 14 | 15 | m_comparationVariable = ret[2]; 16 | m_comparationSymbol = ret[3]; 17 | m_endCondition = ret[4]; 18 | 19 | auto variable = StringHelper(ret[1].str()).trim(); 20 | if (auto ret1 = DetectorHelper::check(variable, R"delimiter((\s+)*(\w+)$)delimiter"); !ret1.empty()) 21 | { 22 | m_type = ret1.prefix().str(); 23 | m_initVariable = ret1[2]; 24 | } 25 | 26 | auto step = ret[5].str(); 27 | if (auto variable = StringHelper(step).getVariableFromSelfOperation("++"); !variable.empty()) 28 | { 29 | m_stepVariable = variable; 30 | m_stepOperation = "++"; 31 | } 32 | 33 | if (auto variable = StringHelper(step).getVariableFromSelfOperation("--"); !variable.empty()) 34 | { 35 | m_stepVariable = variable; 36 | m_stepOperation = "--"; 37 | } 38 | return true; 39 | } 40 | 41 | void ForDefinition::resetData() 42 | { 43 | m_type.clear(); 44 | m_initVariable.clear(); 45 | m_comparationVariable.clear(); 46 | m_comparationSymbol.clear(); 47 | m_endCondition.clear(); 48 | m_stepVariable.clear(); 49 | m_stepOperation.clear(); 50 | } 51 | -------------------------------------------------------------------------------- /detector_core/detectorcommon/fordefinition.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/26. 3 | // 4 | #pragma once 5 | #include 6 | #include "detector_global.h" 7 | 8 | using namespace std; 9 | 10 | class DETECTOR_EXPORT ForDefinition final { 11 | public: 12 | ForDefinition() = default; 13 | bool isFor(const std::string& content); 14 | std::string type() { return m_type; } 15 | std::string initVariable() { return m_initVariable; } 16 | std::string comparationVariable() { return m_comparationVariable; } 17 | std::string comparationSymbol() { return m_comparationSymbol; } 18 | std::string endCondition() { return m_endCondition; } 19 | std::string stepVariable() { return m_stepVariable; } 20 | std::string stepOperation() { return m_stepOperation; } 21 | void resetData(); 22 | private: 23 | // for (unsigned int i = 0; j <= foo.size(); ++k) 24 | std::string m_type; // unsigned int 25 | std::string m_initVariable; // i 26 | std::string m_comparationVariable; // j 27 | std::string m_comparationSymbol; // <= 28 | std::string m_endCondition; // foo.size() 29 | std::string m_stepVariable; // k 30 | std::string m_stepOperation; // ++ 31 | 32 | }; 33 | -------------------------------------------------------------------------------- /detector_core/detectorcommon/functiondefinition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../common/stringhelper.h" 5 | #include "detectorhelp.h" 6 | 7 | using namespace std; 8 | 9 | class DETECTOR_EXPORT FunctionDefinition final 10 | { 11 | public: 12 | bool inFunctionDefinition(const string& content); 13 | 14 | std::string getFuncName() { return m_funcName; } 15 | 16 | std::string getReturnType() { return m_returnType; } 17 | 18 | bool isFunctionDefinition(const string& content); 19 | 20 | void resetData(); 21 | private: 22 | vector m_sapceBeforeFunctions; 23 | string m_sapceBeforeFunction; 24 | string m_funcName; 25 | string m_returnType; 26 | bool m_inFunction = false; 27 | 28 | }; -------------------------------------------------------------------------------- /detector_core/detectorcommon/ifdefinition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../common/stringhelper.h" 5 | #include "detectorhelp.h" 6 | 7 | using namespace std; 8 | 9 | struct DETECTOR_EXPORT ConditionContext final 10 | { 11 | std::string conditionExpresss; 12 | std::string operatorName; 13 | std::pair operands; 14 | std::string logicalOperatorToNext; 15 | }; 16 | 17 | class DETECTOR_EXPORT IfDefinition final 18 | { 19 | public: 20 | bool inIfDefinition(const std::string& content); 21 | void resetData(); 22 | bool isEnd() { return m_isEnd; } 23 | std::string condition() { return m_condition; } 24 | const std::vector& getConditionContexts() { return m_conditionContexts; } 25 | 26 | private: 27 | std::size_t findEnd(const string& content); 28 | void addCondition(const string& content); 29 | void handleCondition(const string& content, const size_t& indexOfStart); 30 | 31 | void generateIfConfition(std::string& condition, const std::pair& localOperator); 32 | 33 | std::pair getLocalOperator(std::string& condition); 34 | 35 | std::string m_condition; 36 | std::vector m_conditionContexts; 37 | bool m_isEnd = false; 38 | bool m_inDefinition = false; 39 | }; -------------------------------------------------------------------------------- /detector_core/detectorcommon/msgrestorer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "detectorcommon.h" 5 | #include "jsonparsehelper.h" 6 | #include "detectorhelp.h" 7 | 8 | using namespace std; 9 | 10 | 11 | class DETECTOR_EXPORT MsgRestorer final 12 | { 13 | public: 14 | void restoreMsgs(const string& configPath); 15 | 16 | private: 17 | std::vector> filterPaths(const vector& filePaths); 18 | void restoreMsgToCode(const tuple& codeContent, const DetectorRuleContents& detectorRuleContents); 19 | 20 | string getMsg(const string& className, const DetectorRuleContents& detectorRuleContents); 21 | 22 | DetectorRuleContents getDetectorRuleContents(const string& configPath); 23 | 24 | string prefix = "U8("; 25 | string postfix = "\"));"; 26 | }; -------------------------------------------------------------------------------- /detector_core/detectorcommon/variabledefinition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../common/stringhelper.h" 6 | #include "detectorhelp.h" 7 | 8 | using namespace std; 9 | 10 | class DETECTOR_EXPORT VariableDefinition final { 11 | public: 12 | bool isVariableDefinition(const string& content); 13 | 14 | bool checkPoint(const string& content, const string& pointMark); 15 | 16 | bool isStatic() { return m_isStatic; } 17 | 18 | bool isConstexpr() { return m_isConstexpr; } 19 | 20 | bool isPoint() { return m_isPoint; } 21 | 22 | bool isPointToPoint() { return m_isPointToPoint; } 23 | 24 | bool isInitialized() { return m_isInitialized; } 25 | 26 | string type() { return m_type; } 27 | 28 | std::string name() { return m_name; } 29 | 30 | private: 31 | 32 | string separateOutVariableDeclaration(const string& code); 33 | bool validType(const string& code); 34 | void resetData(); 35 | 36 | string m_content; 37 | bool m_isStatic = false; 38 | bool m_isConst = false; 39 | bool m_isConstexpr = false; 40 | bool m_isPoint = false; 41 | bool m_isPointToPoint = false; 42 | bool m_isReference = false; 43 | bool m_isRvalueReference = false; 44 | bool m_isInitialized = false; 45 | string m_type; 46 | string m_name; 47 | }; -------------------------------------------------------------------------------- /detector_core/detectorcontext/detectorcontext.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectorcontext) 2 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 3 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 4 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 5 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 6 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 7 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 8 | 9 | SET(HEADERS 10 | ${RECURSE_CMAKE} 11 | ) -------------------------------------------------------------------------------- /detector_core/detectorcontext/detectorcontextcore.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/26. 3 | // 4 | #pragma once 5 | #include "detector_global.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "detectors/detector.h" 12 | 13 | using namespace std; 14 | 15 | class IPath; 16 | class IFile; 17 | class CodeFileter; 18 | class DETECTOR_EXPORT DetectorContextCore final { 19 | public: 20 | explicit DetectorContextCore(unique_ptr pFile); 21 | ~DetectorContextCore(); 22 | DetectorRuleName getDetectorName(unique_ptr detector); 23 | pair init(const DetectorRuleNames& detectorRuleNames); 24 | 25 | DetectorRuleNames getDetectorRuleNames(); 26 | 27 | bool detect(const CPPPathPair& pathPair); 28 | DetectorRuleContents getDetectorRuleContents(); 29 | DetectorErrors getDetectorErrors() { return m_detectorErrors; } 30 | 31 | private: 32 | vector> m_detectors; 33 | DetectorErrors m_detectorErrors; 34 | void detectWithDetectors(const CPPPathPair& pathPair); 35 | void detectWithDetectors(const string& filePath); 36 | unique_ptr m_pFile; 37 | unique_ptr m_codeFileter; 38 | }; 39 | -------------------------------------------------------------------------------- /detector_core/detectorcontext/multiprocessdetectorcontext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectorcontext.h" 3 | #include 4 | 5 | using namespace std; 6 | 7 | class DetectorContextCore; 8 | class DETECTOR_EXPORT MultiProcessDetectorContext final : public DetectorContext 9 | { 10 | public: 11 | MultiProcessDetectorContext(const string& resultDir, const string& appPath, const int numberOfConcurrent = std::thread::hardware_concurrency()); 12 | virtual DetectorRuleNames getDetectorRuleNames() override; 13 | protected: 14 | virtual pair init(const DetectorRuleNames& detectorRuleNames) override; 15 | virtual bool detectCore(const vector& pathPairs) override; 16 | virtual DetectorErrors getDetectorErrorsCore() override; 17 | virtual DetectorRuleContents getDetectorRuleContents() override; 18 | 19 | void detectorConcurrentCore(atomic_int& index, const vector& pathPairs, int i); 20 | int getIndex(atomic_int& index); 21 | private: 22 | vector> m_contextCores; 23 | int m_numberOfConcurrent = 0; 24 | string m_appPath; 25 | std::mutex m_mutex; 26 | }; -------------------------------------------------------------------------------- /detector_core/detectorcontext/multithreaddetectorcontext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detector_global.h" 3 | #include "detectorcontext.h" 4 | #include 5 | 6 | using namespace std; 7 | 8 | class DetectorContextCore; 9 | class DETECTOR_EXPORT MultiThreadDetectorContext final : public DetectorContext 10 | { 11 | public: 12 | explicit MultiThreadDetectorContext(const string& resultDir, const int numberOfConcurrent = std::thread::hardware_concurrency()); 13 | virtual DetectorRuleNames getDetectorRuleNames() override; 14 | protected: 15 | virtual pair init(const DetectorRuleNames& detectorRuleNames) override; 16 | virtual bool detectCore(const vector& pathPairs) override; 17 | virtual DetectorErrors getDetectorErrorsCore() override; 18 | virtual DetectorRuleContents getDetectorRuleContents() override; 19 | 20 | void detectorConcurrentCore(atomic_int& index, const vector& pathPairs, int i); 21 | int getIndex(atomic_int& index); 22 | private: 23 | vector> m_contextCores; 24 | int m_numberOfConcurrent = 0; 25 | std::mutex m_mutex; 26 | }; -------------------------------------------------------------------------------- /detector_core/detectorcontext/singlethreaddetectorcontext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detector_global.h" 3 | #include "detectorcontext.h" 4 | 5 | using namespace std; 6 | 7 | class DetectorContextCore; 8 | class DETECTOR_EXPORT SingleThreadDetectorContext final : public DetectorContext 9 | { 10 | public: 11 | explicit SingleThreadDetectorContext(const string& resultDir); 12 | virtual DetectorRuleNames getDetectorRuleNames() override; 13 | DetectorErrors detectFromApp(const string& header, const string& source, const string& ruleNamePath); 14 | protected: 15 | virtual DetectorErrors getDetectorErrorsCore() override; 16 | virtual DetectorRuleContents getDetectorRuleContents() override; 17 | virtual pair init(const DetectorRuleNames& detectorRuleNames) override; 18 | virtual bool detectCore(const vector& pathPairs) override; 19 | void writeResultToFile(const DetectorErrors& detectorErrors, const CPPPathPair& cppPathPair); 20 | private: 21 | shared_ptr m_contextCore; 22 | }; 23 | -------------------------------------------------------------------------------- /detector_core/detectors/accesscontrol/accesscontrol.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/accesscontrol) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/accesscontrol/accesscontroldetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "accesscontrolrule_membervariable.h" 5 | 6 | class AccessControlDetector final : public Detector { 7 | public: 8 | AccessControlDetector() 9 | :Detector("AccessControlDetector") 10 | { 11 | } 12 | 13 | vector getRuleNames() override 14 | { 15 | #ifdef WIN32 16 | return { 17 | GETRULENAMES(AccessControlRuleMemberVariable) 18 | }; 19 | #else 20 | return { 21 | "AccessControlRuleMemberVariable" 22 | }; 23 | #endif 24 | } 25 | }; 26 | 27 | REGISTER_CLASS(AccessControlDetector) -------------------------------------------------------------------------------- /detector_core/detectors/accesscontrol/accesscontrolrule_membervariable.cpp: -------------------------------------------------------------------------------- 1 | #include "accesscontrolrule_membervariable.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "detectorcommon/functiondefinition.h" 4 | #include "detectorcommon/classdefinition.h" 5 | #include "detectorcommon/variabledefinition.h" 6 | 7 | AccessControlRuleMemberVariable::AccessControlRuleMemberVariable() : Rule("AccessControlRuleMemberVariable") 8 | , classDefinition(make_unique()) 9 | , variableDefinition(make_unique()) 10 | { 11 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 12 | "Do not set the access to member variables to public.", 13 | U8("不要将成员变量访问权限设置成public")); 14 | } 15 | 16 | AccessControlRuleMemberVariable::~AccessControlRuleMemberVariable() = default; 17 | 18 | bool AccessControlRuleMemberVariable::detectCore(const string& code, const ErrorFile& errorFile) 19 | { 20 | if (!classDefinition->inClassDefinition(code)) 21 | { 22 | return false; 23 | } 24 | 25 | if (classDefinition->isStruct() 26 | || classDefinition->getAccessControl(code) != AccessControl::PUBLIC) 27 | { 28 | return false; 29 | } 30 | 31 | if (!variableDefinition->isVariableDefinition(code)) 32 | { 33 | return false; 34 | } 35 | 36 | storeRuleError(errorFile); 37 | return true; 38 | } 39 | 40 | void AccessControlRuleMemberVariable::resetData() 41 | { 42 | Rule::resetData(); 43 | classDefinition->resetData(); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /detector_core/detectors/accesscontrol/accesscontrolrule_membervariable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../rule.h" 4 | #include "../../common/reflecter.h" 5 | 6 | using namespace std; 7 | 8 | class ClassDefinition; 9 | class VariableDefinition; 10 | 11 | class DETECTOR_EXPORT AccessControlRuleMemberVariable final : public Rule { 12 | public: 13 | AccessControlRuleMemberVariable(); 14 | 15 | ~AccessControlRuleMemberVariable(); 16 | 17 | bool detectCore(const string& code, const ErrorFile& errorFile) override; 18 | 19 | void resetData() override; 20 | 21 | private: 22 | std::unique_ptr classDefinition; 23 | std::unique_ptr variableDefinition; 24 | }; 25 | REGISTER_CLASS(AccessControlRuleMemberVariable) 26 | -------------------------------------------------------------------------------- /detector_core/detectors/array/array.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/array) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_bufferoverflow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class ArrayRuleHelper; 7 | class DETECTOR_EXPORT ArrayRuleBufferOverflow final : public Rule { 8 | public: 9 | ArrayRuleBufferOverflow(); 10 | explicit ArrayRuleBufferOverflow(std::unique_ptr helper); 11 | 12 | ~ArrayRuleBufferOverflow(); 13 | 14 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 15 | 16 | void resetData() override; 17 | 18 | private: 19 | std::unique_ptr m_helper; 20 | std::multimap> m_arrays; 21 | }; 22 | 23 | REGISTER_CLASS(ArrayRuleBufferOverflow) 24 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_indexcheckdefectively.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | struct ArrayLen 7 | { 8 | string lenName; 9 | }; 10 | 11 | class ArrayRuleHelper; 12 | class DETECTOR_EXPORT ArrayRuleIndexCheckDefectively final : public Rule { 13 | public: 14 | ArrayRuleIndexCheckDefectively(); 15 | explicit ArrayRuleIndexCheckDefectively(std::unique_ptr helper); 16 | 17 | ~ArrayRuleIndexCheckDefectively(); 18 | 19 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 20 | 21 | void resetData() override; 22 | 23 | private: 24 | std::multimap> m_arrays; 25 | std::unique_ptr m_helper; 26 | std::string m_dataRest; 27 | std::string m_checkStatement; 28 | std::vector m_indexAndLen;; 29 | bool m_findCheck = true; 30 | }; 31 | 32 | REGISTER_CLASS(ArrayRuleIndexCheckDefectively) 33 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_indexoutofbounds.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../rule.h" 4 | #include "../../common/reflecter.h" 5 | #include "detector_global.h" 6 | #include 7 | 8 | class ArrayRuleHelper; 9 | class DETECTOR_EXPORT ArrayRuleIndexOutOfBounds final : public Rule { 10 | public: 11 | ArrayRuleIndexOutOfBounds(); 12 | explicit ArrayRuleIndexOutOfBounds(std::unique_ptr helper); 13 | 14 | ~ArrayRuleIndexOutOfBounds(); 15 | 16 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 17 | 18 | void resetData() override; 19 | 20 | private: 21 | std::unique_ptr m_helper; 22 | std::multimap m_arrays; 23 | }; 24 | 25 | REGISTER_CLASS(ArrayRuleIndexOutOfBounds) 26 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_indexoutofboundsfromfunc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class ArrayRuleHelper; 7 | class DETECTOR_EXPORT ArrayRuleIndexOutOfBoundsFromFunc final : public Rule { 8 | public: 9 | ArrayRuleIndexOutOfBoundsFromFunc(); 10 | explicit ArrayRuleIndexOutOfBoundsFromFunc(std::unique_ptr helper); 11 | 12 | ~ArrayRuleIndexOutOfBoundsFromFunc(); 13 | 14 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 15 | 16 | void resetData() override; 17 | 18 | private: 19 | std::multimap> m_arrays; 20 | std::unique_ptr m_helper; 21 | std::pair m_nameIndexPair; 22 | }; 23 | 24 | REGISTER_CLASS(ArrayRuleIndexOutOfBoundsFromFunc) 25 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_indexoutofboundsinloop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include 5 | #include "detector_global.h" 6 | 7 | class ArrayRuleHelper; 8 | class DETECTOR_EXPORT ArrayRuleIndexOutOfBoundsInLoop final : public Rule { 9 | public: 10 | ArrayRuleIndexOutOfBoundsInLoop(); 11 | explicit ArrayRuleIndexOutOfBoundsInLoop(std::unique_ptr helper); 12 | ~ArrayRuleIndexOutOfBoundsInLoop(); 13 | 14 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 15 | 16 | void resetData() override; 17 | 18 | private: 19 | std::unique_ptr m_helper; 20 | std::multimap> m_arrays; 21 | std::string m_maxLenInLoop; 22 | }; 23 | 24 | REGISTER_CLASS(ArrayRuleIndexOutOfBoundsInLoop) 25 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_indexusedbeforecheck.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | #include 6 | 7 | class ArrayRuleHelper; 8 | class DETECTOR_EXPORT ArrayRuleIndexUsedBeforeCheck final : public Rule { 9 | public: 10 | ArrayRuleIndexUsedBeforeCheck(); 11 | explicit ArrayRuleIndexUsedBeforeCheck(std::unique_ptr helper); 12 | ~ArrayRuleIndexUsedBeforeCheck(); 13 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 14 | 15 | void resetData() override; 16 | 17 | private: 18 | std::unique_ptr m_helper; 19 | std::string m_data; 20 | std::string m_target; 21 | bool m_needCheck = true; 22 | }; 23 | 24 | REGISTER_CLASS(ArrayRuleIndexUsedBeforeCheck) 25 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_memsetzerobyte.cpp: -------------------------------------------------------------------------------- 1 | #include "arrayrule_memsetzerobyte.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | ArrayRuleMemsetZeroByte::ArrayRuleMemsetZeroByte() : Rule("ArrayRuleMemsetZeroByte") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Error, m_name, 8 | "The third parameter of memset is the number of bytes to be formated and should not be 0.", 9 | U8("memset第三个参数是要格式化的字节数,不应该为0")); 10 | } 11 | 12 | bool ArrayRuleMemsetZeroByte::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | //if (auto ret = DetectorHelper::check(code, "memset\s*\\(.+0\\s*\\)"); !ret.empty()) 15 | if (StringHelper(code).findIndexOfCode("memset(") == string::npos 16 | || code.find("0)") == string::npos) 17 | { 18 | return false; 19 | } 20 | storeRuleError(errorFile); 21 | return true; 22 | } 23 | 24 | void ArrayRuleMemsetZeroByte::resetData() 25 | { 26 | Rule::resetData(); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrule_memsetzerobyte.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ArrayRuleMemsetZeroByte final : public Rule { 7 | public: 8 | ArrayRuleMemsetZeroByte(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(ArrayRuleMemsetZeroByte) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/array/arrayrulehelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "detector_global.h" 5 | using namespace std; 6 | 7 | class DETECTOR_EXPORT ArrayRuleHelper final 8 | { 9 | public: 10 | void makeData(const std::string& filePath); 11 | int getIndexWithString(const std::string& var, const std::string& filePath); 12 | 13 | pair getIndex(const std::string& arrayLen, const std::string& filePath); 14 | 15 | std::string getData() 16 | { 17 | return m_data; 18 | } 19 | 20 | void setData(const std::string& data) 21 | { 22 | m_data = data; 23 | } 24 | 25 | void clear() 26 | { 27 | m_data.clear(); 28 | } 29 | 30 | private: 31 | std::string m_data; 32 | }; 33 | -------------------------------------------------------------------------------- /detector_core/detectors/class/class.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/class) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/class/classdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "classrule_pairofconstructorandassignment.h" 5 | 6 | class ClassDetector final: public Detector { 7 | public: 8 | ClassDetector() 9 | :Detector("ClassDetector") 10 | { 11 | } 12 | 13 | vector getRuleNames() override 14 | { 15 | #ifdef WIN32 16 | return { 17 | GETRULENAMES(VariableRulePairOfConstructorAndAssignment) 18 | }; 19 | #else 20 | return { 21 | "VariableRulePairOfConstructorAndAssignment" 22 | }; 23 | #endif 24 | } 25 | }; 26 | 27 | REGISTER_CLASS(ClassDetector) -------------------------------------------------------------------------------- /detector_core/detectors/class/classrule_pairofconstructorandassignment.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | using namespace std; 6 | 7 | class FunctionDefinition; 8 | class ClassDefinition; 9 | 10 | struct DETECTOR_EXPORT ErrorFileWithType 11 | { 12 | bool isCopy = false; 13 | bool isMove = false; 14 | ErrorFile errorFile; 15 | void resetData() 16 | { 17 | isCopy = false; 18 | isMove = false; 19 | errorFile.resetData(); 20 | } 21 | }; 22 | 23 | class DETECTOR_EXPORT VariableRulePairOfConstructorAndAssignment final : public Rule{ 24 | public: 25 | VariableRulePairOfConstructorAndAssignment(); 26 | ~VariableRulePairOfConstructorAndAssignment(); 27 | bool detectCore(const string & code, const ErrorFile & errorFile) override; 28 | void resetData() override; 29 | bool calculateType(const string& code, const string& className, ErrorFileWithType& errorFileWithTpe); 30 | private: 31 | unique_ptr m_classDefinition; 32 | ErrorFileWithType m_constructor; 33 | ErrorFileWithType m_assignment; 34 | }; 35 | REGISTER_CLASS(VariableRulePairOfConstructorAndAssignment) 36 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confused.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/confused) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_assignmentinassertorif.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | #include "detector_global.h" 6 | 7 | class DETECTOR_EXPORT ConfusedRuleAssignmentInAssertOrIf final : public Rule { 8 | public: 9 | ConfusedRuleAssignmentInAssertOrIf(); 10 | 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | std::string makeCondition(const std::string& code, const std::string& prefix); 17 | bool isAssignment(const string& code); 18 | std::smatch checkOperator(const std::string& code, const std::string& arithmetic); 19 | }; 20 | 21 | REGISTER_CLASS(ConfusedRuleAssignmentInAssertOrIf) 22 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_break.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class BraceHelper; 7 | class DETECTOR_EXPORT ConfusedRuleBreak final : public Rule { 8 | public: 9 | ConfusedRuleBreak(); 10 | ~ConfusedRuleBreak(); 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | std::unique_ptr m_braceHelper; 17 | std::string m_indexOfLoop; 18 | std::string::size_type m_indexOfSwitch = string::npos; 19 | int m_countOfBraceInSwitch = 0; 20 | }; 21 | 22 | REGISTER_CLASS(ConfusedRuleBreak) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_casewithoutbreak.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleCaseWithoutBreak final : public Rule { 7 | public: 8 | ConfusedRuleCaseWithoutBreak(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::vector m_cases; 16 | bool m_inSwitch = false; 17 | bool m_inCase = false; 18 | std::vector> m_switchState; 19 | }; 20 | 21 | REGISTER_CLASS(ConfusedRuleCaseWithoutBreak) 22 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_conditionrepeat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class IfDefinition; 7 | class ConditionContext; 8 | class DETECTOR_EXPORT ConfusedRuleConditionRepeat final : public Rule { 9 | public: 10 | ConfusedRuleConditionRepeat(); 11 | ~ConfusedRuleConditionRepeat(); 12 | 13 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 14 | 15 | void resetData() override; 16 | 17 | private: 18 | bool checkOperand(const std::string& condition, const std::string& operand); 19 | bool assignToOperand(const string& code, const string& operand); 20 | std::unique_ptr m_ifDefinition; 21 | std::vector m_conditionContexts; 22 | 23 | std::map m_conditions; 24 | }; 25 | 26 | REGISTER_CLASS(ConfusedRuleConditionRepeat) 27 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_constructor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleConstructor final : public Rule { 7 | public: 8 | ConfusedRuleConstructor(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_className; 16 | }; 17 | 18 | REGISTER_CLASS(ConfusedRuleConstructor) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_diffvariablewithinitandcondition.cpp: -------------------------------------------------------------------------------- 1 | #include "confusedrule_diffvariablewithinitandcondition.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | ConfusedRuleDiffVariableWithInitAndCondition::ConfusedRuleDiffVariableWithInitAndCondition() 5 | : Rule("ConfusedRuleDiffVariableWithInitAndCondition") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 8 | "In the judgment condition, the initialized variable is inconsistent with the comparison variable, "\ 9 | "please confirm that it is correct.", 10 | U8("在判断条件中,初始化的变量与比较变量不一致,请确认是否正确")); 11 | } 12 | 13 | bool ConfusedRuleDiffVariableWithInitAndCondition::detectCore(const string& code, const ErrorFile& errorFile) 14 | { 15 | StringHelper helper(code); 16 | if (!helper.findCode("if") 17 | && !helper.findCode(";")) 18 | { 19 | return false; 20 | } 21 | 22 | if (auto ret = DetectorHelper::check(code, R"delimiter((\w+)\s*=.+;(.+)\)$)delimiter"); !ret.empty()) 23 | { 24 | if (!StringHelper(ret[2]).findCode(ret[1])) 25 | { 26 | storeRuleError(errorFile); 27 | return true; 28 | } 29 | } 30 | 31 | return false; 32 | } 33 | 34 | void ConfusedRuleDiffVariableWithInitAndCondition::resetData() 35 | { 36 | Rule::resetData(); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_diffvariablewithinitandcondition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleDiffVariableWithInitAndCondition final: public Rule { 7 | public: 8 | ConfusedRuleDiffVariableWithInitAndCondition(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(ConfusedRuleDiffVariableWithInitAndCondition) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_nothandlefuncreturn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | #include "detector_global.h" 6 | 7 | class FunctionDefinition; 8 | class DETECTOR_EXPORT ConfusedRuleNotHandleFuncReturn final : public Rule { 9 | public: 10 | ConfusedRuleNotHandleFuncReturn(); 11 | ~ConfusedRuleNotHandleFuncReturn(); 12 | 13 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 14 | 15 | void resetData() override; 16 | 17 | private: 18 | std::unique_ptr m_functionDefinition; 19 | std::set m_funcsWithReturn; 20 | }; 21 | 22 | REGISTER_CLASS(ConfusedRuleNotHandleFuncReturn) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_priority.cpp: -------------------------------------------------------------------------------- 1 | #include "confusedrule_priority.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | ConfusedRulePriority::ConfusedRulePriority() : Rule("ConfusedRulePriority") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 8 | "Confusing priority. The priority of + is higher than <<.", 9 | U8("令人迷惑的优先级,+优先级高于<<")); 10 | } 11 | 12 | bool ConfusedRulePriority::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (code.find("<<") == string::npos) 15 | { 16 | return false; 17 | } 18 | if (auto ret = DetectorHelper::check(code, "\\w+\\s*<<\\s*\\w+\\s*\\+\\s*\\w+"); !ret.empty()) 19 | { 20 | //check "int iTemp = 10 << iMax + 3;" 21 | storeRuleError(errorFile); 22 | return true; 23 | } 24 | return false; 25 | } 26 | 27 | void ConfusedRulePriority::resetData() 28 | { 29 | Rule::resetData(); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_priority.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRulePriority final : public Rule { 7 | public: 8 | ConfusedRulePriority(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(ConfusedRulePriority) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_prioritywithassignmentandcompare.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class IfDefinition; 7 | class DETECTOR_EXPORT ConfusedRulePriorityWithAssignmentAndCompare final : public Rule { 8 | public: 9 | ConfusedRulePriorityWithAssignmentAndCompare(); 10 | ~ConfusedRulePriorityWithAssignmentAndCompare(); 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | void resetData() override; 13 | 14 | private: 15 | std::unique_ptr m_ifDefinition; 16 | }; 17 | 18 | REGISTER_CLASS(ConfusedRulePriorityWithAssignmentAndCompare) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_returnbool.cpp: -------------------------------------------------------------------------------- 1 | #include "confusedrule_returnbool.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | ConfusedRuleReturnBool::ConfusedRuleReturnBool() : Rule("ConfusedRuleReturnBool") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Error, m_name, 8 | "Confusing function return value. The return value type is bool, but the return statement is a different type.", 9 | U8("令人迷惑的函数返回值,返回值类型是bool,但是return语句是其他类型")); 10 | } 11 | 12 | bool ConfusedRuleReturnBool::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (auto ret = DetectorHelper::getReturnTypeOfFunctionDefinition(code); !ret.empty()) 15 | { 16 | m_returnTypeIsBool = ret == "bool"; 17 | return false; 18 | } 19 | 20 | if (m_returnTypeIsBool 21 | && !DetectorHelper::check(code, "return\\s*\\d+\\s*;").empty()) 22 | { 23 | storeRuleError(errorFile); 24 | return true; 25 | } 26 | 27 | return false; 28 | } 29 | 30 | void ConfusedRuleReturnBool::resetData() 31 | { 32 | Rule::resetData(); 33 | m_returnTypeIsBool = false; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_returnbool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleReturnBool final : public Rule { 7 | public: 8 | ConfusedRuleReturnBool(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | bool m_returnTypeIsBool = false; 16 | }; 17 | 18 | REGISTER_CLASS(ConfusedRuleReturnBool) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_semicolon.cpp: -------------------------------------------------------------------------------- 1 | #include "confusedrule_semicolon.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | ConfusedRuleSemicolon::ConfusedRuleSemicolon() : Rule("ConfusedRuleSemicolon") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 8 | "Confusing. It is possibly mistyped.", 9 | U8("令人迷惑的;,可能是误输入的")); 10 | } 11 | 12 | bool ConfusedRuleSemicolon::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (code.find("if") == string::npos 15 | && code.find("for") == string::npos 16 | && code.find("while") == string::npos) 17 | { 18 | return false; 19 | } 20 | 21 | if (auto ret = DetectorHelper::check(code, "\\s+(if|for|while)\\s*\\(.*\\);[\\n\\s]*$"); !ret.empty()) 22 | { 23 | //check "if (iMax > 0 && iMax != 3);" 24 | //"[\\n\\s]*$" is necessary to prevent a match to "for(iter = ivec.begin();iter!=ivec.end();iter++)" 25 | if (code.find("while") != string::npos) 26 | { 27 | //filter do while 28 | auto prefix = ret.prefix().str(); 29 | if (!prefix.empty() 30 | && prefix[prefix.size() - 1] == '}') 31 | { 32 | return false; 33 | } 34 | } 35 | storeRuleError(errorFile); 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | void ConfusedRuleSemicolon::resetData() 43 | { 44 | Rule::resetData(); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_semicolon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleSemicolon final : public Rule { 7 | public: 8 | ConfusedRuleSemicolon(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | }; 16 | 17 | REGISTER_CLASS(ConfusedRuleSemicolon) 18 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_statementOutsideOfcase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleStatementOutsideOfCase final : public Rule { 7 | public: 8 | ConfusedRuleStatementOutsideOfCase(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | bool m_inSwitch = false; 16 | bool m_inCase = false; 17 | }; 18 | 19 | REGISTER_CLASS(ConfusedRuleStatementOutsideOfCase) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/confused/confusedrule_switchwihtoutdefault.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT ConfusedRuleSwitchWithoutDefault final: public Rule { 7 | public: 8 | ConfusedRuleSwitchWithoutDefault(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::vector m_errorFiles; 16 | bool m_inSwitch = false; 17 | }; 18 | 19 | REGISTER_CLASS(ConfusedRuleSwitchWithoutDefault) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/detectors.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors) 2 | 3 | include(detectors/accesscontrol/accesscontrol.cmake) 4 | include(detectors/array/array.cmake) 5 | include(detectors/confused/confused.cmake) 6 | include(detectors/dynamic/dynamic.cmake) 7 | include(detectors/inline/inline.cmake) 8 | include(detectors/iterator/iterator.cmake) 9 | include(detectors/lambda/lambda.cmake) 10 | include(detectors/logic/logic.cmake) 11 | include(detectors/loop/loop.cmake) 12 | include(detectors/memleak/memleak.cmake) 13 | include(detectors/operation/operation.cmake) 14 | include(detectors/pointer/pointer.cmake) 15 | include(detectors/singleton/singleton.cmake) 16 | include(detectors/sizeof/sizeof.cmake) 17 | include(detectors/uninit/uninit.cmake) 18 | include(detectors/variable/variable.cmake) 19 | include(detectors/class/class.cmake) 20 | 21 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 22 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 23 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 24 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 25 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 26 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 27 | 28 | SET(HEADERS 29 | ${RECURSE_CMAKE} 30 | ) -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamic.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/dynamic) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamicdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "dynamicrule_localstatic.h" 4 | #include "dynamicrule_inline.h" 5 | 6 | class DynamicDetector final : public Detector { 7 | public: 8 | DynamicDetector() 9 | :Detector("DynamicDetector") 10 | { 11 | } 12 | 13 | vector getRuleNames() override 14 | { 15 | #ifdef WIN32 16 | return { 17 | GETRULENAMES(DynamicRuleLocalStatic), 18 | GETRULENAMES(DynamicRuleInline) 19 | }; 20 | #else 21 | return { 22 | "DynamicRuleLocalStatic", 23 | "DynamicRuleInline" 24 | }; 25 | #endif 26 | } 27 | }; 28 | 29 | REGISTER_CLASS(DynamicDetector) -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamicrule_inline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | struct ErrorFileWithClass { 7 | std::vector classNames; 8 | ErrorFile errorFile; 9 | }; 10 | 11 | class DETECTOR_EXPORT DynamicRuleInline final : public Rule { 12 | public: 13 | DynamicRuleInline(); 14 | 15 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 16 | 17 | bool findClassDomain(const std::string& code, const std::vector& classNames); 18 | 19 | void resetData() override; 20 | 21 | private: 22 | map m_errorFileWithClass; 23 | }; 24 | 25 | REGISTER_CLASS(DynamicRuleInline) 26 | -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamicrule_localstatic.cpp: -------------------------------------------------------------------------------- 1 | #include "dynamicrule_localstatic.h" 2 | #include "dynamicrulehelper.h" 3 | #include "detectorcommon/detectorhelp.h" 4 | 5 | DynamicRuleLocalStatic::DynamicRuleLocalStatic() : Rule("DynamicRuleLocalStatic") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Error, m_name, 8 | "Local static variables may be used outside the dynamic library. When Android5.1 accesses across so, different so will instantiate an independent singleton, resulting in multiple instances in the system.", 9 | U8("可能在动态库外面使用的局部静态变量, Android5.1跨so访问时,不同so会实例化一份独立的单例,导致系统存在多实例")); 10 | } 11 | 12 | bool DynamicRuleLocalStatic::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (m_className.empty()) 15 | { 16 | auto ret = DynamicRuleHelper::findExportedClass(code); 17 | if (!ret.first.empty()) 18 | { 19 | m_className = ret.first; 20 | } 21 | return false; 22 | } 23 | 24 | //check "static Test2 test; 25 | if (code.find("static " + m_className + " ") == string::npos) 26 | //if (DetectorHelper::check(code, "static\\s+" + m_className + "\\s+(\\w+);").empty()) 27 | { 28 | return false; 29 | } 30 | m_className.clear(); 31 | storeRuleError(errorFile); 32 | return true; 33 | } 34 | 35 | void DynamicRuleLocalStatic::resetData() 36 | { 37 | Rule::resetData(); 38 | m_className.clear(); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamicrule_localstatic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT DynamicRuleLocalStatic final : public Rule { 7 | public: 8 | DynamicRuleLocalStatic(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_className; 16 | }; 17 | 18 | REGISTER_CLASS(DynamicRuleLocalStatic) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamicrulehelper.cpp: -------------------------------------------------------------------------------- 1 | #include "dynamicrulehelper.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | std::pair DynamicRuleHelper::findExportedClass(const std::string& code) 5 | { 6 | auto ret = DetectorHelper::checkExportClass(code); 7 | if (ret.empty()) 8 | { 9 | return { "", "" }; 10 | } 11 | 12 | string subClass = ret[2]; 13 | if (subClass == "final") 14 | { 15 | return { "", "" }; 16 | } 17 | string baseClass = ret[ret.size() - 1]; 18 | return { subClass, baseClass }; 19 | } 20 | 21 | bool DynamicRuleHelper::findClassDomain(const std::string& code, const string& className) 22 | { 23 | return code.find(className + "::") != string::npos; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /detector_core/detectors/dynamic/dynamicrulehelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class DynamicRuleHelper final 6 | { 7 | public: 8 | static std::pair findExportedClass(const std::string& code); 9 | 10 | static bool findClassDomain(const std::string& code, const std::string& className); 11 | }; -------------------------------------------------------------------------------- /detector_core/detectors/idetector.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/26. 3 | // 4 | #pragma once 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class DETECTOR_EXPORT IDetector { 11 | public: 12 | explicit IDetector(const string& name) :m_name(name) {} 13 | virtual ~IDetector() {} 14 | virtual bool detect(const string& content, const string& path) = 0; 15 | virtual bool detect(const string& content, const ErrorFile& errorFile) = 0; 16 | virtual void resetData() {} 17 | string getName() const { return m_name; } 18 | protected: 19 | string m_name; 20 | }; 21 | -------------------------------------------------------------------------------- /detector_core/detectors/inline/inline.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/inline) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/inline/inlinedetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "inlinerule_tenlines.h" 4 | #include "inlinerule_specialclassmethod.h" 5 | #include "inlinerule_complexfunction.h" 6 | #include "inlinerule_recursion.h" 7 | 8 | //内联规则详见: 9 | // Google 开源项目风格指南:1.4. 内联函数:https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/headers/ 10 | // 编码规范,内联:https://www.jianshu.com/p/d08be89ee6af 11 | class InlineDetector final : public Detector { 12 | public: 13 | InlineDetector() 14 | :Detector("InlineDetector") 15 | { 16 | } 17 | 18 | vector getRuleNames() override 19 | { 20 | #ifdef WIN32 21 | return { 22 | GETRULENAMES(InlineRuleTenLines), 23 | GETRULENAMES(InlineRuleSpecialClassMethod), 24 | GETRULENAMES(InlineRuleComplexFunction), 25 | GETRULENAMES(InlineRuleRecursion) 26 | }; 27 | #else 28 | return { 29 | "InlineRuleTenLines", 30 | "InlineRuleSpecialClassMethod", 31 | "InlineRuleComplexFunction", 32 | "InlineRuleRecursion" 33 | }; 34 | #endif 35 | } 36 | }; 37 | 38 | REGISTER_CLASS(InlineDetector) -------------------------------------------------------------------------------- /detector_core/detectors/inline/inlinerule_complexfunction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | 7 | class DETECTOR_EXPORT InlineRuleComplexFunction final : public Rule { 8 | public: 9 | InlineRuleComplexFunction(); 10 | 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | bool m_isInline = false; 17 | int m_lineOfFunction = 0; 18 | std::string m_spacesBeforeFunction; 19 | }; 20 | 21 | REGISTER_CLASS(InlineRuleComplexFunction) 22 | -------------------------------------------------------------------------------- /detector_core/detectors/inline/inlinerule_recursion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class BraceHelper; 7 | class DETECTOR_EXPORT InlineRuleRecursion final : public Rule { 8 | public: 9 | InlineRuleRecursion(); 10 | 11 | ~InlineRuleRecursion(); 12 | 13 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 14 | 15 | void resetData() override; 16 | 17 | private: 18 | unique_ptr braceHelper; 19 | bool m_isInline = false; 20 | int m_lineOfFunction = 0; 21 | string m_nameOfFunctionDefinition; 22 | }; 23 | 24 | REGISTER_CLASS(InlineRuleRecursion) 25 | -------------------------------------------------------------------------------- /detector_core/detectors/inline/inlinerule_specialclassmethod.cpp: -------------------------------------------------------------------------------- 1 | #include "inlinerule_specialclassmethod.h" 2 | #include "detectorcommon/classdefinition.h" 3 | 4 | InlineRuleSpecialClassMethod::InlineRuleSpecialClassMethod() : Rule("InlineRuleSpecialClassMethod") 5 | , classDefinition(make_unique()) 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Suggest, m_name, 8 | "Do not make special class methods inline: constructor, destructor, virtual function.", 9 | U8("不要将特殊的类方法设置为内联:构造函数,析构函数,虚函数")); 10 | } 11 | 12 | InlineRuleSpecialClassMethod::~InlineRuleSpecialClassMethod() = default; 13 | 14 | bool InlineRuleSpecialClassMethod::detectCore(const string& code, const ErrorFile& errorFile) 15 | { 16 | if (errorFile.path.find(".h") == string::npos) 17 | { 18 | return false; 19 | } 20 | 21 | if (!classDefinition->inClassDefinition(code)) 22 | { 23 | return false; 24 | } 25 | 26 | if (code.find("inline ") == string::npos) 27 | { 28 | return false; 29 | } 30 | 31 | if (!classDefinition->isConstructor(code).first 32 | && !classDefinition->isDestructor(code).first 33 | && !classDefinition->isVirtual(code)) 34 | { 35 | return false; 36 | } 37 | 38 | storeRuleError(errorFile); 39 | return true; 40 | } 41 | 42 | void InlineRuleSpecialClassMethod::resetData() 43 | { 44 | classDefinition->resetData(); 45 | Rule::resetData(); 46 | } 47 | -------------------------------------------------------------------------------- /detector_core/detectors/inline/inlinerule_specialclassmethod.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectorcommon/bracehelper.h" 3 | #include "../rule.h" 4 | #include "detectorcommon/detectorhelp.h" 5 | #include "common/reflecter.h" 6 | 7 | class ClassDefinition; 8 | 9 | class DETECTOR_EXPORT InlineRuleSpecialClassMethod final : public Rule { 10 | public: 11 | InlineRuleSpecialClassMethod(); 12 | 13 | ~InlineRuleSpecialClassMethod(); 14 | 15 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 16 | 17 | void resetData() override; 18 | 19 | private: 20 | std::unique_ptr classDefinition; 21 | }; 22 | 23 | REGISTER_CLASS(InlineRuleSpecialClassMethod) 24 | -------------------------------------------------------------------------------- /detector_core/detectors/inline/inlinerule_tenlines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class BraceHelper; 7 | class DETECTOR_EXPORT InlineRuleTenLines final : public Rule { 8 | public: 9 | InlineRuleTenLines(); 10 | 11 | ~InlineRuleTenLines(); 12 | 13 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 14 | void resetData() override; 15 | 16 | private: 17 | std::unique_ptr braceHelper; 18 | bool m_isInline = false; 19 | int m_lineOfFunction = 0; 20 | }; 21 | 22 | REGISTER_CLASS(InlineRuleTenLines) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/iterator/iterator.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/iterator) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/iterator/iteratordetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "iteratorrule_outofbound.h" 5 | #include "iteratorrule_invaliddereference.h" 6 | 7 | class IteratorDetector final : public Detector { 8 | public: 9 | IteratorDetector() 10 | :Detector("IteratorDetector") 11 | { 12 | } 13 | 14 | vector getRuleNames() override 15 | { 16 | #ifdef WIN32 17 | return { 18 | GETRULENAMES(IteratorRuleOutOfBound), 19 | GETRULENAMES(IteratorRuleInvalidDereference) 20 | }; 21 | #else 22 | return { 23 | "IteratorRuleOutOfBound", 24 | "IteratorRuleInvalidDereference" 25 | }; 26 | #endif 27 | } 28 | }; 29 | 30 | REGISTER_CLASS(IteratorDetector) -------------------------------------------------------------------------------- /detector_core/detectors/iterator/iteratorrule_invaliddereference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT IteratorRuleInvalidDereference final : public Rule { 7 | public: 8 | IteratorRuleInvalidDereference(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | bool checkReference(const string& code, const ErrorFile& errorFile); 13 | 14 | void resetData() override; 15 | 16 | private: 17 | std::string m_iteratorName; 18 | std::string m_spaces; 19 | }; 20 | 21 | REGISTER_CLASS(IteratorRuleInvalidDereference) 22 | -------------------------------------------------------------------------------- /detector_core/detectors/iterator/iteratorrule_outofbound.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT IteratorRuleOutOfBound final : public Rule { 7 | public: 8 | IteratorRuleOutOfBound(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_sizeVariable; 16 | }; 17 | 18 | REGISTER_CLASS(IteratorRuleOutOfBound) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/lambda/lambda.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/lambda) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/lambda/lambdadetector.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/26. 3 | // 4 | 5 | #pragma once 6 | #include "detectors/detector.h" 7 | #include "lambdarule_catchbyreference.h" 8 | #include "../../common/reflecter.h" 9 | 10 | class LambdaDetector final : public Detector { 11 | public: 12 | LambdaDetector() 13 | :Detector("LambdaDetector") 14 | { 15 | } 16 | 17 | vector getRuleNames() override 18 | { 19 | #ifdef WIN32 20 | return { 21 | GETRULENAMES(LambdaRuleCatchByReference) 22 | }; 23 | #else 24 | return { 25 | "LambdaRuleCatchByReference" 26 | }; 27 | #endif 28 | } 29 | }; 30 | 31 | REGISTER_CLASS(LambdaDetector) -------------------------------------------------------------------------------- /detector_core/detectors/lambda/lambdarule_catchbyreference.cpp: -------------------------------------------------------------------------------- 1 | #include "lambdarule_catchbyreference.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | LambdaRuleCatchByReference::LambdaRuleCatchByReference() : Rule("LambdaRuleCatchByReference") 5 | { 6 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 7 | "Lambda expressions should not capture all variables by reference.", 8 | U8("Lambda expressions cannot capture all variables by reference.")); 9 | } 10 | 11 | bool LambdaRuleCatchByReference::detectCore(const string& code, const ErrorFile& errorFile) 12 | { 13 | if (code.find("[") == string::npos 14 | || code.find("&") == string::npos) 15 | { 16 | return false; 17 | } 18 | 19 | auto ret = DetectorHelper::check(code, R"delimiter(\[.*&(.*)\]\()delimiter"); 20 | if (ret.empty()) 21 | { 22 | return false; 23 | } 24 | 25 | auto capturedVar = ret[1].str(); 26 | if (!capturedVar.empty() 27 | && !DetectorHelper::check(ret[1], "^\\s*(_\\w)*").empty()) 28 | { 29 | return false; 30 | } 31 | //check "void fontManger(startTransferProgram, [&](const int errorCode, const std::string& result) {" 32 | storeRuleError(errorFile); 33 | return true; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /detector_core/detectors/lambda/lambdarule_catchbyreference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LambdaRuleCatchByReference final : public Rule { 7 | public: 8 | LambdaRuleCatchByReference(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | }; 12 | 13 | REGISTER_CLASS(LambdaRuleCatchByReference) 14 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logic.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/logic) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "logicrule_basevalue.h" 5 | #include "logicrule_incorrectoperation.h" 6 | #include "logicrule_assignself.h" 7 | #include "logicrule_stringfind.h" 8 | #include "logicrule_expressionrepetition.h" 9 | #include "detector_global.h" 10 | 11 | class DETECTOR_EXPORT LogicDetector final : public Detector { 12 | public: 13 | LogicDetector() 14 | :Detector("LogicDetector") 15 | { 16 | } 17 | 18 | vector getRuleNames() override 19 | { 20 | #ifdef WIN32 21 | return { 22 | GETRULENAMES(LogicRuleBaseValue), 23 | GETRULENAMES(LogicRuleIncorrectOperation), 24 | GETRULENAMES(LogicRuleAssignSelf), 25 | GETRULENAMES(LogicRuleStringFind), 26 | GETRULENAMES(LogicRuleExpressionRepetition) 27 | }; 28 | #else 29 | return { 30 | "LogicRuleBaseValue", 31 | "LogicRuleIncorrectOperation", 32 | "LogicRuleAssignSelf", 33 | "LogicRuleStringFind", 34 | "LogicRuleExpressionRepetition" 35 | }; 36 | #endif 37 | } 38 | }; 39 | 40 | REGISTER_CLASS(LogicDetector) -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_assignself.cpp: -------------------------------------------------------------------------------- 1 | #include "logicrule_assignself.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | LogicRuleAssignSelf::LogicRuleAssignSelf() : Rule("LogicRuleAssignSelf") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 8 | "Assign a value to itself. Please make sure whether the value you entered is wrong.", 9 | U8("给自己赋值,请确认是否写错")); 10 | } 11 | 12 | bool LogicRuleAssignSelf::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (code.find("=") == string::npos 15 | || code.find("==") != string::npos) 16 | { 17 | return false; 18 | } 19 | 20 | auto codeTmp = StringHelper(code).removeSpaceAndTab(); 21 | auto index = codeTmp.find("="); 22 | auto left = codeTmp.substr(0, index); 23 | auto rightStart = index + strlen("="); 24 | auto rightEnd = codeTmp.size() - rightStart - 1; 25 | auto right = codeTmp.substr(rightStart, rightEnd); 26 | if (left != right) 27 | { 28 | return false; 29 | } 30 | 31 | storeRuleError(errorFile); 32 | return true; 33 | } 34 | 35 | void LogicRuleAssignSelf::resetData() 36 | { 37 | Rule::resetData(); 38 | } 39 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_assignself.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LogicRuleAssignSelf final : public Rule { 7 | public: 8 | LogicRuleAssignSelf(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(LogicRuleAssignSelf) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_basevalue.cpp: -------------------------------------------------------------------------------- 1 | #include "logicrule_basevalue.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | LogicRuleBaseValue::LogicRuleBaseValue() : Rule("LogicRuleBaseValue") { 6 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 7 | "Judgment condition that is always true or false", 8 | U8("总是为真或为假的判断条件")); 9 | } 10 | 11 | bool LogicRuleBaseValue::detectCore(const string &code, const ErrorFile &errorFile) { 12 | if (code.find("if (1)") != string::npos 13 | || code.find("if (0)") != string::npos 14 | || code.find("if (true)") != string::npos 15 | || code.find("if (false)") != string::npos 16 | ) 17 | { 18 | storeRuleError(errorFile); 19 | return true; 20 | } 21 | return false; 22 | } 23 | 24 | void LogicRuleBaseValue::resetData() { 25 | Rule::resetData(); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_basevalue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LogicRuleBaseValue final : public Rule { 7 | public: 8 | LogicRuleBaseValue(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(LogicRuleBaseValue) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_expressionrepetition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LogicRuleExpressionRepetition final : public Rule { 7 | public: 8 | LogicRuleExpressionRepetition(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(LogicRuleExpressionRepetition) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_incorrectoperation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LogicRuleIncorrectOperation final : public Rule { 7 | public: 8 | LogicRuleIncorrectOperation(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(LogicRuleIncorrectOperation) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/logic/logicrule_stringfind.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LogicRuleStringFind final : public Rule { 7 | public: 8 | LogicRuleStringFind(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | bool checkValid(const std::string& code); 16 | }; 17 | 18 | REGISTER_CLASS(LogicRuleStringFind) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/loop.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/loop) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/loop/loopdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "looprule_wrongvariable.h" 5 | #include "looprule_outofbounds.h" 6 | #include "looprule_suggestauto.h" 7 | #include "looprule_wrongstepdirection.h" 8 | 9 | class LoopDetector final : public Detector { 10 | public: 11 | LoopDetector() 12 | :Detector("LoopDetector") 13 | { 14 | } 15 | 16 | vector getRuleNames() override 17 | { 18 | #ifdef WIN32 19 | return { 20 | GETRULENAMES(LoopRuleWrongVariable), 21 | GETRULENAMES(LoopRuleOutOfBounds), 22 | GETRULENAMES(LoopRuleSuggestauto), 23 | GETRULENAMES(LoopRuleWrongStepDirection) 24 | }; 25 | #else 26 | return { 27 | "LoopRuleWrongVariable", 28 | "LoopRuleOutOfBounds", 29 | "LoopRuleSuggestauto", 30 | "LoopRuleWrongStepDirection" 31 | }; 32 | #endif 33 | } 34 | }; 35 | 36 | REGISTER_CLASS(LoopDetector) -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | using VariableInFor = pair>; 6 | class DETECTOR_EXPORT LoopRuleHelper final { 7 | public: 8 | static bool findNotAutoFromFor(const std::string& code); 9 | 10 | static VariableInFor getVariablesFromFor(const std::string& code); 11 | 12 | static bool isValid(const std::string& code, std::string& variable); 13 | }; 14 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_outofbounds.cpp: -------------------------------------------------------------------------------- 1 | #include "looprule_outofbounds.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | #include "looprule_helper.h" 5 | 6 | LoopRuleOutOfBounds::LoopRuleOutOfBounds() : Rule("LoopRuleOutOfBounds") 7 | { 8 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 9 | "The iteration variables in for loop are modified and may be out of range, resulting in an error to the loop.", 10 | U8("for循环中的迭代变量被修改,可能超过范围,导致循环出错")); 11 | } 12 | 13 | bool LoopRuleOutOfBounds::detectCore(const string& code, const ErrorFile& errorFile) 14 | { 15 | if (!LoopRuleHelper::isValid(code, m_loopVariable)) 16 | { 17 | return false; 18 | } 19 | 20 | if (m_loopVariable.empty()) 21 | { 22 | return false; 23 | } 24 | 25 | auto codeTmp = StringHelper(code).removeSpaceAndTab(); 26 | auto index = codeTmp.find(m_loopVariable); 27 | if (index == string::npos) 28 | { 29 | return false; 30 | } 31 | 32 | auto border = "([\\+\\-]*)"; 33 | auto regValue = border + m_loopVariable + border; 34 | if (auto ret = DetectorHelper::check(codeTmp, regValue); !ret.empty()) 35 | { 36 | if (!ret[1].str().empty() 37 | || !ret[2].str().empty()) 38 | { 39 | storeRuleError(errorFile); 40 | return true; 41 | } 42 | } 43 | 44 | return false; 45 | } 46 | 47 | void LoopRuleOutOfBounds::resetData() 48 | { 49 | Rule::resetData(); 50 | m_loopVariable.clear(); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_outofbounds.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LoopRuleOutOfBounds final : public Rule { 7 | public: 8 | LoopRuleOutOfBounds(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_loopVariable; 16 | }; 17 | 18 | REGISTER_CLASS(LoopRuleOutOfBounds) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_suggestauto.cpp: -------------------------------------------------------------------------------- 1 | #include "looprule_suggestauto.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | #include "looprule_helper.h" 5 | 6 | LoopRuleSuggestauto::LoopRuleSuggestauto() : Rule("LoopRuleSuggestauto") 7 | { 8 | m_ruleContent = make_shared(ErrorPriority::Suggest, m_name, 9 | "An auto declaration is recommended for the iteration variables in a for loop.", 10 | U8("for循环中的迭代变量建议采用auto声明")); 11 | } 12 | 13 | bool LoopRuleSuggestauto::detectCore(const string& code, const ErrorFile& errorFile) 14 | { 15 | if (LoopRuleHelper::findNotAutoFromFor(code)) 16 | { 17 | storeRuleError(errorFile); 18 | return true; 19 | } 20 | 21 | return false; 22 | } 23 | 24 | void LoopRuleSuggestauto::resetData() 25 | { 26 | Rule::resetData(); 27 | m_loopVariable.clear(); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_suggestauto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LoopRuleSuggestauto final : public Rule { 7 | public: 8 | LoopRuleSuggestauto(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_loopVariable; 16 | }; 17 | 18 | REGISTER_CLASS(LoopRuleSuggestauto) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_wrongstepdirection.cpp: -------------------------------------------------------------------------------- 1 | #include "looprule_wrongstepdirection.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | #include "looprule_helper.h" 5 | #include "detectorcommon/fordefinition.h" 6 | 7 | LoopRuleWrongStepDirection::LoopRuleWrongStepDirection() : Rule("LoopRuleWrongStepDirection") 8 | , m_forDefinition(make_unique()) 9 | { 10 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 11 | "Please check the iteration variable in the for loop is in the opposite direction", 12 | U8("for循环中的迭代变量方向是否反了")); 13 | } 14 | 15 | bool LoopRuleWrongStepDirection::detectCore(const string& code, const ErrorFile& errorFile) 16 | { 17 | if (!m_forDefinition->isFor(code)) 18 | { 19 | return false; 20 | } 21 | 22 | auto comparationSymbol = m_forDefinition->comparationSymbol(); 23 | auto stepOperation = m_forDefinition->stepOperation(); 24 | if (comparationSymbol.find("<") != string::npos && stepOperation == "--" 25 | || comparationSymbol.find(">") != string::npos && stepOperation == "++") 26 | { 27 | storeRuleError(errorFile); 28 | return true; 29 | } 30 | return false; 31 | } 32 | 33 | void LoopRuleWrongStepDirection::resetData() 34 | { 35 | Rule::resetData(); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_wrongstepdirection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | #include "detectorcommon/fordefinition.h" 6 | 7 | class DETECTOR_EXPORT LoopRuleWrongStepDirection final : public Rule { 8 | public: 9 | LoopRuleWrongStepDirection(); 10 | 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | std::unique_ptr m_forDefinition; 17 | }; 18 | 19 | REGISTER_CLASS(LoopRuleWrongStepDirection) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_wrongvariable.cpp: -------------------------------------------------------------------------------- 1 | #include "looprule_wrongvariable.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | #include "looprule_helper.h" 5 | 6 | LoopRuleWrongVariable::LoopRuleWrongVariable() : Rule("LoopRuleWrongVariable") 7 | { 8 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 9 | "The iteration variables in for loop are not consistent.", 10 | U8("for循环迭代变量不一致")); 11 | } 12 | 13 | bool LoopRuleWrongVariable::detectCore(const string& code, const ErrorFile& errorFile) 14 | { 15 | auto variablesInFor = LoopRuleHelper::getVariablesFromFor(code); 16 | if (variablesInFor.second.size() > 1) 17 | { 18 | storeRuleError(errorFile); 19 | return true; 20 | } 21 | return false; 22 | } 23 | 24 | void LoopRuleWrongVariable::resetData() 25 | { 26 | Rule::resetData(); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /detector_core/detectors/loop/looprule_wrongvariable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT LoopRuleWrongVariable final : public Rule { 7 | public: 8 | LoopRuleWrongVariable(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(LoopRuleWrongVariable) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleak.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/memleak) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "memleakrule_newwithoutdelete.h" 5 | #include "memleakrule_realloc.h" 6 | #include "memleakrule_mallocfree.h" 7 | #include "memleakrule_filehandle.h" 8 | #include "memleakrule_destructor.h" 9 | 10 | class MemLeakDetector final : public Detector { 11 | public: 12 | MemLeakDetector() 13 | :Detector("MemLeakDetector") 14 | { 15 | } 16 | 17 | vector getRuleNames() override 18 | { 19 | #ifdef WIN32 20 | return { 21 | GETRULENAMES(MemLeakRuleNewWithOutDelete), 22 | GETRULENAMES(MemLeakRuleRealloc), 23 | GETRULENAMES(MemLeakRuleMallocFree), 24 | GETRULENAMES(MemLeakRuleFileHandle), 25 | GETRULENAMES(MemLeakRuleDestructor) 26 | }; 27 | #else 28 | return { 29 | "MemLeakRuleNewWithOutDelete", 30 | "MemLeakRuleRealloc", 31 | "MemLeakRuleMallocFree", 32 | "MemLeakRuleFileHandle", 33 | "MemLeakRuleDestructor" 34 | }; 35 | #endif 36 | } 37 | }; 38 | 39 | REGISTER_CLASS(MemLeakDetector) -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_destructor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT MemLeakRuleDestructor final : public Rule { 7 | public: 8 | MemLeakRuleDestructor(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | bool m_isStruct = false; 16 | std::string m_className; 17 | std::string m_spaceBeforeClass; 18 | }; 19 | 20 | REGISTER_CLASS(MemLeakRuleDestructor) 21 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_filehandle.cpp: -------------------------------------------------------------------------------- 1 | #include "memleakrule_filehandle.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | MemLeakRuleFileHandle::MemLeakRuleFileHandle() : Rule("MemLeakRuleFileHandle") 5 | { 6 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 7 | "A file handle leak", 8 | U8("文件句柄泄漏")); 9 | } 10 | 11 | bool MemLeakRuleFileHandle::detectCore(const string& code, const ErrorFile& errorFile) 12 | { 13 | if (code.find("fopen") == string::npos 14 | && code.find("fclose") == string::npos) 15 | { 16 | return false; 17 | } 18 | 19 | if (auto ret = DetectorHelper::check(code, "(\\w+)\\s*=\\s*fopen"); !ret.empty()) 20 | { 21 | //check "FILE* pFile = fopen("c:\\test.txt", "w+");" 22 | m_resources.insert({ ret[1], errorFile }); 23 | return false; 24 | } 25 | 26 | if (auto ret = DetectorHelper::check(code, "fclose\\((\\w+)\\)"); !ret.empty()) 27 | { 28 | auto count = m_resources.count(ret[1]); 29 | if (count == 1) 30 | { 31 | m_resources.erase(m_resources.find(ret[1])); 32 | } 33 | return false; 34 | } 35 | 36 | return false; 37 | } 38 | 39 | void MemLeakRuleFileHandle::resetData() 40 | { 41 | Rule::resetData(); 42 | for_each(m_resources.begin(), m_resources.end(), [this](const auto& item) {return storeRuleError(item.second); }); 43 | m_resources.clear(); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_filehandle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT MemLeakRuleFileHandle final : public Rule { 7 | public: 8 | MemLeakRuleFileHandle(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::multimap m_resources; 16 | }; 17 | 18 | REGISTER_CLASS(MemLeakRuleFileHandle) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_mallocfree.cpp: -------------------------------------------------------------------------------- 1 | #include "memleakrule_mallocfree.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | MemLeakRuleMallocFree::MemLeakRuleMallocFree() : Rule("MemLeakRuleMallocFree") 5 | { 6 | m_ruleContent = make_shared(ErrorPriority::Suggest, m_name, 7 | "malloc/free are not recommended. new/delete are recommended.", 8 | U8("不建议使用malloc/free,请使用new/delete替代")); 9 | } 10 | 11 | bool MemLeakRuleMallocFree::detectCore(const string& code, const ErrorFile& errorFile) 12 | { 13 | if (!StringHelper(code).findCode("malloc") 14 | && !StringHelper(code).findCode("free")) 15 | { 16 | return false; 17 | } 18 | 19 | if (StringHelper(code).findCode("realloc")) 20 | { 21 | return false; 22 | } 23 | 24 | storeRuleError(errorFile); 25 | return true; 26 | } 27 | 28 | void MemLeakRuleMallocFree::resetData() 29 | { 30 | Rule::resetData(); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_mallocfree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT MemLeakRuleMallocFree final : public Rule { 7 | public: 8 | MemLeakRuleMallocFree(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(MemLeakRuleMallocFree) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_newwithoutdelete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT MemLeakRuleNewWithOutDelete final : public Rule { 7 | public: 8 | MemLeakRuleNewWithOutDelete(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::multimap m_objectCreateByNew; 16 | }; 17 | 18 | REGISTER_CLASS(MemLeakRuleNewWithOutDelete) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_realloc.cpp: -------------------------------------------------------------------------------- 1 | #include "memleakrule_realloc.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | MemLeakRuleRealloc::MemLeakRuleRealloc() : Rule("MemLeakRuleRealloc") 5 | { 6 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 7 | "Realloc is not recommended", 8 | U8("realloc年轻人把握不住,让基础库实现者来把握")); 9 | } 10 | 11 | bool MemLeakRuleRealloc::detectCore(const string& code, const ErrorFile& errorFile) 12 | { 13 | if (!StringHelper(code).findCode("realloc")) 14 | { 15 | return false; 16 | } 17 | 18 | storeRuleError(errorFile); 19 | return true; 20 | } 21 | 22 | void MemLeakRuleRealloc::resetData() 23 | { 24 | Rule::resetData(); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /detector_core/detectors/memleak/memleakrule_realloc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT MemLeakRuleRealloc final : public Rule { 7 | public: 8 | MemLeakRuleRealloc(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | }; 14 | 15 | REGISTER_CLASS(MemLeakRuleRealloc) 16 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operation.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/operation) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_arithmeticwithbool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../rule.h" 4 | #include "detectorcommon/detectorhelp.h" 5 | #include "../../common/reflecter.h" 6 | 7 | #include 8 | #include "../../common/stringhelper.h" 9 | 10 | class OperationRuleArithmeticWithBool final : public Rule { 11 | public: 12 | OperationRuleArithmeticWithBool(); 13 | 14 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 15 | 16 | void resetData() override; 17 | 18 | private: 19 | std::set m_varNames; 20 | }; 21 | 22 | REGISTER_CLASS(OperationRuleArithmeticWithBool) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_bitwiseshifttonegative.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | class OperationRuleBitwiseShiftToNegative final : public Rule { 6 | public: 7 | OperationRuleBitwiseShiftToNegative(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | bool checkMinus(const std::string& content); 15 | }; 16 | 17 | REGISTER_CLASS(OperationRuleBitwiseShiftToNegative) 18 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_bitwisewithbool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT OperationRuleBitwiseWithBool final : public Rule { 7 | public: 8 | OperationRuleBitwiseWithBool(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | 16 | bool valid(const std::string& variableName, const std::string& path); 17 | 18 | std::string getRegValue(const std::string& variableName); 19 | std::string m_data; 20 | }; 21 | 22 | REGISTER_CLASS(OperationRuleBitwiseWithBool) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_float.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | class OperationRuleFloat final : public Rule { 6 | public: 7 | OperationRuleFloat(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | 15 | bool checkVarName(const std::string& varName, const std::string& left, const std::string& right); 16 | 17 | std::set m_varNames; 18 | std::set m_varNamesInFunc; 19 | std::string m_funcName; 20 | 21 | bool insertVarNames(const string &code1); 22 | }; 23 | 24 | REGISTER_CLASS(OperationRuleFloat) 25 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_module.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | class StringHelp; 5 | class OperationRuleModule final : public Rule { 6 | public: 7 | OperationRuleModule(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | bool invalid(const std::string& str1, const std::string& str2); 15 | 16 | int getModule(const std::string& str); 17 | }; 18 | 19 | REGISTER_CLASS(OperationRuleModule) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_unsignedlessthanzero.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | class OperationRuleUnsignedLessThanZero final : public Rule { 6 | public: 7 | OperationRuleUnsignedLessThanZero(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | std::set m_varNames; 15 | }; 16 | 17 | REGISTER_CLASS(OperationRuleUnsignedLessThanZero) 18 | -------------------------------------------------------------------------------- /detector_core/detectors/operation/operationrule_zerodivision.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | class OperationRuleZeroDivision final : public Rule { 6 | public: 7 | OperationRuleZeroDivision(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | }; 13 | 14 | REGISTER_CLASS(OperationRuleZeroDivision) 15 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointer.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/pointer) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_checkafternew.cpp: -------------------------------------------------------------------------------- 1 | #include "pointerrule_checkafternew.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "pointerrule_helper.h" 4 | 5 | PointerRuleCheckAfterNew::PointerRuleCheckAfterNew() : Rule("PointerRuleCheckAfterNew") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Error, m_name, 8 | "After C++03, new failures will throw an exception instead of returning NULL. There is no need to check whether the value is null.", 9 | U8("C++03以后,new失败会抛出异常而不是返回NULL,没有必要进行判空。")); 10 | } 11 | 12 | bool PointerRuleCheckAfterNew::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (code.find("new ") == string::npos 15 | && code.find("if") == string::npos) 16 | { 17 | return false; 18 | } 19 | 20 | if (auto ret = DetectorHelper::checkConstructedObject(code); !ret.empty()) 21 | { 22 | m_pointerNameFromNew = ret[1]; 23 | return false; 24 | } 25 | 26 | if (m_pointerNameFromNew.empty()) 27 | { 28 | return false; 29 | } 30 | 31 | auto ret = PointerRuleHelper::getObjNameFromPair(PointerRuleHelper::getObjNamePairFromIfEqual(code)); 32 | auto pointerNameFromNew = m_pointerNameFromNew; 33 | m_pointerNameFromNew.clear(); 34 | if (pointerNameFromNew != ret) 35 | { 36 | return false; 37 | } 38 | 39 | storeRuleError(errorFile); 40 | return true; 41 | } 42 | 43 | void PointerRuleCheckAfterNew::resetData() 44 | { 45 | Rule::resetData(); 46 | m_pointerNameFromNew.clear(); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_checkafternew.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | 5 | class PointerRuleCheckAfterNew final : public Rule { 6 | public: 7 | PointerRuleCheckAfterNew(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | std::string m_pointerNameFromNew; 15 | }; 16 | 17 | REGISTER_CLASS(PointerRuleCheckAfterNew) 18 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | class PointerRuleHelper final { 5 | public: 6 | static std::string getObjNameOfNull(const std::string& content); 7 | 8 | static std::string getObjNameOfUninitialized(const std::string& content); 9 | 10 | static std::string getDereferenceVariable(const string& content); 11 | 12 | static std::pair getObjNamePairFromIfNotEqual(const std::string& content); 13 | 14 | static std::string getObjNameFromIfNotEqual(const std::string& content); 15 | 16 | static std::string getObjNameFromIfEqual(const std::string& content); 17 | 18 | static std::pair getObjNamePairFromIfEqual(const std::string& content); 19 | 20 | static bool isNull(const std::string& content); 21 | 22 | static bool existNull(const std::string& content); 23 | 24 | static bool detectDereference(const std::string& content, const std::string& objName, std::vector& inConditions); 25 | 26 | static std::string getObjNameFromPair(const std::pair& names); 27 | 28 | static std::vector getPointerFromIf(const std::string& content); 29 | 30 | static std::string getPointerFromCondition(const std::string& condition); 31 | 32 | private: 33 | static std::pair getObjNamePairFromIf(const std::string& content, const std::string& comparisonOperator); 34 | }; 35 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_ifnulldefect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include 5 | 6 | class DETECTOR_EXPORT PointerRuleIfNullDefect final : public Rule { 7 | public: 8 | PointerRuleIfNullDefect(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_objName; 16 | bool m_hasAnd = false; 17 | }; 18 | 19 | REGISTER_CLASS(PointerRuleIfNullDefect) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_localvariable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | #include 6 | 7 | class DETECTOR_EXPORT PointerRuleLocalVariable final : public Rule { 8 | public: 9 | PointerRuleLocalVariable(); 10 | 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | bool m_bInFunction = false; 17 | std::string m_localVariableType; 18 | std::string m_localVariable; 19 | }; 20 | 21 | REGISTER_CLASS(PointerRuleLocalVariable) 22 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_notcheck.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class DETECTOR_EXPORT PointerRuleNotCheck final : public Rule { 7 | public: 8 | PointerRuleNotCheck(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | private: 14 | struct PointerCheck 15 | { 16 | bool checked = false; 17 | bool inChecked = false; 18 | }; 19 | std::pair checkTernaryOperator(const string& code); 20 | bool storeRuleErrorFromNotCheckNames(const std::pair& item); 21 | bool getPointerFromIf(const string& code); 22 | bool endOfCondition(const string& code); 23 | 24 | std::map m_objNames; 25 | std::multimap m_notCheckNames; 26 | std::string m_sapceBeforeIf; 27 | }; 28 | 29 | REGISTER_CLASS(PointerRuleNotCheck) 30 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_nullptr.cpp: -------------------------------------------------------------------------------- 1 | #include "pointerrule_nullptr.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | 4 | PointerRuleNullptr::PointerRuleNullptr() : Rule("PointerRuleNullptr") 5 | { 6 | m_ruleContent = make_shared(ErrorPriority::Suggest, m_name, 7 | "NULL will cause the overloading in C++ to be out of order: void foo(char*);void foo(int);", 8 | U8("NULL将导致 C++ 中重载特性发生混乱:void foo(char*);void foo(int);")); 9 | } 10 | 11 | bool PointerRuleNullptr::detectCore(const string& code, const ErrorFile& errorFile) 12 | { 13 | if (!StringHelper(code).findCode("NULL")) 14 | { 15 | return false; 16 | } 17 | 18 | storeRuleError(errorFile); 19 | return true; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_nullptr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | 5 | class PointerRuleNullptr final : public Rule { 6 | public: 7 | PointerRuleNullptr(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | }; 11 | 12 | REGISTER_CLASS(PointerRuleNullptr) 13 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_returnnull.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | 5 | struct ReturnNull 6 | { 7 | bool mayNULL = false; 8 | std::multimap vars; 9 | }; 10 | 11 | class PointerRuleReturnNull final : public Rule { 12 | public: 13 | PointerRuleReturnNull(); 14 | 15 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 16 | 17 | void resetData() override; 18 | 19 | private: 20 | std::string m_funcName; 21 | std::map> m_returnNulls; 22 | 23 | bool conditionWithNull(const string &code); 24 | 25 | bool insertReturnNull(const string &code, const ErrorFile &errorFile); 26 | }; 27 | 28 | REGISTER_CLASS(PointerRuleReturnNull) 29 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_useddanglingpointer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | 5 | class PointerRuleUsedDanglingPointer final : public Rule { 6 | public: 7 | PointerRuleUsedDanglingPointer(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | std::string getObjectName(const std::string& code); 15 | 16 | std::set m_objNames; 17 | }; 18 | 19 | REGISTER_CLASS(PointerRuleUsedDanglingPointer) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_usedinsideofnullcheck.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | 6 | class IfDefinition; 7 | class DETECTOR_EXPORT PointerRuleUsedInsideOfNULLCheck final : public Rule { 8 | public: 9 | PointerRuleUsedInsideOfNULLCheck(); 10 | ~PointerRuleUsedInsideOfNULLCheck(); 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | std::string getObjNameFromIf(const string& code); 17 | 18 | std::string m_objName; 19 | std::vector m_inConditions; 20 | std::unique_ptr m_ifDefinition; 21 | }; 22 | 23 | REGISTER_CLASS(PointerRuleUsedInsideOfNULLCheck) 24 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_usednull.cpp: -------------------------------------------------------------------------------- 1 | #include "pointerrule_usednull.h" 2 | #include "pointerrule_helper.h" 3 | #include "detectorcommon/detectorhelp.h" 4 | 5 | PointerRuleUsedNull::PointerRuleUsedNull() : PointerRuleUsedUninitializedOrNull("PointerRuleUsedNull") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Critical, m_name, 8 | "Use a null pointer.", 9 | U8("使用空指针")); 10 | } 11 | 12 | bool PointerRuleUsedNull::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | auto objName = PointerRuleHelper::getObjNameOfNull(code); 15 | return detectReal(code, errorFile, objName); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_usednull.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "pointerrule_useduninitializedornull.h" 5 | #include "detector_global.h" 6 | 7 | class DETECTOR_EXPORT PointerRuleUsedNull final : public PointerRuleUsedUninitializedOrNull { 8 | public: 9 | PointerRuleUsedNull(); 10 | 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | }; 13 | 14 | REGISTER_CLASS(PointerRuleUsedNull) -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_usedoutsideofcheck.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "detector_global.h" 5 | #include 6 | #include 7 | 8 | class DETECTOR_EXPORT PointerRuleUsedOutsideOfCheck final : public Rule { 9 | public: 10 | PointerRuleUsedOutsideOfCheck(); 11 | 12 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 13 | 14 | void resetData() override; 15 | 16 | private: 17 | std::string m_objName; 18 | std::vector m_inConditions; 19 | bool m_findBrace = false; 20 | }; 21 | 22 | REGISTER_CLASS(PointerRuleUsedOutsideOfCheck) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_useduninitialized.cpp: -------------------------------------------------------------------------------- 1 | #include "pointerrule_useduninitialized.h" 2 | #include "../../detectorcommon/detectorcommon.h" 3 | #include "pointerrule_helper.h" 4 | #include "detectorcommon/detectorhelp.h" 5 | #include 6 | 7 | PointerRuleUsedUninitialized::PointerRuleUsedUninitialized() : PointerRuleUsedUninitializedOrNull("PointerRuleUsedUninitialized") 8 | { 9 | m_ruleContent = make_shared(ErrorPriority::Critical, m_name, 10 | "Use an uninitialized pointer (wild pointer).", 11 | U8("使用未初始化的指针(野指针)。")); 12 | } 13 | 14 | bool PointerRuleUsedUninitialized::detectCore(const string& code, const ErrorFile& errorFile) 15 | { 16 | auto objName = PointerRuleHelper::getObjNameOfUninitialized(code); 17 | return detectReal(code, errorFile, objName); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_useduninitialized.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include "pointerrule_useduninitializedornull.h" 5 | 6 | class PointerRuleUsedUninitialized final : public PointerRuleUsedUninitializedOrNull { 7 | public: 8 | PointerRuleUsedUninitialized(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | }; 12 | 13 | REGISTER_CLASS(PointerRuleUsedUninitialized) -------------------------------------------------------------------------------- /detector_core/detectors/pointer/pointerrule_useduninitializedornull.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "detector_global.h" 4 | 5 | class DETECTOR_EXPORT PointerRuleUsedUninitializedOrNull : public Rule { 6 | public: 7 | using Rule::Rule; 8 | virtual ~PointerRuleUsedUninitializedOrNull() = default; 9 | bool detectReal(const std::string& code, const ErrorFile& errorFile, const std::string& objName); 10 | 11 | void resetData() override; 12 | 13 | private: 14 | std::map m_objNames; 15 | }; -------------------------------------------------------------------------------- /detector_core/detectors/singleton/singleton.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/singleton) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/singleton/singletondetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "singletonrule_threadsafety.h" 4 | #include "../../common/reflecter.h" 5 | 6 | class SingletonDetector final : public Detector { 7 | public: 8 | SingletonDetector() 9 | :Detector("SingletonDetector") 10 | { 11 | } 12 | 13 | vector getRuleNames() override 14 | { 15 | #ifdef WIN32 16 | return { 17 | GETRULENAMES(SingletonRuleThreadSafety) 18 | }; 19 | #else 20 | return { 21 | "SingletonRuleThreadSafety" 22 | }; 23 | #endif 24 | } 25 | }; 26 | 27 | REGISTER_CLASS(SingletonDetector) -------------------------------------------------------------------------------- /detector_core/detectors/singleton/singletonrule_threadsafety.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | 6 | class SingletonRuleThreadSafety final : public Rule { 7 | public: 8 | SingletonRuleThreadSafety(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | void clear(); 15 | 16 | private: 17 | bool m_findIf = false; 18 | std::string m_className; 19 | std::string m_parameterName; 20 | ErrorFile m_errorFile; 21 | }; 22 | 23 | REGISTER_CLASS(SingletonRuleThreadSafety) 24 | -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeof.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/sizeof) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "sizeofrule_funcparameter.h" 5 | #include "sizeofrule_repetition.h" 6 | #include "sizeofrule_withnumber.h" 7 | #include "sizeofrule_pointer.h" 8 | 9 | class SizeofDetector final : public Detector { 10 | public: 11 | SizeofDetector() 12 | :Detector("SizeofDetector") 13 | { 14 | } 15 | 16 | vector getRuleNames() override 17 | { 18 | #ifdef WIN32 19 | return { 20 | GETRULENAMES(SizeOfRuleFuncParameter), 21 | GETRULENAMES(SizeOfRuleRepetition), 22 | GETRULENAMES(SizeOfRuleWithNumber), 23 | GETRULENAMES(SizeOfRulePointer) 24 | }; 25 | #else 26 | return { 27 | "SizeOfRuleFuncParameter", 28 | "SizeOfRuleRepetition", 29 | "SizeOfRuleWithNumber", 30 | "SizeOfRulePointer" 31 | }; 32 | #endif 33 | } 34 | }; 35 | 36 | REGISTER_CLASS(SizeofDetector) -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofrule_funcparameter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | class SizeOfRuleFuncParameter final : public Rule { 6 | public: 7 | SizeOfRuleFuncParameter(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | std::string m_arrayName; 15 | }; 16 | 17 | REGISTER_CLASS(SizeOfRuleFuncParameter) 18 | -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofrule_pointer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | 6 | class VariableDefinition; 7 | class SizeOfRulePointer final : public Rule { 8 | public: 9 | SizeOfRulePointer(); 10 | ~SizeOfRulePointer(); 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | std::set m_variableNames; 17 | std::unique_ptr m_variableDefinition; 18 | }; 19 | 20 | REGISTER_CLASS(SizeOfRulePointer) 21 | -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofrule_repetition.cpp: -------------------------------------------------------------------------------- 1 | #include "sizeofrule_repetition.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | SizeOfRuleRepetition::SizeOfRuleRepetition() : Rule("SizeOfRuleRepetition") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 8 | "Meaningless reuse of sizeof, which may be caused by an error.", 9 | U8("无意义的重复使用sizeof,可能是失误造成的")); 10 | } 11 | 12 | bool SizeOfRuleRepetition::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (!StringHelper(code).findCode("sizeof(sizeof")) 15 | { 16 | return false; 17 | } 18 | 19 | storeRuleError(errorFile); 20 | return true; 21 | } 22 | 23 | void SizeOfRuleRepetition::resetData() 24 | { 25 | Rule::resetData(); 26 | m_arrayName.clear(); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofrule_repetition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | 5 | class SizeOfRuleRepetition final : public Rule { 6 | public: 7 | SizeOfRuleRepetition(); 8 | 9 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 10 | 11 | void resetData() override; 12 | 13 | private: 14 | std::string m_arrayName; 15 | }; 16 | 17 | REGISTER_CLASS(SizeOfRuleRepetition) 18 | -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofrule_withnumber.cpp: -------------------------------------------------------------------------------- 1 | #include "sizeofrule_withnumber.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "../../common/stringhelper.h" 4 | 5 | SizeOfRuleWithNumber::SizeOfRuleWithNumber() : Rule("SizeOfRuleWithNumber") 6 | { 7 | m_ruleContent = make_shared(ErrorPriority::Warning, m_name, 8 | "When sizeof is used for a numeric constant, please check whether it makes sense.", 9 | U8("对一个数字常量使用sizeof,请确认是否有意义")); 10 | } 11 | 12 | bool SizeOfRuleWithNumber::detectCore(const string& code, const ErrorFile& errorFile) 13 | { 14 | if (code.find("sizeof") == string::npos) 15 | { 16 | return false; 17 | } 18 | 19 | if (DetectorHelper::check(code, "sizeof\\s*\\(\\s*\\d+").empty()) 20 | { 21 | return false; 22 | } 23 | 24 | storeRuleError(errorFile); 25 | return true; 26 | } 27 | 28 | void SizeOfRuleWithNumber::resetData() 29 | { 30 | Rule::resetData(); 31 | m_arrayName.clear(); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /detector_core/detectors/sizeof/sizeofrule_withnumber.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | 6 | class SizeOfRuleWithNumber final : public Rule { 7 | public: 8 | SizeOfRuleWithNumber(); 9 | 10 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 11 | 12 | void resetData() override; 13 | 14 | private: 15 | std::string m_arrayName; 16 | }; 17 | 18 | REGISTER_CLASS(SizeOfRuleWithNumber) 19 | -------------------------------------------------------------------------------- /detector_core/detectors/uninit/uninit.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/uninit) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/uninit/uninitdetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "uninitrule_var.h" 5 | #include "uninitrule_pointer.h" 6 | 7 | class UninitDetector final : public Detector { 8 | public: 9 | UninitDetector() 10 | :Detector("UninitDetector") 11 | { 12 | } 13 | 14 | vector getRuleNames() override 15 | { 16 | #ifdef WIN32 17 | return { 18 | GETRULENAMES(UninitRuleVar), 19 | GETRULENAMES(UninitRulePointer) 20 | }; 21 | #else 22 | return { 23 | "UninitRuleVar", 24 | "UninitRulePointer" 25 | }; 26 | #endif 27 | } 28 | }; 29 | 30 | REGISTER_CLASS(UninitDetector) -------------------------------------------------------------------------------- /detector_core/detectors/uninit/uninitrule_helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "detectorcommon/detectorcommon.h" 4 | #include 5 | #include 6 | #include 7 | 8 | class UninitRuleVariableDefinitionHelper final { 9 | public: 10 | bool detectCore(const ErrorFile& errorFile, const std::string& variableName); 11 | 12 | std::vector resetData(); 13 | 14 | void checkClass(const std::string& code); 15 | 16 | private: 17 | void resetEndOfClass(); 18 | 19 | std::string m_className; 20 | bool m_findConstructor = false; 21 | bool m_inConstructor = false; 22 | int m_countOfLeftBrace = 0; 23 | std::map> m_initializedVariables; 24 | std::multimap> m_definedVariables; 25 | }; 26 | -------------------------------------------------------------------------------- /detector_core/detectors/uninit/uninitrule_pointer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include 5 | #include "detector_global.h" 6 | 7 | class UninitRuleVariableDefinitionHelper; 8 | class VariableDefinition; 9 | class DETECTOR_EXPORT UninitRulePointer final : public Rule { 10 | public: 11 | UninitRulePointer(); 12 | ~UninitRulePointer(); 13 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 14 | 15 | void resetData() override; 16 | 17 | private: 18 | std::unique_ptr m_uninitRuleVarHelper; 19 | std::unique_ptr m_definition; 20 | }; 21 | 22 | REGISTER_CLASS(UninitRulePointer) 23 | -------------------------------------------------------------------------------- /detector_core/detectors/uninit/uninitrule_var.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "common/reflecter.h" 4 | #include 5 | 6 | class UninitRuleVariableDefinitionHelper; 7 | class UninitRuleVar final : public Rule { 8 | public: 9 | UninitRuleVar(); 10 | ~UninitRuleVar(); 11 | bool detectCore(const std::string& code, const ErrorFile& errorFile) override; 12 | 13 | void resetData() override; 14 | 15 | private: 16 | std::unique_ptr m_uninitRuleVarHelper; 17 | }; 18 | 19 | REGISTER_CLASS(UninitRuleVar) 20 | -------------------------------------------------------------------------------- /detector_core/detectors/variable/variable.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/variable) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 6 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 7 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 8 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) 9 | 10 | SET(HEADERS 11 | ${RECURSE_CMAKE} 12 | ) -------------------------------------------------------------------------------- /detector_core/detectors/variable/variabledetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "detectors/detector.h" 3 | #include "../../common/reflecter.h" 4 | #include "variablerule_global.h" 5 | 6 | class VariableDetector final: public Detector { 7 | public: 8 | VariableDetector() 9 | :Detector("VariableDetector") 10 | { 11 | } 12 | 13 | vector getRuleNames() override 14 | { 15 | #ifdef WIN32 16 | return { 17 | GETRULENAMES(VariableRuleGlobal) 18 | }; 19 | #else 20 | return { 21 | "VariableRuleGlobal" 22 | }; 23 | #endif 24 | } 25 | }; 26 | 27 | REGISTER_CLASS(VariableDetector) -------------------------------------------------------------------------------- /detector_core/detectors/variable/variablerule_global.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../rule.h" 3 | #include "../../common/reflecter.h" 4 | #include 5 | using namespace std; 6 | 7 | class FunctionDefinition; 8 | class ClassDefinition; 9 | 10 | class DETECTOR_EXPORT VariableRuleGlobal final : public Rule { 11 | public: 12 | VariableRuleGlobal(); 13 | ~VariableRuleGlobal(); 14 | bool detectCore(const string& code, const ErrorFile& errorFile) override; 15 | void resetData() override; 16 | 17 | private: 18 | unique_ptr m_functionDefinition; 19 | unique_ptr m_classDefinition; 20 | }; 21 | REGISTER_CLASS(VariableRuleGlobal) 22 | -------------------------------------------------------------------------------- /release/windows_x64/checklastpush.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | ::set codepath=D:\gitRepo\viplexcore 3 | set codepath=F:\work\git\viplexcore 4 | call checklastpushcore.bat %codepath% 5 | echo %errorlevel% 6 | pause -------------------------------------------------------------------------------- /release/windows_x64/config/exceptionconfig.json: -------------------------------------------------------------------------------- 1 | ["F:\work\git\viplexcore\src\libs\sqlite", "F:\work\git\viplexcore\src\libs\viplexcommon\sqlite3qq" 2 | ] -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-convert-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-convert-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-filesystem-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-filesystem-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-heap-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-heap-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-locale-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-locale-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-math-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-math-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-runtime-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-runtime-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-stdio-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-stdio-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/api-ms-win-crt-string-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/api-ms-win-crt-string-l1-1-0.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/cppdetector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/cppdetector.exe -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/detector_core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/detector_core.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/msvcp140.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/msvcp140_atomic_wait.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/msvcp140_atomic_wait.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/vcruntime140.dll -------------------------------------------------------------------------------- /release/windows_x64/cppdetector/vcruntime140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/release/windows_x64/cppdetector/vcruntime140_1.dll -------------------------------------------------------------------------------- /release/windows_x64/readme.md: -------------------------------------------------------------------------------- 1 | # CPPDetector 2 | 3 | cppdetector是一款C++的静态代码检测工具,后续会逐步将effective C++,谷歌编程规范,诺瓦编程规范中的条款引入到检测规则中。 4 | 5 | cppdetector参数如下: 6 | 7 | 参数1:标识应用采用何种方式运行: 8 | 9 | * 多线程:"multithread" 10 | 11 | * 多进程:"multiprocess" 12 | 13 | * 单线程:"singlethread" 14 | 15 | 参数2:被检测的代码路径 16 | 17 | 参数3(可选):例外代码路径,存放例外文件数组的JSON文件,参见:exceptionconfig.json 18 | 19 | 参数4:检测的规则项,存放规则的JSON文件,参见:detectorRuleNames.json 20 | 21 | 示例:run.bat,检测代码,只要修改第2个参数,即被检测代码路径后即可双击运行检测 22 | 23 | 示例:checklastpush.bat,检测最后一次提交记录的代码,只需要将codePath设置成git库的更目录即可:set codepath=F:\work\git\viplexcore\ 24 | 25 | -------------------------------------------------------------------------------- /release/windows_x64/run.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | set codepath=%~dp0..\..\supporting\badcodesamples 3 | echo %codepath% 4 | runcore.bat %codepath% 5 | pause -------------------------------------------------------------------------------- /release/windows_x64/runcore.bat: -------------------------------------------------------------------------------- 1 | set cur=%~dp0 2 | %~dp0cppdetector\cppdetector.exe multithread %1 %cur%config\exceptionconfig.json %cur%config\detectorRuleNames.json %cur%detectorResult 3 | set reterror=%errorlevel% 4 | echo %reterror% 5 | exit /b %reterror% -------------------------------------------------------------------------------- /supporting/badcodesamples/acrossdynamicsample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class OUTPUT Test1() { 4 | static Test1& getInstance() { 5 | static Test1 test; 6 | return test; 7 | } 8 | } 9 | 10 | class OUTPUT Test2() { 11 | static Test2& getInstance() { 12 | static Test2 test; 13 | return test; 14 | } 15 | } -------------------------------------------------------------------------------- /supporting/badcodesamples/acrossdynamicsample2.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/supporting/badcodesamples/acrossdynamicsample2.h -------------------------------------------------------------------------------- /supporting/badcodesamples/arraysample2.h: -------------------------------------------------------------------------------- 1 | void Demo(int j) 2 | { 3 | int a[10] = { 0 }; 4 | 5 | int i = 9; 6 | if (j > 5) 7 | { 8 | i = -1; 9 | } 10 | 11 | a[i] = a[i] + 1; 12 | } 13 | 14 | 15 | char szStrTime[5]; 16 | char source[10] = {"abcde"}; 17 | 18 | snprintf(szStrTime, 5, "%s", source); 19 | strcpy(szStrTime, source); 20 | strncpy(szStrTime, "12345", 5); -------------------------------------------------------------------------------- /supporting/badcodesamples/classsample.h: -------------------------------------------------------------------------------- 1 | class A final 2 | { 3 | public: 4 | explicit A(const int s) 5 | { 6 | 7 | } 8 | 9 | A(const A& s) 10 | { 11 | 12 | } 13 | 14 | A& operator=(const A&& a) 15 | { 16 | 17 | } 18 | }; -------------------------------------------------------------------------------- /supporting/badcodesamples/confusedsample.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/supporting/badcodesamples/confusedsample.h -------------------------------------------------------------------------------- /supporting/badcodesamples/lambdasample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void fontManger(startTransferProgram, [&](const int errorCode, const std::string& result) { 4 | } -------------------------------------------------------------------------------- /supporting/badcodesamples/logicsample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | void LogicRuleBaseValueDemo() 3 | { 4 | if (1) {}; 5 | if (0) {}; 6 | if (true) {}; 7 | if (false) {}; 8 | } 9 | 10 | void LogicRuleIncorrectOperationDemo() 11 | { 12 | if ((a != 1) || (a != 3)) {} 13 | if ((a == 1) && (a == 3)) {} 14 | } 15 | 16 | void LogicRuleAssignSelfDemo() 17 | { 18 | int i; 19 | i = i; 20 | } 21 | 22 | void LogicRuleStringFindDemo(std::string& str, std::string& search) 23 | { 24 | if (0 <= str.find(search)) 25 | { 26 | } 27 | } 28 | 29 | void LogicRuleExpressionRepetitionDemo(int a) 30 | { 31 | if (a < 3 && a < 25) 32 | { 33 | return; 34 | } 35 | 36 | if (a >= 10 && a >= 20) 37 | { 38 | return; 39 | } 40 | 41 | if (a != 10 && a == 20) {} 42 | } -------------------------------------------------------------------------------- /supporting/badcodesamples/loopsample.h: -------------------------------------------------------------------------------- 1 | void LoopRuleVariableModifiedDemo() 2 | { 3 | for (int ii = 0; ii < 10; ++ii) 4 | { 5 | ii == 2; 6 | for (int ii = 0; ii < 20; ++ii) 7 | } 8 | } 9 | 10 | void LoopRuleWrongVariableDemo(int iMax) 11 | { 12 | for (int i = 0; i < iMax; ++j) 13 | { 14 | 15 | } 16 | } 17 | 18 | void LoopRuleOutOfBoundsDemo(std::string& str, char ch) 19 | { 20 | for (std::string::const_iterator iter = str.begin(); iter != str.end(); ++iter) 21 | { 22 | if (*(iter + 1) == ch) 23 | { 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /supporting/badcodesamples/memleaksample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void MemLeakRuleNewWithOutDeleteDemo() 4 | { 5 | char* p = new char; 6 | p = nullptr; 7 | } 8 | 9 | void MemLeakRuleReallocDemo() 10 | { 11 | char* buf = (char*)malloc(10); 12 | char* p = buf[1]; 13 | buf = (char*)realloc(buf, 100); 14 | *p = 'a'; 15 | free(buf); 16 | } 17 | 18 | void MemLeakRuleFileHandleDemo1() 19 | { 20 | FILE* pFile = fopen("c:\\test.txt", "w+"); 21 | } 22 | 23 | void MemLeakRuleFileHandleDemo2() 24 | { 25 | FILE* pFile = fopen("c:\\test.txt", "w+"); 26 | fclose(pFile); 27 | } 28 | 29 | "~dd"; 30 | class Derived : public Base 31 | { 32 | public: 33 | ~Derived() 34 | { 35 | (void)11; 36 | } 37 | }; -------------------------------------------------------------------------------- /supporting/badcodesamples/operationsample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | void OperationRuleZeroDivisionDemo() 3 | { 4 | int nZeroDivision = 10; 5 | int nZero = 0; 6 | int ret = nZeroDivision % nZero; 7 | int ret1 = nZeroDivision / nZero; 8 | } 9 | 10 | void OperationRuleConfusedSemicolonDemo(int iMax) 11 | { 12 | if (iMax > 0 && iMax != 3); 13 | { 14 | 15 | } 16 | } 17 | 18 | void OperationRuleArithmeticWithBoolDemo() 19 | { 20 | bool b; 21 | b *; 22 | 23 | if (b % 10 == 10) 24 | } 25 | 26 | bool OperationRuleFloatDemo(FLOAT f) 27 | { 28 | if (f == 0) 29 | { 30 | return true; 31 | } 32 | return false; 33 | } 34 | 35 | void OperationRuleUnsignedLessThanZeroDemo(unsigned int i) 36 | { 37 | if (i < 0) 38 | { 39 | } 40 | } 41 | 42 | void OperationRuleBitwiseShiftToNegativeDemo(int a) 43 | { 44 | a >> -2; 45 | } 46 | 47 | void OperationRuleBitwiseWithBoolDemo() 48 | { 49 | auto b = false; 50 | int r = b & 0x01; 51 | b & 0x01; 52 | } -------------------------------------------------------------------------------- /supporting/badcodesamples/singletonsample.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhlongfj/cppdetector/5a9ace790e6c38c78ad481dced92a19f4c1e9c37/supporting/badcodesamples/singletonsample.cpp -------------------------------------------------------------------------------- /supporting/badcodesamples/singletonsample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Test() { 4 | public: 5 | static Test* getInstance(); 6 | private: 7 | static Test* m_tt; 8 | } -------------------------------------------------------------------------------- /supporting/badcodesamples/sizeofsample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int sz[] = { 1,2,4 } 4 | int SizeOfRuleFuncParameterDemo1(int32_t sz[3]) 5 | { 6 | auto ss = sizeof(sz); 7 | return ss; 8 | } 9 | 10 | int SizeOfRuleFuncParameterDemo2() 11 | { 12 | int sz; 13 | auto ss = sizeof(sz); 14 | return ss; 15 | } 16 | 17 | int SizeOfRuleRepetitionDemo() 18 | { 19 | int a = 0; 20 | int n = sizeof(sizeof(a)); 21 | } 22 | 23 | void SizeOfRuleWithNumberDemo() 24 | { 25 | int n = sizeof(9); 26 | } 27 | -------------------------------------------------------------------------------- /supporting/badcodesamples/uninitsample.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | void UninitRuleVarDemo() 3 | { 4 | int32_t s; 5 | int64_t s; 6 | uint16_t s; 7 | unsigned int32_t ss; 8 | int a; 9 | a++; 10 | } 11 | 12 | void UninitRulePointerDemo() 13 | { 14 | Foo* p; 15 | p->Method(); 16 | } -------------------------------------------------------------------------------- /supporting/exceptionconfig.json: -------------------------------------------------------------------------------- 1 | ["F:\work\git\viplexcore\src\libs\sqlite", "F:\work\git\viplexcore\src\libs\viplexcommon\sqlite3qq" 2 | ] -------------------------------------------------------------------------------- /unit_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #add_definitions(-DBUILD_STATIC) 2 | INCLUDE(unit_tests.cmake) 3 | add_executable(unit_tests_run ${SOURCES}) 4 | target_link_libraries(unit_tests_run detector_core) -------------------------------------------------------------------------------- /unit_tests/common/common.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME common) 2 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 3 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 4 | FILE(GLOB_RECURSE RECURSE_CMAKE "./${DIR_NAME}/*.cmake") 5 | SOURCE_GROUP("${DIR_NAME}/Header Files" FILES ${RECURSE_H}) 6 | SOURCE_GROUP("${DIR_NAME}/Source Files" FILES ${RECURSE_CPP}) 7 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_CMAKE}) -------------------------------------------------------------------------------- /unit_tests/common/stringhelper_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../doctest.h" 2 | #include "common/stringhelper.h" 3 | 4 | SCENARIO("StringHelper") { 5 | GIVEN("") { 6 | WHEN("") { 7 | THEN("realloc") { 8 | StringHelper helper("else if (buf = (char*)realloc(buf, 100))"); 9 | CHECK(helper.findCode("realloc")); 10 | } 11 | THEN("") { 12 | StringHelper helper("++i"); 13 | CHECK(helper.getVariableFromSelfOperation("++") == "i"); 14 | } 15 | THEN("") { 16 | StringHelper helper("i--"); 17 | CHECK(helper.getVariableFromSelfOperation("--") == "i"); 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /unit_tests/detectorcommon/detectorcommon.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectorcommon) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectorcommon/fordefinition_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../doctest.h" 2 | #include "detectorcommon/detectorhelp.h" 3 | #include "detectorcommon/fordefinition.h" 4 | 5 | SCENARIO("ForDefinition") { 6 | GIVEN("checkConstructedObject") { 7 | WHEN("") { 8 | THEN("Iteration variables are declared in loops") { 9 | string code = R"delimiter(for (unsigned int ii = 0; ii <= foo.size(); ++ii))delimiter"; 10 | ForDefinition definition; 11 | CHECK(definition.isFor(code)); 12 | CHECK(definition.type() == "unsigned int"); 13 | } 14 | THEN("Iteration variables are declared outside the loop") { 15 | string code = R"delimiter(for (ii = 0; ii <= foo.size(); ++ii))delimiter"; 16 | ForDefinition definition; 17 | CHECK(definition.isFor(code)); 18 | CHECK(definition.type() == ""); 19 | } 20 | THEN("Reverse loop") { 21 | string code = R"delimiter(for (ii = foo.size() - 1; ii >= 0; ii--))delimiter"; 22 | ForDefinition definition; 23 | CHECK(definition.isFor(code)); 24 | CHECK(definition.type() == ""); 25 | } 26 | THEN("") { 27 | string code = R"delimiter(while (d))delimiter"; 28 | ForDefinition definition; 29 | CHECK(!definition.isFor(code)); 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /unit_tests/detectors/accesscontrol/accesscontrol.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/accesscontrol) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/array/array.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/array) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/array/arrayrule_indexoutofboundsfromfunc_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/array/arrayrulehelper.h" 3 | #include "detectors/array/arrayrule_indexoutofboundsfromfunc.h" 4 | 5 | static constexpr auto code1 = R"delimiter( 6 | constexpr int INDEX1 = 200; 7 | class ArrayRuleIndexOutOfBoundsFromFuncDemo() 8 | { 9 | char buf[INDEX1]; 10 | int length = getLenFromBuf(INDEX1); 11 | buf[length] = 'Q'; 12 | } 13 | )delimiter"; 14 | 15 | SCENARIO("ArrayRuleIndexOutOfBoundsFromFunc") { 16 | GIVEN("") { 17 | WHEN("Match condition with define outside") { 18 | THEN("Matching rule") { 19 | std::unique_ptr helper = make_unique(); 20 | helper->setData(code1); 21 | ArrayRuleIndexOutOfBoundsFromFunc rule(move(helper)); 22 | CHECK(rule.detect(code1, "dd.h")); 23 | } 24 | } 25 | WHEN("just called") { 26 | THEN("called") { 27 | ArrayRuleIndexOutOfBoundsFromFunc rule; 28 | rule.resetData(); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /unit_tests/detectors/array/arrayrule_indexoutofboundsinloop_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/array/arrayrulehelper.h" 3 | #include "detectors/array/arrayrule_indexoutofboundsinloop.h" 4 | 5 | static constexpr auto code1 = R"delimiter( 6 | #define INDEX 200 7 | void ArrayRuleIndexOutOfBoundsInLoopDemo() 8 | { 9 | char buf[INDEX]; 10 | for (unsigned int i = 0; i <= INDEX; ++i) 11 | { 12 | buf[i] = 'a'; 13 | } 14 | 15 | for (unsigned int i = 0; i < INDEX; ++i) 16 | { 17 | buf[i] = 'a'; 18 | } 19 | } 20 | )delimiter"; 21 | 22 | SCENARIO("ArrayRuleIndexOutOfBoundsInLoop") { 23 | GIVEN("") { 24 | WHEN("Match condition with define outside") { 25 | THEN("Matching rule") { 26 | std::unique_ptr helper = make_unique(); 27 | helper->setData(code1); 28 | ArrayRuleIndexOutOfBoundsInLoop rule(move(helper)); 29 | CHECK(rule.detect(code1, "dd.h")); 30 | } 31 | } 32 | WHEN("just called") { 33 | THEN("called") { 34 | ArrayRuleIndexOutOfBoundsInLoop rule; 35 | rule.resetData(); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /unit_tests/detectors/array/arrayrule_memsetzerobyte_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/array/arrayrule_memsetzerobyte.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void ArrayRuleMemsetDemo() 6 | { 7 | char* p = new char[100]; 8 | memset(p, 100, 0); 9 | delete[] p; 10 | } 11 | )delimiter"; 12 | 13 | static constexpr auto code2 = R"delimiter( 14 | void ArrayRuleMemsetDemo() 15 | { 16 | char* p = new char[100]; 17 | auto ss = "memset(p, 100, 0);"; 18 | delete[] p; 19 | } 20 | )delimiter"; 21 | 22 | SCENARIO("ArrayRuleMemsetZeroByte") { 23 | GIVEN("") { 24 | WHEN("Match condition") { 25 | THEN("Matching rule") { 26 | ArrayRuleMemsetZeroByte rule; 27 | CHECK(rule.detect(code1, "dd.h")); 28 | } 29 | } 30 | WHEN("Not match condition") { 31 | THEN("Mismatching rule") { 32 | ArrayRuleMemsetZeroByte rule; 33 | CHECK(!rule.detect(code2, "dd.h")); 34 | } 35 | } 36 | WHEN("just called") { 37 | THEN("called") { 38 | ArrayRuleMemsetZeroByte rule; 39 | rule.resetData(); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /unit_tests/detectors/class/class.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/class) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/class/classrule_pairofconstructorandassignment_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/class/classrule_pairofconstructorandassignment.h" 3 | 4 | static constexpr auto sss = R"delimiter( 5 | class A 6 | { 7 | public: 8 | A(const int s) 9 | { 10 | 11 | } 12 | 13 | A(const A& s) 14 | { 15 | 16 | } 17 | 18 | A& operator=(const A&& a) 19 | { 20 | 21 | } 22 | }; 23 | )delimiter"; 24 | 25 | SCENARIO("VariableRulePairOfConstructorAndAssignment") { 26 | GIVEN("") { 27 | WHEN("") { 28 | THEN("bad smell") { 29 | VariableRulePairOfConstructorAndAssignment rule; 30 | rule.detect(sss, "ddd"); 31 | CHECK(rule.getRuleErrors().size() == 2); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confused.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/confused) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_casewithoutbreak_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_casewithoutbreak.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void dd() 6 | { 7 | int param = 4; 8 | string qstrAlign; 9 | switch (param) 10 | { 11 | case 1: 12 | { 13 | qstrAlign = " align=\"CENTER\">"; 14 | int param1 = 3; 15 | switch (param1) 16 | { 17 | case 3: 18 | qstrAlign = " align=\"RIGHT\">"; 19 | default: 20 | qstrAlign = " align=\"RIGHT\">"; 21 | } 22 | } 23 | case 2: 24 | qstrAlign = " align=\"LEFT\">"; 25 | break; 26 | case 3: 27 | qstrAlign = " align=\"RIGHT\">"; 28 | default: 29 | qstrAlign = " align=\"RIGHT\">"; 30 | } 31 | } 32 | )delimiter"; 33 | 34 | SCENARIO("ConfusedRuleCaseWithoutBreak") { 35 | GIVEN("") { 36 | WHEN("Match condition") { 37 | THEN("Matching rule") { 38 | ConfusedRuleCaseWithoutBreak rule; 39 | rule.detect(code1, "dd.h"); 40 | rule.resetData(); 41 | CHECK(rule.getRuleErrors().size() == 4); 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_diffvariablewithinitandcondition_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_diffvariablewithinitandcondition.h" 3 | 4 | SCENARIO("ConfusedRuleDiffVariableWithInitAndCondition") { 5 | GIVEN("") { 6 | WHEN("Match condition") { 7 | THEN("Matching rule") { 8 | ConfusedRuleDiffVariableWithInitAndCondition rule; 9 | CHECK(!rule.detect(R"delimiter1(if (ret.empty())delimiter1", "dd")); 10 | CHECK(!rule.detect(R"delimiter1(if (auto ret1 = DetectorHelper::check(ret[1], R\"delimiter(\w+\s+\w+\s*$)delimiter\"); ret1.empty()))delimiter1", "dd")); 11 | CHECK(rule.detect(R"delimiter1(if (auto ret1 = DetectorHelper::check(ret[1], R\"delimiter(\w+\s+\w+\s*$)delimiter\"); ret.empty()))delimiter1", "dd")); 12 | } 13 | } 14 | WHEN("Mismatch condition") { 15 | THEN("Mismatching rule") { 16 | ConfusedRuleDiffVariableWithInitAndCondition rule; 17 | CHECK(!rule.detect("class A", "dd.h")); 18 | 19 | } 20 | } 21 | WHEN("just called") { 22 | THEN("called") { 23 | ConfusedRuleDiffVariableWithInitAndCondition rule; 24 | rule.resetData(); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_nothandlefuncreturn_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_nothandlefuncreturn.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | int* DemoFunc() 6 | { 7 | if (rand() > 1024) 8 | { 9 | int* p = new int; 10 | return p; 11 | } 12 | return nullptr; 13 | } 14 | 15 | void PointerRuleReturnNullDemo() 16 | { 17 | int* p = DemoFunc(); 18 | DemoFunc(); 19 | } 20 | 21 | )delimiter"; 22 | 23 | SCENARIO("ConfusedRuleNotHandleFuncReturn") { 24 | GIVEN("") { 25 | WHEN("") { 26 | THEN("no explicit") { 27 | ConfusedRuleNotHandleFuncReturn rule; 28 | CHECK(rule.detect(code1, "dd.h")); 29 | CHECK(rule.getRuleErrors().size() == 1); 30 | } 31 | } 32 | WHEN("just called") { 33 | THEN("called") { 34 | ConfusedRuleNotHandleFuncReturn rule; 35 | rule.resetData(); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_priority_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_priority.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void ConfusedRulePriorityDemo(int iMax) 6 | { 7 | int iTemp = 10 << iMax + 3; 8 | } 9 | )delimiter"; 10 | 11 | SCENARIO("ConfusedRulePriority") { 12 | GIVEN("") { 13 | WHEN("Match condition") { 14 | THEN("Matching rule") { 15 | ConfusedRulePriority rule; 16 | CHECK(rule.detect(code1, "dd.h")); 17 | } 18 | } 19 | WHEN("Mismatch condition") { 20 | THEN("Mismatching rule") { 21 | ConfusedRulePriority rule; 22 | CHECK(!rule.detect("int iTemp = 10 << iMax;", "dd.h")); 23 | } 24 | } 25 | WHEN("just called") { 26 | THEN("called") { 27 | ConfusedRulePriority rule; 28 | rule.resetData(); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_prioritywithassignmentandcompare_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_prioritywithassignmentandcompare.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | if (auto ret = DetectorHelper::check(content, "(\\w+)\\s*->"); !ret.empty()) 6 | )delimiter"; 7 | SCENARIO("ConfusedRulePriorityWithAssignmentAndCompare") { 8 | GIVEN("") { 9 | WHEN("Match condition") { 10 | THEN("Matching rule") { 11 | ConfusedRulePriorityWithAssignmentAndCompare rule; 12 | CHECK(rule.detect("if (x = a < 0)", "dd.h")); 13 | CHECK(!rule.detect(code1, "dd.h")); 14 | } 15 | } 16 | WHEN("Mismatch condition") { 17 | THEN("Mismatching rule") { 18 | ConfusedRulePriorityWithAssignmentAndCompare rule; 19 | CHECK(!rule.detect("if (x = a)", "dd.h")); 20 | CHECK(!rule.detect(code1, "dd.h")); 21 | } 22 | } 23 | WHEN("just called") { 24 | THEN("called") { 25 | ConfusedRulePriorityWithAssignmentAndCompare rule; 26 | rule.resetData(); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_returnbool_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_returnbool.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | bool ConfusedRuleReturnBoolRetFunc() 6 | { 7 | if (rand() > 10) 8 | { 9 | return 10; 10 | } 11 | return 1; 12 | } 13 | )delimiter"; 14 | 15 | SCENARIO("ConfusedRuleReturnBool") { 16 | GIVEN("") { 17 | WHEN("Match condition") { 18 | THEN("Matching rule") { 19 | ConfusedRuleReturnBool rule; 20 | CHECK(rule.detect(code1, "dd.h")); 21 | } 22 | } 23 | WHEN("just called") { 24 | THEN("called") { 25 | ConfusedRuleReturnBool rule; 26 | rule.resetData(); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_semicolon_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_semicolon.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void ConfusedRuleSemicolonDemo(int iMax) 6 | { 7 | if (iMax > 0 && iMax != 3); 8 | { 9 | 10 | } 11 | } 12 | )delimiter"; 13 | 14 | static constexpr auto code2 = R"delimiter( 15 | void ConfusedRuleSemicolonDemo(int iMax) 16 | { 17 | do 18 | { 19 | int i = 0; 20 | } while (true); 21 | } 22 | )delimiter"; 23 | 24 | SCENARIO("ConfusedRuleSemicolon") { 25 | GIVEN("") { 26 | WHEN("Match condition") { 27 | THEN("Matching rule") { 28 | ConfusedRuleSemicolon rule; 29 | CHECK(rule.detect(code1, "dd.h")); 30 | } 31 | } 32 | WHEN("Mismatch condition") { 33 | THEN("Mismatching rule") { 34 | ConfusedRuleSemicolon rule; 35 | CHECK(!rule.detect(code2, "dd.h")); 36 | } 37 | } 38 | WHEN("just called") { 39 | THEN("called") { 40 | ConfusedRuleSemicolon rule; 41 | rule.resetData(); 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_statementoutsideofcase_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_statementOutsideOfcase.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void ConfusedRuleStatementOutsideOfCaseDemo(int b) 6 | { 7 | int c = 0; 8 | switch (b) 9 | { 10 | c = 3;// case之前不应该有代码 11 | case 2: 12 | // 13 | c = 2; 14 | break; 15 | default: 16 | break; 17 | } 18 | } 19 | )delimiter"; 20 | 21 | SCENARIO("ConfusedRuleStatementOutsideOfCase") { 22 | GIVEN("") { 23 | WHEN("Match condition") { 24 | THEN("Matching rule") { 25 | ConfusedRuleStatementOutsideOfCase rule; 26 | CHECK(rule.detect(code1, "dd.h")); 27 | } 28 | } 29 | WHEN("just called") { 30 | THEN("called") { 31 | ConfusedRuleStatementOutsideOfCase rule; 32 | rule.resetData(); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /unit_tests/detectors/confused/confusedrule_switchwihtoutdefault_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/confused/confusedrule_switchwihtoutdefault.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void ConfusedRuleStatementOutsideOfCaseDemo(int b) 6 | { 7 | int c = 0; 8 | switch (b) 9 | { 10 | case 2: 11 | c = 2; 12 | break; 13 | } 14 | int a = 6; 15 | } 16 | )delimiter"; 17 | 18 | static constexpr auto code2 = R"delimiter( 19 | void ConfusedRuleStatementOutsideOfCaseDemo(int b) 20 | { 21 | int c = 0; 22 | switch (b) 23 | { 24 | case 2: 25 | c = 2; 26 | break; 27 | default: 28 | c = 3; 29 | break; 30 | } 31 | int a = 6; 32 | } 33 | )delimiter"; 34 | 35 | SCENARIO("ConfusedRuleSwitchWithoutDefault") { 36 | GIVEN("") { 37 | WHEN("Match condition") { 38 | THEN("Matching rule") { 39 | ConfusedRuleSwitchWithoutDefault rule; 40 | CHECK(!rule.detect(code1, "dd.h")); 41 | rule.resetData(); 42 | CHECK(rule.getRuleErrors().size() == 1); 43 | } 44 | } 45 | WHEN("Mismatch condition") { 46 | THEN("Mismatching rule") { 47 | ConfusedRuleSwitchWithoutDefault rule; 48 | CHECK(!rule.detect(code2, "dd.h")); 49 | rule.resetData(); 50 | CHECK(rule.getRuleErrors().empty()); 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /unit_tests/detectors/detectors.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors) 2 | 3 | include(detectors/dynamic/dynamic.cmake) 4 | include(detectors/array/array.cmake) 5 | include(detectors/confused/confused.cmake) 6 | include(detectors/iterator/iterator.cmake) 7 | include(detectors/lambda/lambda.cmake) 8 | include(detectors/logic/logic.cmake) 9 | include(detectors/loop/loop.cmake) 10 | include(detectors/memleak/memleak.cmake) 11 | include(detectors/operation/operation.cmake) 12 | include(detectors/pointer/pointer.cmake) 13 | include(detectors/singleton/singleton.cmake) 14 | include(detectors/sizeof/sizeof.cmake) 15 | include(detectors/uninit/uninit.cmake) 16 | include(detectors/variable/variable.cmake) 17 | include(detectors/inline/inline.cmake) 18 | include(detectors/accesscontrol/accesscontrol.cmake) 19 | include(detectors/class/class.cmake) 20 | 21 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 22 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 23 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 24 | SET(SOURCES 25 | ${SOURCES} 26 | ${RECURSE_H} 27 | ) 28 | SET(HEADERS 29 | ${HEADERS} 30 | ${RECURSE_CPP} 31 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/dynamic/dynamic.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/dynamic) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/dynamic/dynamicrule_inline_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/dynamic/dynamicrule_inline.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | class OUTPUT Test 6 | { 7 | public: 8 | void f() {} 9 | }; 10 | 11 | class OUTPUT Test2 : public Test 12 | { 13 | public: 14 | void ff() 15 | { 16 | FF::dd(); 17 | } 18 | }; 19 | )delimiter"; 20 | 21 | SCENARIO("DynamicRuleInline") { 22 | GIVEN("") { 23 | WHEN("Match condition") { 24 | THEN("Matching rule") { 25 | DynamicRuleInline rule; 26 | CHECK(!rule.detect(code1, "dd.h")); 27 | rule.resetData(); 28 | CHECK(rule.getRuleErrors().size() == 1); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /unit_tests/detectors/dynamic/dynamicrule_localstatic_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/dynamic/dynamicrule_localstatic.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | class OUTPUT Test1() { 6 | static Test1& getInstance() { 7 | static Test1 test; 8 | return test; 9 | } 10 | } 11 | 12 | class OUTPUT Test2() { 13 | static Test2& getInstance() { 14 | static Test2 test; 15 | return test; 16 | } 17 | } 18 | )delimiter"; 19 | 20 | SCENARIO("DynamicRuleLocalStatic") { 21 | GIVEN("") { 22 | WHEN("Match condition") { 23 | THEN("Matching rule") { 24 | DynamicRuleLocalStatic rule; 25 | CHECK(rule.detect(code1, "dd.h")); 26 | CHECK(rule.getRuleErrors().size() == 2); 27 | } 28 | } 29 | WHEN("just called") { 30 | THEN("called") { 31 | DynamicRuleLocalStatic rule; 32 | rule.resetData(); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /unit_tests/detectors/inline/inline.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/inline) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/inline/inlinerule_complexfunction_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/inline/inlinerule_complexfunction.h" 3 | 4 | SCENARIO("InlineRuleComplexFunction") { 5 | GIVEN("") { 6 | WHEN("Match condition") { 7 | THEN("Matching rule") { 8 | InlineRuleComplexFunction rule; 9 | 10 | CHECK(!rule.detect("inline void func(){", "ss.h")); 11 | CHECK(rule.detect("for (", "ss.h")); 12 | 13 | CHECK(!rule.detect("inline void func(){", "ss.h")); 14 | CHECK(rule.detect("switch (", "ss.h")); 15 | 16 | CHECK(!rule.detect("inline void func(){", "ss.h")); 17 | CHECK(rule.detect("while (", "ss.h")); 18 | } 19 | } 20 | WHEN("Mismatch condition") { 21 | THEN("Mismatching rule") { 22 | InlineRuleComplexFunction rule; 23 | CHECK(!rule.detect("void func(){", "ss.h")); 24 | CHECK(!rule.detect("for (", "ss.h")); 25 | 26 | CHECK(!rule.detect("inline void func(){", "ss.h")); 27 | CHECK(!rule.detect("\"for (\"", "ss.h")); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /unit_tests/detectors/inline/inlinerule_recursion_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/inline/inlinerule_recursion.h" 3 | 4 | SCENARIO("InlineRuleRecursion") { 5 | GIVEN("") { 6 | WHEN("Match condition") { 7 | THEN("Matching rule") { 8 | InlineRuleRecursion rule; 9 | string ss = 10 | "inline void func(){\n" 11 | " func();\n" 12 | "}\n"; 13 | CHECK(rule.detect(ss, "ss.h")); 14 | } 15 | } 16 | WHEN("Mismatch condition") { 17 | THEN("Mismatching rule") { 18 | InlineRuleRecursion rule; 19 | string ss = 20 | "inline void func(){\n" 21 | " func1();\n" 22 | "}\n"; 23 | CHECK(!rule.detect(ss, "ss.h")); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /unit_tests/detectors/inline/inlinerule_specialclassmethod_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/inline/inlinerule_specialclassmethod.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | class AA { 6 | inline AA(){} 7 | inline ~AA(){} 8 | inline virtual DD(){} 9 | virtual DD1(){} 10 | inline DD2(){} override 11 | )delimiter"; 12 | 13 | SCENARIO("InlineRuleTenLines") { 14 | GIVEN("") { 15 | WHEN("Match condition") { 16 | THEN("Matching rule") { 17 | InlineRuleSpecialClassMethod rule; 18 | CHECK(rule.detect(code1, "ss.h")); 19 | } 20 | } 21 | WHEN("Mismatch condition") { 22 | THEN("Mismatching rule") { 23 | InlineRuleSpecialClassMethod rule; 24 | CHECK(!rule.detect("ffg", "ss.cpp")); 25 | } 26 | } 27 | WHEN("just called") { 28 | THEN("called") { 29 | InlineRuleSpecialClassMethod rule; 30 | rule.resetData(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /unit_tests/detectors/inline/inlinerule_tenlines_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/inline/inlinerule_tenlines.h" 3 | 4 | static constexpr auto sss = R"delimiter( 5 | inline void func(){ 6 | int i = 0; 7 | int i = 0; 8 | int i = 0; 9 | int i = 0; 10 | int i = 0; 11 | int i = 0; 12 | int i = 0; 13 | int i = 0; 14 | int i = 0; 15 | int i = 0; 16 | int i = 0; 17 | } 18 | )delimiter"; 19 | SCENARIO("InlineRuleSpecialClassMethod") { 20 | GIVEN("") { 21 | WHEN("Match condition") { 22 | THEN("Matching rule") { 23 | InlineRuleTenLines rule; 24 | CHECK(!rule.detect("void func(){int i = 0;}", "ss.h")); 25 | CHECK(!rule.detect("inline void func(){int i = 0;}", "ss.h")); 26 | CHECK(!rule.detect("void func() {\n int i = 0;}", "ss.h")); 27 | CHECK(rule.detect(sss, "ss.h")); 28 | } 29 | } 30 | WHEN("Mismatch condition") { 31 | THEN("Mismatching rule") { 32 | InlineRuleTenLines rule; 33 | CHECK(!rule.detect("void func(){int i = 0;}", "ss.cpp")); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /unit_tests/detectors/iterator/iterator.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/iterator) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/iterator/iteratorrule_invaliddereference_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/iterator/iteratorrule_invaliddereference.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void IteratorRuleInvalidDereferenceDemo() 6 | { 7 | std::vector& ivec; 8 | std::vector::iterator iter = ivec.begin(); 9 | if (iter == ivec.end()){ 10 | iter->value_type; 11 | cout << *iter; 12 | } 13 | } 14 | )delimiter"; 15 | 16 | static constexpr auto code2 = R"delimiter( 17 | void IteratorRuleInvalidDereferenceDemo2() 18 | { 19 | std::vector& ivec; 20 | std::vector::iterator iter = ivec.begin(); 21 | if (ivec.end() == ivec.find(3)) 22 | { 23 | ivec.find(3)->value_type; 24 | cout << *(ivec.find(3)); 25 | } 26 | } 27 | )delimiter"; 28 | 29 | SCENARIO("IteratorRuleInvalidDereference") { 30 | GIVEN("") { 31 | WHEN("Match condition") { 32 | THEN("Matching rule") { 33 | IteratorRuleInvalidDereference rule; 34 | CHECK(rule.detect(code1, "ss.h")); 35 | CHECK(rule.detect(code2, "ss.h")); 36 | } 37 | } 38 | WHEN("just called") { 39 | THEN("called") { 40 | IteratorRuleInvalidDereference rule; 41 | rule.resetData(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /unit_tests/detectors/iterator/iteratorrule_outofbound_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/iterator/iteratorrule_outofbound.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void IteratorRuleOutOfBoundDemo() 6 | { 7 | std::vector foo; 8 | for (unsigned int ii = 0; ii <= foo.size(); ++ii) 9 | { 10 | foo[ii] = 0; 11 | } 12 | } 13 | )delimiter"; 14 | 15 | static constexpr auto code2 = R"delimiter( 16 | void IteratorRuleOutOfBoundDemo2() 17 | { 18 | std::vector foo; 19 | auto ss = foo.size(); 20 | for (unsigned int ii = 0; ii <= ss; ++ii) 21 | { 22 | foo[ii] = 0; 23 | } 24 | } 25 | )delimiter"; 26 | 27 | SCENARIO("IteratorRuleOutOfBound") { 28 | GIVEN("") { 29 | WHEN("Match condition") { 30 | THEN("Matching rule1") { 31 | IteratorRuleOutOfBound rule; 32 | CHECK(rule.detect(code1, "ss.h")); 33 | } 34 | THEN("Matching rule2") { 35 | IteratorRuleOutOfBound rule; 36 | CHECK(rule.detect(code2, "ss.h")); 37 | } 38 | } 39 | WHEN("just called") { 40 | THEN("called") { 41 | IteratorRuleOutOfBound rule; 42 | rule.resetData(); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /unit_tests/detectors/lambda/lambda.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/lambda) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/lambda/lambdarule_catchbyreference_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/lambda/lambdarule_catchbyreference.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void fontManger(startTransferProgram, [&](const int errorCode, const std::string& result) { 6 | } 7 | )delimiter"; 8 | 9 | static constexpr auto code2 = R"delimiter( 10 | void fontManger(startTransferProgram, [=](const int errorCode, const std::string& result) { 11 | } 12 | )delimiter"; 13 | 14 | static constexpr auto code3 = R"delimiter( 15 | void fontManger(startTransferProgram, [param1](const int errorCode, const std::string& result) { 16 | } 17 | )delimiter"; 18 | 19 | SCENARIO("LambdaRuleCatchByReference") { 20 | GIVEN("") { 21 | WHEN("Match condition") { 22 | THEN("Matching rule") { 23 | LambdaRuleCatchByReference rule; 24 | CHECK(rule.detect(code1, "ss.h")); 25 | } 26 | } 27 | WHEN("Mismatch condition") { 28 | THEN("Mismatching rule1") { 29 | LambdaRuleCatchByReference rule; 30 | CHECK(!rule.detect(code2, "ss.cpp")); 31 | } 32 | THEN("Mismatching rule2") { 33 | LambdaRuleCatchByReference rule; 34 | CHECK(!rule.detect(code3, "ss.cpp")); 35 | } 36 | } 37 | WHEN("just called") { 38 | THEN("called") { 39 | LambdaRuleCatchByReference rule; 40 | rule.resetData(); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /unit_tests/detectors/logic/logic.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/logic) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/logic/logicrule_assignself_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/logic/logicrule_assignself.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void LogicRuleAssignSelfDemo() 6 | { 7 | int i; 8 | i = i; 9 | } 10 | )delimiter"; 11 | 12 | SCENARIO("LogicRuleAssignSelf") { 13 | GIVEN("") { 14 | WHEN("Match condition") { 15 | THEN("Matching rule") { 16 | LogicRuleAssignSelf rule; 17 | CHECK(rule.detect(code1, "dd.h")); 18 | } 19 | } 20 | WHEN("just called") { 21 | THEN("called") { 22 | LogicRuleAssignSelf rule; 23 | rule.resetData(); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /unit_tests/detectors/logic/logicrule_basevalue_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/logic/logicrule_basevalue.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void LogicRuleBaseValueDemo() 6 | { 7 | if (1) {}; 8 | if (0) {}; 9 | if (true) {}; 10 | if (false) {}; 11 | } 12 | )delimiter"; 13 | 14 | SCENARIO("LogicRuleBaseValue") { 15 | GIVEN("") { 16 | WHEN("Match condition") { 17 | THEN("Matching rule") { 18 | LogicRuleBaseValue rule; 19 | CHECK(rule.detect(code1, "dd.h")); 20 | } 21 | } 22 | WHEN("just called") { 23 | THEN("called") { 24 | LogicRuleBaseValue rule; 25 | rule.resetData(); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /unit_tests/detectors/logic/logicrule_incorrectoperation_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/logic/logicrule_basevalue.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void LogicRuleIncorrectOperationDemo() 6 | { 7 | if ((a != 1) || (a != 3)) {} 8 | if ((a == 1) && (a == 3)) {} 9 | } 10 | )delimiter"; 11 | 12 | SCENARIO("LogicRuleIncorrectOperation") { 13 | GIVEN("") { 14 | WHEN("Match condition") { 15 | THEN("Matching rule") { 16 | LogicRuleBaseValue rule; 17 | CHECK(rule.detect("if (1)", "dd.h")); 18 | CHECK(rule.detect("if (0)", "dd.h")); 19 | CHECK(rule.detect("if (true)", "dd.h")); 20 | CHECK(rule.detect("if (false)", "dd.h")); 21 | } 22 | THEN("Matching rule") { 23 | LogicRuleBaseValue rule; 24 | //todo 25 | //CHECK(rule.detect(code1, "dd.h")); 26 | } 27 | } 28 | WHEN("just called") { 29 | THEN("called") { 30 | LogicRuleBaseValue rule; 31 | rule.resetData(); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /unit_tests/detectors/logic/logicrule_stringfind_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/logic/logicrule_stringfind.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void Demo(std::string &str, std::string &search) 6 | { 7 | // string的find返回的结果应该跟string::npos来判定 8 | if( string::npos <= str.find(search)) 9 | { 10 | 11 | } 12 | if( 0 == str.find(search)) 13 | { 14 | } 15 | } 16 | )delimiter"; 17 | 18 | static constexpr auto code2 = R"delimiter( 19 | void LogicRuleStringFindDemo(std::string& str, std::string& search) 20 | { 21 | if (0 <= str.find(search)) 22 | { 23 | } 24 | } 25 | )delimiter"; 26 | 27 | SCENARIO("LogicRuleStringFind") { 28 | GIVEN("") { 29 | WHEN("Match condition") { 30 | THEN("Matching rule") { 31 | LogicRuleStringFind rule; 32 | CHECK(rule.detect(code1, "dd")); 33 | } 34 | THEN("Matching rule") { 35 | LogicRuleStringFind rule; 36 | CHECK(rule.detect(code2, "dd")); 37 | } 38 | } 39 | WHEN("just called") { 40 | THEN("called") { 41 | LogicRuleStringFind rule; 42 | rule.resetData(); 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /unit_tests/detectors/loop/loop.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/loop) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/loop/looprule_helper_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/loop/looprule_helper.h" 3 | 4 | SCENARIO("LoopRuleHelper") { 5 | GIVEN("") { 6 | WHEN("") { 7 | THEN("no explicit") { 8 | LoopRuleHelper helper; 9 | //CHECK(helper.findNotAutoFromFor 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /unit_tests/detectors/loop/looprule_outofbounds_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/loop/looprule_outofbounds.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void LoopRuleOutOfBoundsDemo(std::string& str, char ch) 6 | { 7 | for (std::string::const_iterator iter = str.begin(); iter != str.end(); ++iter) 8 | { 9 | if (*(iter + 1) == ch) 10 | { 11 | } 12 | } 13 | } 14 | )delimiter"; 15 | 16 | SCENARIO("LoopRuleOutOfBounds") { 17 | GIVEN("") { 18 | WHEN("Match condition") { 19 | THEN("Matching rule") { 20 | LoopRuleOutOfBounds rule; 21 | CHECK(rule.detect(code1, "dd")); 22 | } 23 | } 24 | WHEN("Mismatch condition") { 25 | THEN("Mismatching rule") { 26 | LoopRuleOutOfBounds rule; 27 | CHECK(!rule.detect(" for (int i = 64; i < len; i += 64) {", "dd")); 28 | CHECK(!rule.detect(" if (pubKey[i] != '\n') {", "dd")); 29 | } 30 | } 31 | WHEN("just called") { 32 | THEN("called") { 33 | LoopRuleOutOfBounds rule; 34 | rule.resetData(); 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /unit_tests/detectors/loop/looprule_suggestauto_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/loop/looprule_suggestauto.h" 3 | 4 | SCENARIO("LoopRuleSuggestauto") { 5 | GIVEN("") { 6 | WHEN("Mismatch condition") { 7 | THEN("Mismatching rule") { 8 | LoopRuleSuggestauto rule; 9 | CHECK(rule.detect(" for (int i = 64; i < len; i += 64) {", "dd")); 10 | } 11 | } 12 | WHEN("Mismatch condition") { 13 | THEN("Mismatching rule") { 14 | LoopRuleSuggestauto rule; 15 | CHECK(!rule.detect(" for (auto i = 64; i < len; i += 64) {", "dd")); 16 | } 17 | } 18 | WHEN("just called") { 19 | THEN("called") { 20 | LoopRuleSuggestauto rule; 21 | rule.resetData(); 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /unit_tests/detectors/loop/looprule_wrongstepdirection_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/loop/looprule_wrongstepdirection.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void LoopRuleWrongVariableDemo(int iMax) 6 | { 7 | for (int i = 0; i < iMax; --i) 8 | { 9 | 10 | } 11 | } 12 | )delimiter"; 13 | 14 | static constexpr auto code2 = R"delimiter( 15 | void LoopRuleWrongVariableDemo(int iMax) 16 | { 17 | for (int i = iMax - 1; i > 0; ++i) 18 | { 19 | 20 | } 21 | } 22 | )delimiter"; 23 | 24 | SCENARIO("LoopRuleWrongStepDirection") { 25 | GIVEN("") { 26 | WHEN("Match condition") { 27 | THEN("Matching rule1") { 28 | LoopRuleWrongStepDirection rule; 29 | CHECK(rule.detect(code1, "dd")); 30 | } 31 | THEN("Matching rule2") { 32 | LoopRuleWrongStepDirection rule; 33 | CHECK(rule.detect(code2, "dd")); 34 | } 35 | } 36 | WHEN("just called") { 37 | THEN("called") { 38 | LoopRuleWrongStepDirection rule; 39 | rule.resetData(); 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /unit_tests/detectors/loop/looprule_wrongvariable_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/loop/looprule_wrongvariable.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void LoopRuleWrongVariableDemo(int iMax) 6 | { 7 | for (int i = 0; i < iMax; ++j) 8 | { 9 | 10 | } 11 | } 12 | )delimiter"; 13 | 14 | SCENARIO("LoopRuleWrongVariable") { 15 | GIVEN("") { 16 | WHEN("Mismatch condition") { 17 | THEN("Mismatching rule") { 18 | LoopRuleWrongVariable rule; 19 | CHECK(rule.detect(code1, "dd")); 20 | } 21 | } 22 | WHEN("just called") { 23 | THEN("called") { 24 | LoopRuleWrongVariable rule; 25 | rule.resetData(); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /unit_tests/detectors/loop/loopruleoutofbounds_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include 3 | #include "detectors/loop/looprule_outofbounds.h" 4 | 5 | SCENARIO("LoopRuleOutOfBounds") { 6 | GIVEN("") { 7 | WHEN("") { 8 | THEN("no explicit") { 9 | LoopRuleOutOfBounds rule; 10 | CHECK(!rule.detect(" for (int i = 64; i < len; i += 64) {", "dd")); 11 | CHECK(!rule.detect(" if (pubKey[i] != '\n') {", "dd")); 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /unit_tests/detectors/memleak/memleak.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/memleak) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/memleak/memleakrule_filehandle_tests.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Hualong Zhang on 2021/4/26. 3 | // 4 | #include "../../doctest.h" 5 | #include "detectors/memleak/memleakrule_filehandle.h" 6 | 7 | static constexpr auto code1 = R"delimiter( 8 | void MemLeakRuleFileHandleDemo1() 9 | { 10 | FILE* pFile = fopen("c:\\test.txt", "w+"); 11 | } 12 | )delimiter"; 13 | 14 | static constexpr auto code2 = R"delimiter( 15 | void MemLeakRuleFileHandleDemo2() 16 | { 17 | FILE* pFile = fopen("c:\\test.txt", "w+"); 18 | fclose(pFile); 19 | } 20 | )delimiter"; 21 | 22 | SCENARIO("MemLeakRuleFileHandle") { 23 | GIVEN("") { 24 | WHEN("Match condition") { 25 | THEN("Matching rule1") { 26 | MemLeakRuleFileHandle rule; 27 | rule.detect(code1, "dd.h"); 28 | rule.resetData(); 29 | CHECK(rule.getRuleErrors().size() == 1); 30 | } 31 | THEN("Matching rule2") { 32 | MemLeakRuleFileHandle rule; 33 | rule.detect(code2, "dd.h"); 34 | rule.resetData(); 35 | CHECK(rule.getRuleErrors().empty()); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /unit_tests/detectors/memleak/memleakrule_mallocfree_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/memleak/memleakrule_destructor.h" 3 | #include "../../../detector_core/detectors/memleak/memleakrule_mallocfree.h" 4 | 5 | static constexpr auto code1 = R"delimiter( 6 | void MemLeakRuleReallocDemo() 7 | { 8 | char* buf = (char*)malloc(10); 9 | char* p = buf[1]; 10 | buf = (char*)realloc(buf, 100); 11 | *p = 'a'; 12 | free(buf); 13 | } 14 | )delimiter"; 15 | 16 | SCENARIO("MemLeakRuleMallocFree") { 17 | GIVEN("") { 18 | WHEN("Match condition") { 19 | THEN("Matching rule") { 20 | MemLeakRuleMallocFree rule; 21 | CHECK(rule.detect(code1, "dd.h")); 22 | } 23 | } 24 | WHEN("just called") { 25 | THEN("called") { 26 | MemLeakRuleMallocFree rule; 27 | rule.resetData(); 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /unit_tests/detectors/memleak/memleakrule_newwithoutdelete_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/memleak/memleakrule_newwithoutdelete.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void MemLeakRuleNewWithOutDeleteDemo() 6 | { 7 | char* p = new char; 8 | p = nullptr; 9 | } 10 | )delimiter"; 11 | 12 | static constexpr auto code2 = R"delimiter( 13 | void MemLeakRuleNewWithOutDeleteDemo() 14 | { 15 | char* p = new char; 16 | delete p; 17 | p = nullptr; 18 | } 19 | )delimiter"; 20 | 21 | SCENARIO("MemLeakRuleNewWithOutDelete") { 22 | GIVEN("") { 23 | WHEN("Match condition") { 24 | THEN("Matching rule") { 25 | MemLeakRuleNewWithOutDelete rule; 26 | rule.detect(code1, "dd.h"); 27 | rule.resetData(); 28 | CHECK(rule.getRuleErrors().size() == 1); 29 | } 30 | } 31 | WHEN("Mismatch condition") { 32 | THEN("Mismatching rule") { 33 | MemLeakRuleNewWithOutDelete rule; 34 | rule.detect(code2, "dd.h"); 35 | rule.resetData(); 36 | CHECK(rule.getRuleErrors().empty()); 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /unit_tests/detectors/memleak/memleakrule_realloc_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/memleak/memleakrule_realloc.h" 3 | 4 | static constexpr auto code1 = R"delimiter( 5 | void MemLeakRuleReallocDemo() 6 | { 7 | char* buf = (char*)malloc(10); 8 | char* p = buf[1]; 9 | buf = (char*)realloc(buf, 100); 10 | *p = 'a'; 11 | free(buf); 12 | } 13 | )delimiter"; 14 | 15 | SCENARIO("MemLeakRuleRealloc") { 16 | GIVEN("") { 17 | WHEN("Match condition") { 18 | THEN("Matching rule") { 19 | MemLeakRuleRealloc rule; 20 | CHECK(rule.detect(code1, "dd.h")); 21 | } 22 | } 23 | WHEN("just called") { 24 | THEN("called") { 25 | MemLeakRuleRealloc rule; 26 | rule.resetData(); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /unit_tests/detectors/operation/operation.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/operation) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/pointer/pointer.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/pointer) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/pointer/pointerrule_usedinsideofnullcheck_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/pointer/pointerrule_usedinsideofnullcheck.h" 3 | 4 | static constexpr auto content1 = R"delimiter( 5 | int Demo(STNullPointer* npSt) 6 | { 7 | if(!npSt) 8 | { 9 | // npSt为空时解引用 10 | int nResult = npSt->m_node; 11 | return nResult; 12 | } 13 | return 0; 14 | } 15 | )delimiter"; 16 | 17 | static constexpr auto content2 = R"delimiter( 18 | int Demo(STNullPointer* npSt) 19 | { 20 | if(npSt == nullptr) 21 | { 22 | // npSt为空时解引用 23 | int nResult = npSt->m_node; 24 | return nResult; 25 | } 26 | return 0; 27 | } 28 | )delimiter"; 29 | 30 | static constexpr auto content3 = R"delimiter( 31 | int Demo(STNullPointer* npSt) 32 | { 33 | // if条件表达式存在逻辑漏洞,&&应该换成|| 34 | if(npSt == nullptr && npSt->m_node) 35 | { 36 | return nResult; 37 | } 38 | return 0; 39 | } 40 | )delimiter"; 41 | 42 | SCENARIO("PointerRuleUsedInsideOfNULLCheck") { 43 | GIVEN("") { 44 | WHEN("") { 45 | THEN("no explicit") { 46 | PointerRuleUsedInsideOfNULLCheck rule; 47 | CHECK(rule.detect(content1, "dd")); 48 | } 49 | THEN("no explicit") { 50 | PointerRuleUsedInsideOfNULLCheck rule; 51 | CHECK(rule.detect(content2, "dd")); 52 | } 53 | THEN("no explicit") { 54 | PointerRuleUsedInsideOfNULLCheck rule; 55 | CHECK(rule.detect(content3, "dd")); 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /unit_tests/detectors/pointer/pointerrule_usednull_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "../../doctest.h" 2 | #include "detectors/pointer/pointerrule_usednull.h" 3 | 4 | static constexpr auto content = R"delimiter( 5 | void func() 6 | { 7 | IWbemClassObject *pclsObj = nullptr; 8 | ULONG uReturn = 0; 9 | HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 10 | if (0 == uReturn) 11 | { 12 | break; 13 | } 14 | VARIANT vtProp; 15 | hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0); 16 | } 17 | )delimiter"; 18 | 19 | SCENARIO("PointerRuleUsedNull") { 20 | GIVEN("") { 21 | WHEN("") { 22 | THEN("no explicit") { 23 | PointerRuleUsedNull rule; 24 | CHECK(!rule.detect(content, "dd")); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /unit_tests/detectors/singleton/singleton.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/singleton) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/sizeof/sizeof.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/sizeof) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/uninit/uninit.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/uninit) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/detectors/variable/variable.cmake: -------------------------------------------------------------------------------- 1 | SET(DIR_NAME detectors/variable) 2 | 3 | FILE(GLOB_RECURSE RECURSE_H "./${DIR_NAME}/*.h*") 4 | FILE(GLOB_RECURSE RECURSE_CPP "./${DIR_NAME}/*.cpp") 5 | SOURCE_GROUP("${DIR_NAME}" FILES ${RECURSE_H} ${RECURSE_CPP}) 6 | SET(SOURCES 7 | ${SOURCES} 8 | ${RECURSE_H} 9 | ) 10 | SET(HEADERS 11 | ${HEADERS} 12 | ${RECURSE_CPP} 13 | ) -------------------------------------------------------------------------------- /unit_tests/unit_tests.cmake: -------------------------------------------------------------------------------- 1 | message(_HIBLUE_ "---Start---Configuring catch_tests:") 2 | 3 | include(detectors/detectors.cmake) 4 | include(common/common.cmake) 5 | include(detectorcommon/detectorcommon.cmake) 6 | FILE(GLOB_RECURSE CATCH_TESTS_H "*.h") 7 | FILE(GLOB_RECURSE CATCH_TESTS_CPP "*.cpp") 8 | SET(SOURCES 9 | ${SOURCES} 10 | ${CATCH_TESTS_CPP} 11 | ) 12 | SET(HEADERS 13 | ${HEADERS} 14 | ${CATCH_TESTS_H} 15 | ) --------------------------------------------------------------------------------