1#!/bin/bash 2# Note: tested with cppcheck 1.72 as shipped with Ubuntu 16.04 3# as well as with cppcheck 1.76.1 4 5set -eu 6 7SCRIPT_DIR=$(dirname "$0") 8case $SCRIPT_DIR in 9 "/"*) 10 ;; 11 ".") 12 SCRIPT_DIR=$(pwd) 13 ;; 14 *) 15 SCRIPT_DIR=$(pwd)/$(dirname "$0") 16 ;; 17esac 18GDAL_ROOT=$SCRIPT_DIR/.. 19cd "$GDAL_ROOT" 20 21 22LOG_FILE=/tmp/cppcheck_gdal.txt 23 24CPPCHECK_VERSION="$(cppcheck --version | awk '{print $2}')" 25if test $(expr $CPPCHECK_VERSION \>= 1.84) = 1; then 26 OVERRIDE= 27else 28 OVERRIDE="-Doverride=" 29fi 30 31echo "" > ${LOG_FILE} 32for dirname in alg port gcore ogr frmts gnm apps fuzzers; do 33 printf "Running cppcheck on %s (can be long): " "$dirname" 34 cppcheck --inline-suppr --template='{file}:{line},{severity},{id},{message}' \ 35 --enable=all --inconclusive --std=posix -UAFL_FRIENDLY -UANDROID \ 36 -UCOMPAT_WITH_ICC_CONVERSION_CHECK -DDEBUG -UDEBUG_BOOL -DHAVE_CXX11=1 \ 37 -D__linux \ 38 -DGBool=int -DCPL_HAS_GINT64=1 -DHAVE_GEOS -DHAVE_EXPAT -DHAVE_XERCES -DCOMPILATION_ALLOWED \ 39 -DHAVE_SFCGAL -DHAVE_SPATIALITE -DSPATIALITE_412_OR_LATER \ 40 -DHAVE_SQLITE -DSQLITE_VERSION_NUMBER=3006000 -DHAVE_SQLITE_VFS \ 41 -DHAVE_RASTERLITE2 \ 42 -DHAVE_CURL -DLIBCURL_VERSION_NUM=0x073800 \ 43 -DPTHREAD_MUTEX_RECURSIVE -DCPU_LITTLE_ENDIAN -DCPL_IS_LSB=1 \ 44 -DKDU_MAJOR_VERSION=7 -DKDU_MINOR_VERSION=5 \ 45 -DHAVE_JASPER_UUID \ 46 -D__GNUC__==5 -DGDAL_COMPILATION \ 47 -DODBCVER=0x0300 \ 48 -DNETCDF_HAS_NC4 \ 49 -DJPEG_SUPPORTED \ 50 -DJPEG_DUAL_MODE_8_12 \ 51 -D_TOOLKIT_IN_DLL_ \ 52 -UGDAL_NO_AUTOLOAD \ 53 -DHAVE_MITAB \ 54 -Dva_copy=va_start \ 55 -D__cplusplus=201103 \ 56 -DVSIRealloc=realloc \ 57 -DCPPCHECK \ 58 -DDEBUG_MUTEX \ 59 -DDEBUG_PROXY_POOL \ 60 ${OVERRIDE} \ 61 -DOCAD_EXTERN= \ 62 -DTIFFLIB_VERSION=99999999 \ 63 -DHAVE_SSE_AT_COMPILE_TIME \ 64 -DHAVE_LIBXML2 \ 65 -DCPL_INTERNAL= \ 66 -DCHAR_BIT=8 \ 67 -DUCHAR_MAX=255 \ 68 -DSHRT_MIN=-32768 \ 69 -DSHRT_MAX=32767 \ 70 -DUSHRT_MAX=65535 \ 71 -DINT_MIN=-2147483648 \ 72 -DINT_MAX=2147483647 \ 73 -DUINT_MAX=4294967295U \ 74 --include=port/cpl_config.h \ 75 --include=port/cpl_port.h \ 76 -I port -I gcore -I ogr -I ogr/ogrsf_frmts -I ogr/ogrsf_frmts/geojson \ 77 -I ogr/ogrsf_frmts/geojson/libjson \ 78 -i cpl_mem_cache.h \ 79 -i ogrdissolve.cpp \ 80 -i gdalasyncread.cpp \ 81 -i gdaltorture.cpp \ 82 $dirname \ 83 -j "$(nproc)" >>${LOG_FILE} 2>&1 & 84 # Display some progress to avoid Travis-CI killing the job after 10 minutes 85 PID=$! 86 while kill -0 $PID 2>/dev/null; do 87 printf "." 88 sleep 1 89 done 90 echo " done" 91 if ! wait $PID; then 92 echo "cppcheck failed" 93 exit 1 94 fi 95done 96 97ret_code=0 98 99grep -v "unmatchedSuppression" ${LOG_FILE} | grep -v -e " yacc.c" -e PublicDecompWT -e "kdu_cache_wrapper.h" > ${LOG_FILE}.tmp 100mv ${LOG_FILE}.tmp ${LOG_FILE} 101 102# I don't want to care about SDE 103grep -v -e "frmts/sde" -e "ogr/ogrsf_frmts/sde" ${LOG_FILE} > ${LOG_FILE}.tmp 104mv ${LOG_FILE}.tmp ${LOG_FILE} 105 106# I don't want to care about flatbuffers 107grep -v -e "ogr/ogrsf_frmts/flatgeobuf/flatbuffers" ${LOG_FILE} > ${LOG_FILE}.tmp 108mv ${LOG_FILE}.tmp ${LOG_FILE} 109 110# False positive deallocuse 111grep -v -e "frmts/png/libpng/png.c" ${LOG_FILE} > ${LOG_FILE}.tmp 112mv ${LOG_FILE}.tmp ${LOG_FILE} 113 114if grep "null pointer" ${LOG_FILE} ; then 115 echo "Null pointer check failed" 116 ret_code=1 117fi 118 119if grep "duplicateBreak" ${LOG_FILE} ; then 120 echo "duplicateBreak check failed" 121 ret_code=1 122fi 123 124if grep "duplicateBranch" ${LOG_FILE} ; then 125 echo "duplicateBranch check failed" 126 ret_code=1 127fi 128 129if grep "uninitMemberVar" ${LOG_FILE} ; then 130 echo "uninitMemberVar check failed" 131 ret_code=1 132fi 133 134if grep "useInitializationList" ${LOG_FILE} ; then 135 echo "uninitMemberVar check failed" 136 ret_code=1 137fi 138 139if grep "clarifyCalculation" ${LOG_FILE} ; then 140 echo "clarifyCalculation check failed" 141 ret_code=1 142fi 143 144if grep "invalidPrintfArgType_uint" ${LOG_FILE} ; then 145 echo "invalidPrintfArgType_uint check failed" 146 ret_code=1 147fi 148 149if grep "catchExceptionByValue" ${LOG_FILE} ; then 150 echo "catchExceptionByValue check failed" 151 ret_code=1 152fi 153 154grep "memleakOnRealloc" ${LOG_FILE} | grep frmts/hdf4/hdf-eos > /dev/null && echo "memleakOnRealloc issues in frmts/hdf4/hdf-eos ignored" 155grep "memleakOnRealloc" ${LOG_FILE} | grep frmts/grib/degrib > /dev/null && echo "memleakOnRealloc issues in frmts/grib/degrib ignored" 156 157if grep "memleakOnRealloc" ${LOG_FILE} | grep -v -e frmts/hdf4/hdf-eos -e frmts/grib/degrib ; then 158 echo "memleakOnRealloc check failed" 159 ret_code=1 160fi 161 162# Those warnings in libjpeg seems to be false positives 163#grep "arrayIndexOutOfBoundsCond" ${LOG_FILE} | grep frmts/jpeg/libjpeg > /dev/null && echo "arrayIndexOutOfBoundsCond issues in frmts/jpeg/libjpeg ignored" 164if grep "arrayIndexOutOfBoundsCond" ${LOG_FILE} | grep -v frmts/jpeg/libjpeg ; then 165 echo "arrayIndexOutOfBoundsCond check failed" 166 ret_code=1 167fi 168 169grep "arrayIndexOutOfBounds," ${LOG_FILE} | grep frmts/hdf4/hdf-eos > /dev/null && echo "arrayIndexOutOfBounds issues in frmts/hdf4/hdf-eos ignored" 170if grep "arrayIndexOutOfBounds," ${LOG_FILE} | grep -v frmts/hdf4/hdf-eos ; then 171 echo "arrayIndexOutOfBounds check failed" 172 ret_code=1 173fi 174 175if grep "syntaxError" ${LOG_FILE} | grep -v "is invalid C code" ; then 176 echo "syntaxError check failed" 177 ret_code=1 178fi 179 180grep "memleak," ${LOG_FILE} | grep frmts/hdf4/hdf-eos > /dev/null && echo "memleak issues in frmts/hdf4/hdf-eos ignored" 181grep "memleak," ${LOG_FILE} | grep frmts/grib/degrib > /dev/null && echo "memleak issues in frmts/grib/degrib ignored" 182if grep "memleak," ${LOG_FILE} | grep -v -e frmts/hdf4/hdf-eos -e frmts/grib/degrib ; then 183 echo "memleak check failed" 184 ret_code=1 185fi 186 187if grep "eraseDereference" ${LOG_FILE} ; then 188 echo "eraseDereference check failed" 189 ret_code=1 190fi 191 192if grep "memsetClass," ${LOG_FILE} ; then 193 echo "memsetClass check failed" 194 ret_code=1 195fi 196 197# Most if not all of them are false positives 198grep "uninitvar," ${LOG_FILE} | grep frmts/hdf4/hdf-eos > /dev/null && echo "(potential) uninitvar issues in frmts/hdf4/hdf-eos ignored" 199grep "uninitvar," ${LOG_FILE} | grep frmts/grib/degrib > /dev/null && echo "(potential) uninitvar issues in frmts/grib/degrib ignored" 200grep "uninitvar," ${LOG_FILE} | grep frmts/gtiff/libtiff > /dev/null && echo "(potential) uninitvar issues in frmts/gtiff/libtiff ignored" 201grep "uninitvar," ${LOG_FILE} | grep frmts/gtiff/libgeotiff > /dev/null && echo "(potential) uninitvar issues in frmts/gtiff/libgeotiff ignored" 202grep "uninitvar," ${LOG_FILE} | grep frmts/jpeg/libjpeg > /dev/null && echo "(potential) uninitvar issues in frmts/jpeg/libjpeg ignored" 203grep "uninitvar," ${LOG_FILE} | grep frmts/gif/giflib > /dev/null && echo "(potential) uninitvar issues in frmts/gif/giflib ignored" 204grep "uninitvar," ${LOG_FILE} | grep frmts/png/libpng > /dev/null && echo "(potential) uninitvar issues in frmts/png/libpng ignored" 205grep "uninitvar," ${LOG_FILE} | grep frmts/zlib > /dev/null && echo "(potential) uninitvar issues in frmts/zlib ignored" 206grep "uninitvar," ${LOG_FILE} | grep ogr/ogrsf_frmts/geojson/libjson > /dev/null && echo "(potential) uninitvar issues in ogr/ogrsf_frmts/geojson/libjson ignored" 207 208if grep "uninitvar," ${LOG_FILE} | grep -v -e frmts/hdf4/hdf-eos \ 209 -e frmts/grib/degrib -e frmts/gtiff/libtiff -e frmts/gtiff/libgeotiff \ 210 -e frmts/jpeg/libjpeg -e frmts/gif/giflib -e frmts/png/libpng \ 211 -e frmts/zlib -e ogr/ogrsf_frmts/geojson/libjson \ 212 -e osr_cs_wkt_parser.c ; then 213 echo "uninitvar check failed" 214 ret_code=1 215fi 216 217grep "uninitdata," ${LOG_FILE} | grep "frmts/grib/degrib/g2clib" > /dev/null && echo "(potential) uninitdata issues in frmts/grib/degrib/g2clib ignored" 218 219if grep "uninitdata," ${LOG_FILE} | grep -v "frmts/grib/degrib/g2clib" ; then 220 echo "uninitdata check failed" 221 ret_code=1 222fi 223 224if grep "va_list_usedBeforeStarted" ${LOG_FILE} ; then 225 echo "va_list_usedBeforeStarted check failed" 226 ret_code=1 227fi 228 229if grep "duplInheritedMember" ${LOG_FILE} ; then 230 echo "duplInheritedMember check failed" 231 ret_code=1 232fi 233 234if grep "terminateStrncpy" ${LOG_FILE} ; then 235 echo "terminateStrncpy check failed" 236 ret_code=1 237fi 238 239if grep "operatorEqVarError" ${LOG_FILE} ; then 240 echo "operatorEqVarError check failed" 241 ret_code=1 242fi 243 244if grep "uselessAssignmentPtrArg" ${LOG_FILE} | grep -v -e swq_parser.cpp -e osr_cs_wkt_parser.c -e ods_formula_parser.cpp ; then 245 echo "uselessAssignmentPtrArg check failed" 246 ret_code=1 247fi 248 249if grep "bufferNotZeroTerminated" ${LOG_FILE} ; then 250 echo "bufferNotZeroTerminated check failed" 251 ret_code=1 252fi 253 254if grep "sizeofDivisionMemfunc" ${LOG_FILE} ; then 255 echo "sizeofDivisionMemfunc check failed" 256 ret_code=1 257fi 258 259if grep "selfAssignment" ${LOG_FILE} ; then 260 echo "selfAssignment check failed" 261 ret_code=1 262fi 263 264if grep "invalidPrintfArgType_sint" ${LOG_FILE} ; then 265 echo "invalidPrintfArgType_sint check failed" 266 ret_code=1 267fi 268 269if grep "redundantAssignInSwitch" ${LOG_FILE} ; then 270 echo "redundantAssignInSwitch check failed" 271 ret_code=1 272fi 273 274if grep "publicAllocationError" ${LOG_FILE} ; then 275 echo "publicAllocationError check failed" 276 ret_code=1 277fi 278 279if grep "invalidScanfArgType_int" ${LOG_FILE} ; then 280 echo "invalidScanfArgType_int check failed" 281 ret_code=1 282fi 283 284if grep "invalidscanf," ${LOG_FILE} ; then 285 echo "invalidscanf check failed" 286 ret_code=1 287fi 288 289if grep "moduloAlwaysTrueFalse" ${LOG_FILE} ; then 290 echo "moduloAlwaysTrueFalse check failed" 291 ret_code=1 292fi 293 294if grep "charLiteralWithCharPtrCompare" ${LOG_FILE} ; then 295 echo "charLiteralWithCharPtrCompare check failed" 296 ret_code=1 297fi 298 299if grep "noConstructor" ${LOG_FILE} ; then 300 echo "noConstructor check failed" 301 ret_code=1 302fi 303 304if grep "noExplicitConstructor" ${LOG_FILE} ; then 305 echo "noExplicitConstructor check failed" 306 ret_code=1 307fi 308 309if grep "noCopyConstructor" ${LOG_FILE} ; then 310 echo "noCopyConstructor check failed" 311 ret_code=1 312fi 313 314if grep "passedByValue" ${LOG_FILE} ; then 315 echo "passedByValue check failed" 316 ret_code=1 317fi 318 319if grep "postfixOperator" ${LOG_FILE} ; then 320 echo "postfixOperator check failed" 321 ret_code=1 322fi 323 324if grep "redundantCopy" ${LOG_FILE} ; then 325 echo "redundantCopy check failed" 326 ret_code=1 327fi 328 329if grep "stlIfStrFind" ${LOG_FILE} ; then 330 echo "stlIfStrFind check failed" 331 ret_code=1 332fi 333 334if grep "functionStatic" ${LOG_FILE} | grep -v -e OGRSQLiteDataSource::OpenRaster \ 335 -e OGRSQLiteDataSource::OpenRasterSubDataset \ 336 -e cpl_mem_cache ; then 337 echo "functionStatic check failed" 338 ret_code=1 339fi 340 341if grep "knownConditionTrueFalse" ${LOG_FILE} ; then 342 echo "knownConditionTrueFalse check failed" 343 ret_code=1 344fi 345 346if grep "arrayIndexThenCheck" ${LOG_FILE} ; then 347 echo "arrayIndexThenCheck check failed" 348 ret_code=1 349fi 350 351if grep "unusedPrivateFunction" ${LOG_FILE} ; then 352 echo "unusedPrivateFunction check failed" 353 ret_code=1 354fi 355 356if grep "redundantCondition" ${LOG_FILE} ; then 357 echo "redundantCondition check failed" 358 ret_code=1 359fi 360 361if grep "unusedStructMember" ${LOG_FILE} | grep -v -e frmts/jpeg/libjpeg -e frmts/gtiff/libtiff -e frmts/zlib ; then 362 echo "unusedStructMember check failed" 363 ret_code=1 364fi 365 366if grep "multiCondition" ${LOG_FILE} ; then 367 echo "multiCondition check failed" 368 ret_code=1 369fi 370 371if grep "duplicateExpression" ${LOG_FILE} ; then 372 echo "duplicateExpression check failed" 373 ret_code=1 374fi 375 376if grep "operatorEq" ${LOG_FILE} ; then 377 echo "operatorEq check failed" 378 ret_code=1 379fi 380 381if grep "truncLongCastAssignment" ${LOG_FILE} ; then 382 echo "truncLongCastAssignment check failed" 383 ret_code=1 384fi 385 386if grep "exceptRethrowCopy" ${LOG_FILE} ; then 387 echo "exceptRethrowCopy check failed" 388 ret_code=1 389fi 390 391if grep "unusedVariable" ${LOG_FILE} ; then 392 echo "unusedVariable check failed" 393 ret_code=1 394fi 395 396if grep "unsafeClassCanLeak" ${LOG_FILE} ; then 397 echo "unsafeClassCanLeak check failed" 398 ret_code=1 399fi 400 401if grep "unsignedLessThanZero" ${LOG_FILE} | grep -v frmts/jpeg/libjpeg ; then 402 echo "unsignedLessThanZero check failed" 403 ret_code=1 404fi 405 406if grep "unpreciseMathCall" ${LOG_FILE} ; then 407 echo "unpreciseMathCall check failed" 408 ret_code=1 409fi 410 411if grep "unreachableCode" ${LOG_FILE} ; then 412 echo "unreachableCode check failed" 413 ret_code=1 414fi 415 416if grep "clarifyCondition" ${LOG_FILE} ; then 417 echo "clarifyCondition check failed" 418 ret_code=1 419fi 420 421if grep "redundantIfRemove" ${LOG_FILE} ; then 422 echo "redundantIfRemove check failed" 423 ret_code=1 424fi 425 426if grep "unassignedVariable" ${LOG_FILE} | grep -v frmts/png/libpng ; then 427 echo "unassignedVariable check failed" 428 ret_code=1 429fi 430 431if grep "redundantAssignment" ${LOG_FILE} | grep -v -e frmts/grib/degrib/g2clib -e frmts/hdf4/hdf-eos -e frmts/png/libpng ; then 432 echo "redundantAssignment check failed" 433 ret_code=1 434fi 435 436if grep "unreadVariable" ${LOG_FILE} | grep -v alg/internal_libqhull | \ 437 grep -v frmts/gtiff/libtiff | \ 438 grep -v frmts/jpeg/libjpeg | \ 439 grep -v frmts/png/libpng | \ 440 grep -v frmts/grib/degrib/degrib | \ 441 grep -v frmts/hdf4/hdf-eos | \ 442 grep -v frmts/zlib ; then 443 echo "unreadVariable check failed" 444 ret_code=1 445fi 446 447 448for whitelisted_dir in alg/ port/ gcore/; do 449 if grep "cstyleCast" ${LOG_FILE} | grep $whitelisted_dir ; then 450 echo "cstyleCast check failed" 451 ret_code=1 452 fi 453done 454 455if grep "AssignmentAddressToInteger" ${LOG_FILE} ; then 456 echo "AssignmentAddressToInteger check failed" 457 ret_code=1 458fi 459 460 461# Check any remaining errors 462if grep "error," ${LOG_FILE} | grep -v "uninitvar" | \ 463 grep -v "memleak," | grep -v "memleakOnRealloc" | \ 464 grep -v "frmts/jpeg/libjpeg/jdphuff.c:493,error,shiftNegative,Shifting a negative value is undefined behaviour" | \ 465 grep -v "ogr/ogrsf_frmts/avc/avc_bin.c:1866,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds" | \ 466 grep -v "frmts/hdf4/hdf-eos/EHapi.c:1890,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 467 grep -v "frmts/hdf4/hdf-eos/EHapi.c:1920,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 468 grep -v "frmts/hdf4/hdf-eos/EHapi.c:1958,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 469 grep -v "frmts/hdf4/hdf-eos/EHapi.c:1994,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 470 grep -v "frmts/hdf4/hdf-eos/EHapi.c:2056,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 471 grep -v "frmts/hdf4/hdf-eos/EHapi.c:2118,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 472 grep -v "frmts/hdf4/hdf-eos/EHapi.c:2159,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 473 grep -v "frmts/hdf4/hdf-eos/EHapi.c:2208,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 474 grep -v "frmts/hdf4/hdf-eos/EHapi.c:2227,error,bufferAccessOutOfBounds,Buffer is accessed out of bounds." | \ 475 grep -v "frmts/grib/degrib/g2clib" | \ 476 grep -v "is invalid C code" ; then 477 478 echo "Errors check failed" 479 ret_code=1 480fi 481 482# Check any remaining warnings 483if grep "warning," ${LOG_FILE} | grep -v "ods_formula_parser" | \ 484 grep -v "osr_cs_wkt_parser" | grep -v "swq_parser" | \ 485 grep -v "frmts/jpeg/libjpeg" ; then 486 echo "Warnings check failed" 487 ret_code=1 488fi 489 490if [ ${ret_code} = 0 ]; then 491 echo "cppcheck succeeded" 492fi 493 494exit ${ret_code} 495