feat: added linter for C

This commit is contained in:
Krzysztof Rudnicki 2025-11-01 19:18:53 +01:00
parent e56a691b22
commit 126bed59e8
6 changed files with 1032 additions and 222 deletions

View File

@ -1,19 +1,10 @@
BasedOnStyle: LLVM
Language: Cpp
DisableFormat: false
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 100
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Allman
SpaceAfterCStyleCast: true
SpaceBeforeParens: ControlStatements
PointerAlignment: Left
AlignConsecutiveAssignments: Consecutive
AlignOperands: Align
AlignAfterOpenBracket: Align
SortIncludes: true
IncludeBlocks: Regroup
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AllowShortIfStatementsOnASingleLine: false
BreakBeforeBraces: Allman

View File

@ -1,34 +1,6 @@
Checks: >
-*,
bugprone-*,
cert-*,
clang-analyzer-*,
concurrency-*,
cppcoreguidelines-*,
google-*,-google-runtime-references,
hicpp-*,
readability-*,
modernize-*,
performance-*,
portability-*,
misc-*,
llvm-*,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables
clang-analyzer-*,bugprone-*,cert-*,concurrency-*,hicpp-*,misc-*,performance-*,
portability-*,readability-*,clang-diagnostic-*,cppcoreguidelines-*
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: true
FormatStyle: file
User: local
CheckOptions:
- key: readability-magic-numbers.IgnorePowersOf2
value: 'false'
- key: readability-magic-numbers.IgnoredIntegerValues
value: '0,1,2'
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
- key: cppcoreguidelines-pro-bounds-array-to-pointer-decay.StrictMode
value: 'true'
FormatStyle: none

105
C/compile_commands.json Normal file

File diff suppressed because one or more lines are too long

40
C/cppcheck.txt Normal file
View File

@ -0,0 +1,40 @@
Checking 1dvelocitysimulator/main.c ...
1/20 files checked 2% done
Checking fps/main.c ...
2/20 files checked 10% done
Checking imageViewer/main.c ...
3/20 files checked 37% done
Checking lichess_random_engine/main.c ...
4/20 files checked 40% done
Checking lichess_random_engine/micro_max.c ...
5/20 files checked 49% done
Checking lichess_random_engine/movegen.c ...
6/20 files checked 60% done
Checking lichess_random_engine/perft.c ...
7/20 files checked 61% done
Checking lichess_random_engine/search.c ...
8/20 files checked 62% done
Checking misc/generatingWordsEndingWIthalka.c ...
9/20 files checked 63% done
Checking misc/randomJPG/generate_images.c ...
10/20 files checked 68% done
Checking misc/randomJPG/generate_jpg.c ...
11/20 files checked 73% done
Checking misc/split/main.c ...
12/20 files checked 74% done
Checking opening_learner/chess.c ...
13/20 files checked 83% done
Checking opening_learner/engine.c ...
14/20 files checked 86% done
Checking opening_learner/gui.c ...
15/20 files checked 90% done
Checking opening_learner/main.c ...
16/20 files checked 93% done
Checking opening_learner/mistakes.c ...
17/20 files checked 95% done
Checking scrapeWebsite/scrape.c ...
18/20 files checked 98% done
Checking tests/generatingPolishLettersOnWindowsTerminal.c ...
19/20 files checked 98% done
Checking websocketServer/main.c ...
20/20 files checked 100% done

627
C/flawfinder.txt Normal file
View File

@ -0,0 +1,627 @@
Flawfinder version 2.0.19, (C) 2001-2019 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 222
./1dvelocitysimulator/main.c:16:5: [4] (shell) system:
This causes a new program to execute and is difficult to use safely
(CWE-78). try using a library call that implements the same functionality
if available.
./1dvelocitysimulator/main.c:22:5: [4] (shell) system:
This causes a new program to execute and is difficult to use safely
(CWE-78). try using a library call that implements the same functionality
if available.
./1dvelocitysimulator/main.c:27:5: [4] (shell) system:
This causes a new program to execute and is difficult to use safely
(CWE-78). try using a library call that implements the same functionality
if available.
./lichess_random_engine/movegen.c:35:20: [4] (buffer) strcpy:
Does not check for buffer overflows when copying to destination [MS-banned]
(CWE-120). Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy
easily misused).
./opening_learner/engine.c:21:9: [4] (shell) execlp:
This causes a new program to execute and is difficult to use safely
(CWE-78). try using a library call that implements the same functionality
if available.
./scrapeWebsite/scrape.c:49:8: [4] (race) access:
This usually indicates a security flaw. If an attacker can change anything
along the path between the call to access() and the file's actual use
(e.g., by moving files), the attacker can exploit the race condition
(CWE-362/CWE-367!). Set up the correct permissions (e.g., using setuid())
and try to open the file directly.
./fps/main.c:521:2: [3] (random) srand:
This function is not sufficiently random for security-related functions
such as key and nonce creation (CWE-327). Use a more secure technique for
acquiring random values.
./lichess_random_engine/main.c:112:2: [3] (random) srand:
This function is not sufficiently random for security-related functions
such as key and nonce creation (CWE-327). Use a more secure technique for
acquiring random values.
./lichess_random_engine/micro_max.c:228:52: [3] (random) srand:
This function is not sufficiently random for security-related functions
such as key and nonce creation (CWE-327). Use a more secure technique for
acquiring random values.
./misc/randomJPG/generate_images.c:257:5: [3] (random) srand:
This function is not sufficiently random for security-related functions
such as key and nonce creation (CWE-327). Use a more secure technique for
acquiring random values.
./misc/randomJPG/generate_jpg.c:208:5: [3] (random) srand:
This function is not sufficiently random for security-related functions
such as key and nonce creation (CWE-327). Use a more secure technique for
acquiring random values.
./opening_learner/main.c:49:2: [3] (random) srand:
This function is not sufficiently random for security-related functions
such as key and nonce creation (CWE-327). Use a more secure technique for
acquiring random values.
./fps/main.c:338:3: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:26:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:34:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:87:5: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./imageViewer/main.c:416:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:447:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:475:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:553:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:585:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:614:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:689:12: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:1137:9: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./imageViewer/main.c:1181:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:1188:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:1200:9: [2] (buffer) strcpy:
Does not check for buffer overflows when copying to destination [MS-banned]
(CWE-120). Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy
easily misused). Risk is low because the source is a constant string.
./imageViewer/main.c:1207:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./imageViewer/main.c:1208:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./lichess_random_engine/micro_max.c:15:6: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./lichess_random_engine/micro_max.c:179:6: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./lichess_random_engine/movegen.c:35:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./lichess_random_engine/movegen.c:36:5: [2] (buffer) strcat:
Does not check for buffer overflows when concatenating to destination
[MS-banned] (CWE-120). Consider using strcat_s, strncat, strlcat, or
snprintf (warning: strncat is easily misused). Risk is low because the
source is a constant string.
./lichess_random_engine/perft.c:38:21: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./lichess_random_engine/perft.c:46:17: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./lichess_random_engine/perft.c:53:36: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./misc/randomJPG/generate_images.c:106:21: [2] (misc) fopen:
Check when opening files - can an attacker redirect it (via symlinks),
force the opening of special file type (e.g., device files), move things
around to create a race condition, control its ancestors, or change its
contents? (CWE-362).
./misc/randomJPG/generate_images.c:117:21: [2] (misc) fopen:
Check when opening files - can an attacker redirect it (via symlinks),
force the opening of special file type (e.g., device files), move things
around to create a race condition, control its ancestors, or change its
contents? (CWE-362).
./misc/randomJPG/generate_images.c:121:14: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./misc/randomJPG/generate_images.c:124:14: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./misc/randomJPG/generate_images.c:163:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./misc/randomJPG/generate_images.c:234:33: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_images.c:235:27: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_images.c:236:33: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_images.c:237:30: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_images.c:273:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./misc/randomJPG/generate_jpg.c:106:21: [2] (misc) fopen:
Check when opening files - can an attacker redirect it (via symlinks),
force the opening of special file type (e.g., device files), move things
around to create a race condition, control its ancestors, or change its
contents? (CWE-362).
./misc/randomJPG/generate_jpg.c:124:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./misc/randomJPG/generate_jpg.c:186:33: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_jpg.c:187:27: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_jpg.c:188:33: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_jpg.c:189:30: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./misc/randomJPG/generate_jpg.c:224:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/chess.c:253:33: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/chess.c:270:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/chess.h:11:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/chess.h:48:33: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:36:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:82:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:88:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:90:41: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:92:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:104:31: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./opening_learner/engine.c:105:66: [2] (integer) atoi:
Unless checked, the resulting number can exceed the expected range
(CWE-190). If source untrusted, check both minimum and maximum, even if the
input had no minus sign (large numbers can roll over into negative number;
consider saving to an unsigned value if that is intended).
./opening_learner/engine.c:106:25: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:124:59: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:126:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.c:128:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.h:11:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/engine.h:32:59: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/gui.c:73:29: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/gui.h:24:29: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:29:2: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:36:38: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:77:2: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:79:2: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:83:2: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:95:4: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:99:4: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:103:6: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./opening_learner/main.c:136:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:155:4: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/main.c:164:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.c:32:15: [2] (misc) fopen:
Check when opening files - can an attacker redirect it (via symlinks),
force the opening of special file type (e.g., device files), move things
around to create a race condition, control its ancestors, or change its
contents? (CWE-362).
./opening_learner/mistakes.c:42:15: [2] (misc) fopen:
Check when opening files - can an attacker redirect it (via symlinks),
force the opening of special file type (e.g., device files), move things
around to create a race condition, control its ancestors, or change its
contents? (CWE-362).
./opening_learner/mistakes.c:44:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.c:44:21: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.c:44:41: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.c:44:61: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.c:49:13: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./opening_learner/mistakes.c:53:13: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./opening_learner/mistakes.c:57:13: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./opening_learner/mistakes.h:10:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.h:11:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./opening_learner/mistakes.h:13:5: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./scrapeWebsite/scrape.c:28:5: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./scrapeWebsite/scrape.c:56:20: [2] (misc) fopen:
Check when opening files - can an attacker redirect it (via symlinks),
force the opening of special file type (e.g., device files), move things
around to create a race condition, control its ancestors, or change its
contents? (CWE-362).
./websocketServer/main.c:22:22: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
./websocketServer/main.c:24:13: [2] (buffer) memcpy:
Does not check for buffer overflows when copying to destination (CWE-120).
Make sure destination can always hold the source data.
./fps/main.c:345:22: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./fps/main.c:346:22: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./fps/main.c:347:22: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:233:27: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:404:27: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:453:49: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:455:43: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:476:31: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:477:31: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:493:33: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:494:33: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:592:49: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:594:43: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:615:31: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:616:31: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:632:33: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:633:33: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:1182:18: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./imageViewer/main.c:1191:23: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./lichess_random_engine/micro_max.c:163:18: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./lichess_random_engine/micro_max.c:241:11: [1] (buffer) strncpy:
Easily used incorrectly; doesn't always \0-terminate or check for invalid
pointers [MS-banned] (CWE-120).
./lichess_random_engine/movegen.c:428:18: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./lichess_random_engine/movegen.c:439:25: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./opening_learner/chess.c:261:15: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./opening_learner/engine.c:38:9: [1] (obsolete) usleep:
This C routine is considered obsolete (as opposed to the shell command by
the same name). The interaction of this function with SIGALRM and other
timer functions such as sleep(), alarm(), setitimer(), and nanosleep() is
unspecified (CWE-676). Use nanosleep(2) or setitimer(2) instead.
./opening_learner/engine.c:39:21: [1] (buffer) read:
Check buffer boundaries if used in a loop including recursive loops
(CWE-120, CWE-20).
./opening_learner/engine.c:49:9: [1] (obsolete) usleep:
This C routine is considered obsolete (as opposed to the shell command by
the same name). The interaction of this function with SIGALRM and other
timer functions such as sleep(), alarm(), setitimer(), and nanosleep() is
unspecified (CWE-676). Use nanosleep(2) or setitimer(2) instead.
./opening_learner/engine.c:50:21: [1] (buffer) read:
Check buffer boundaries if used in a loop including recursive loops
(CWE-120, CWE-20).
./opening_learner/engine.c:72:18: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
./opening_learner/engine.c:94:9: [1] (obsolete) usleep:
This C routine is considered obsolete (as opposed to the shell command by
the same name). The interaction of this function with SIGALRM and other
timer functions such as sleep(), alarm(), setitimer(), and nanosleep() is
unspecified (CWE-676). Use nanosleep(2) or setitimer(2) instead.
./opening_learner/engine.c:95:17: [1] (buffer) read:
Check buffer boundaries if used in a loop including recursive loops
(CWE-120, CWE-20).
./opening_learner/engine.c:107:25: [1] (buffer) sscanf:
It's unclear if the %s limit in the format string is small enough
(CWE-120). Check that the limit is sufficiently small, or use a different
input function.
./opening_learner/engine.c:130:9: [1] (obsolete) usleep:
This C routine is considered obsolete (as opposed to the shell command by
the same name). The interaction of this function with SIGALRM and other
timer functions such as sleep(), alarm(), setitimer(), and nanosleep() is
unspecified (CWE-676). Use nanosleep(2) or setitimer(2) instead.
./opening_learner/engine.c:131:17: [1] (buffer) read:
Check buffer boundaries if used in a loop including recursive loops
(CWE-120, CWE-20).
./opening_learner/engine.c:136:52: [1] (buffer) sscanf:
It's unclear if the %s limit in the format string is small enough
(CWE-120). Check that the limit is sufficiently small, or use a different
input function.
./opening_learner/main.c:23:15: [1] (buffer) strncat:
Easily used incorrectly (e.g., incorrectly computing the correct maximum
size to add) [MS-banned] (CWE-120). Consider strcat_s, strlcat, snprintf,
or automatically resizing strings. Risk is low because the source is a
constant character.
./opening_learner/main.c:24:2: [1] (buffer) strncat:
Easily used incorrectly (e.g., incorrectly computing the correct maximum
size to add) [MS-banned] (CWE-120). Consider strcat_s, strlcat, snprintf,
or automatically resizing strings.
./opening_learner/main.c:36:73: [1] (buffer) strncpy:
Easily used incorrectly; doesn't always \0-terminate or check for invalid
pointers [MS-banned] (CWE-120).
./opening_learner/main.c:100:30: [1] (buffer) strncpy:
Easily used incorrectly; doesn't always \0-terminate or check for invalid
pointers [MS-banned] (CWE-120).
./opening_learner/main.c:140:5: [1] (buffer) strncpy:
Easily used incorrectly; doesn't always \0-terminate or check for invalid
pointers [MS-banned] (CWE-120).
./websocketServer/main.c:23:30: [1] (buffer) strlen:
Does not handle strings that are not \0-terminated; if given one it may
perform an over-read (it could cause a crash if unprotected) (CWE-126).
ANALYSIS SUMMARY:
Hits = 140
Lines analyzed = 5027 in approximately 0.26 seconds (19578 lines/second)
Physical Source Lines of Code (SLOC) = 4111
Hits@level = [0] 208 [1] 41 [2] 87 [3] 6 [4] 6 [5] 0
Hits@level+ = [0+] 348 [1+] 140 [2+] 99 [3+] 12 [4+] 6 [5+] 0
Hits/KSLOC@level+ = [0+] 84.6509 [1+] 34.055 [2+] 24.0817 [3+] 2.919 [4+] 1.4595 [5+] 0
Dot directories skipped = 1 (--followdotdir overrides)
Minimum risk level = 1
Not every hit is necessarily a security vulnerability.
You can inhibit a report by adding a comment in this form:
// flawfinder: ignore
Make *sure* it's a false positive!
You can use the option --neverignore to show these.
There may be other security vulnerabilities; review your code!
See 'Secure Programming HOWTO'
(https://dwheeler.com/secure-programs) for more information.

421
C/lint_all.sh Normal file → Executable file
View File

@ -1,201 +1,276 @@
#!/usr/bin/env bash
# Aggressive linting for all C code in this C/ folder and subfolders
# - Installs missing tools when possible
# - Runs: clang-format (check), cppcheck, flawfinder, clang-tidy (aggressive)
#
# Usage:
# ./lint_all.sh [--fix-format]
#
# If --fix-format is provided, it will format files in-place with clang-format before linting.
# Lint all C code in C/ and its subfolders with aggressive rules
# - Installs required tools if missing (clang-tidy, clang-format, cppcheck, flawfinder)
# - Uses compile_commands.json if present for clang-tidy; otherwise uses sane defaults
# - Checks formatting with clang-format --dry-run --Werror
# - Runs cppcheck with exhaustive rules
# - Runs flawfinder for security issues
set -euo pipefail
IFS=$'\n\t'
set -u
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
ROOT_DIR="$SCRIPT_DIR"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
CYAN='\033[0;36m'; RED='\033[0;31m'; YELLOW='\033[0;33m'; GREEN='\033[0;32m'; NC='\033[0m'
info() { echo -e "${BLUE}==>${NC} $*"; }
ok() { echo -e "${GREEN}${NC} $*"; }
warn() { echo -e "${YELLOW}${NC} $*"; }
err() { echo -e "${RED}${NC} $*"; }
have() { command -v "$1" &>/dev/null; }
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
C_DIR="${ROOT_DIR}/C"
pm=""
detect_pm() {
if have apt-get; then pm=apt; return 0; fi
if have dnf; then pm=dnf; return 0; fi
if have yum; then pm=yum; return 0; fi
if have pacman; then pm=pacman; return 0; fi
if have zypper; then pm=zypper; return 0; fi
if have brew; then pm=brew; return 0; fi
return 1
}
sudo_prefix() {
if [ "$EUID" -ne 0 ] && have sudo; then echo sudo; else echo; fi
}
install_packages() {
local pkgs=("clang" "clang-tidy" "clang-format" "cppcheck" "flawfinder" "bear")
detect_pm || { echo -e "${YELLOW}No supported package manager detected. Skipping auto-install.${NC}"; return 0; }
echo -e "${CYAN}Attempting to install missing tools using $pm...${NC}"
case "$pm" in
apt)
# Prefer non-interactive installs; ignore missing packages gracefully
$(sudo_prefix) apt-get update -y || true
# Try common variants for clang tools
$(sudo_prefix) apt-get install -y --no-install-recommends \
clang clang-tidy clang-format cppcheck flawfinder bear || true
;;
dnf)
$(sudo_prefix) dnf install -y clang clang-tools-extra cppcheck flawfinder bear || true
;;
yum)
$(sudo_prefix) yum install -y clang clang-tools-extra cppcheck flawfinder bear || true
;;
pacman)
$(sudo_prefix) pacman --noconfirm -Sy || true
$(sudo_prefix) pacman --noconfirm -S clang clang-tools-extra cppcheck flawfinder bear || true
;;
zypper)
$(sudo_prefix) zypper --non-interactive refresh || true
$(sudo_prefix) zypper --non-interactive install clang clang-tools cppcheck flawfinder bear || true
;;
brew)
brew update || true
# llvm contains clang-tidy/format; add others separately
brew install llvm cppcheck flawfinder bear || true
# Add llvm tools to PATH if not present
if ! have clang-tidy && [ -d "/home/linuxbrew/.linuxbrew/opt/llvm/bin" ]; then
export PATH="/home/linuxbrew/.linuxbrew/opt/llvm/bin:$PATH"
fi
;;
esac
}
ensure_tools() {
local missing=()
for t in clang clang-tidy clang-format cppcheck flawfinder; do
have "$t" || missing+=("$t")
done
if [ ${#missing[@]} -gt 0 ]; then
echo -e "${YELLOW}Missing tools: ${missing[*]}${NC}"
install_packages
fi
local still_missing=()
for t in clang clang-tidy clang-format cppcheck flawfinder; do
have "$t" || still_missing+=("$t")
done
if [ ${#still_missing[@]} -gt 0 ]; then
echo -e "${YELLOW}Still missing after install attempt: ${still_missing[*]}${NC}"
fi
}
# Collect files
mapfile -t C_FILES < <(find "$ROOT_DIR" \
-type f \( -name '*.c' -o -name '*.h' \) \
-not -path '*/.*/*' \
-not -path '*/.git/*' \
-not -path '*/build/*' \
-not -path '*/bin/*' \
-not -path '*/obj/*' \
-print | sort)
if [ ${#C_FILES[@]} -eq 0 ]; then
echo -e "${RED}No C source/header files found under: $ROOT_DIR${NC}"
if [[ ! -d "${C_DIR}" ]]; then
err "C directory not found at ${C_DIR}"
exit 1
fi
# Unique include dirs where headers live
mapfile -t INCLUDE_DIRS < <(printf '%s\n' "${C_FILES[@]}" | awk -F/ '{ $NF=""; print $0 }' | sed 's# $##;s#[^/]*$##' | sed 's#/$##' | sort -u)
ISSUES=0
MISSING=()
INC_FLAGS=("-I$ROOT_DIR")
for d in "${INCLUDE_DIRS[@]}"; do
[ -n "$d" ] && INC_FLAGS+=("-I$d")
done
need_cmd() {
command -v "$1" >/dev/null 2>&1 || MISSING+=("$1")
}
CPU_JOBS=1
if have nproc; then CPU_JOBS="$(nproc)"; elif have getconf; then CPU_JOBS="$(getconf _NPROCESSORS_ONLN || echo 1)"; fi
detect_pkg_manager() {
if command -v pacman >/dev/null 2>&1; then echo pacman; return; fi
if command -v apt-get >/dev/null 2>&1; then echo apt; return; fi
if command -v apt >/dev/null 2>&1; then echo apt; return; fi
if command -v dnf >/dev/null 2>&1; then echo dnf; return; fi
if command -v zypper >/dev/null 2>&1; then echo zypper; return; fi
if command -v apk >/dev/null 2>&1; then echo apk; return; fi
echo none
}
ensure_tools
install_tools() {
info "Checking required tools..."
need_cmd clang-tidy
need_cmd clang-format
need_cmd cppcheck
need_cmd flawfinder
FORMAT_ONLY=false
if [ "${1:-}" = "--fix-format" ]; then
FORMAT_ONLY=true
fi
if [[ ${#MISSING[@]} -eq 0 ]]; then
ok "All tools present: clang-tidy, clang-format, cppcheck, flawfinder"
return 0
fi
fail=0
warn "Missing tools: ${MISSING[*]} — attempting to install with sudo"
local pm
pm=$(detect_pkg_manager)
case "$pm" in
pacman)
sudo pacman -S --needed --noconfirm clang clang-tools-extra clang-format cppcheck flawfinder || true
;;
apt|apt-get)
sudo "$pm" update -y || true
# clang-tidy and clang-format may be versioned; prefer unversioned meta pkgs
sudo "$pm" install -y clang-tidy clang-format cppcheck flawfinder || true
;;
dnf)
sudo dnf install -y clang-tools-extra clang cppcheck flawfinder || true
;;
zypper)
sudo zypper --non-interactive install clang-tools clang-tools-extra cppcheck flawfinder || true
;;
apk)
sudo apk add clang-extra-tools clang cppcheck flawfinder || true
;;
*)
warn "Unsupported package manager. Please install: clang-tidy clang-format cppcheck flawfinder"
;;
esac
if have clang-format; then
if $FORMAT_ONLY; then
echo -e "${CYAN}Formatting with clang-format (in-place)...${NC}"
printf '%s\0' "${C_FILES[@]}" | xargs -0 -n50 -P "$CPU_JOBS" clang-format -style=file -i || fail=1
# Re-check after attempted install
MISSING=()
need_cmd clang-tidy
need_cmd clang-format
need_cmd cppcheck
need_cmd flawfinder
if [[ ${#MISSING[@]} -ne 0 ]]; then
warn "Still missing: ${MISSING[*]} — continuing, but related steps may be skipped"
else
echo -e "${CYAN}Checking formatting with clang-format...${NC}"
# -n: dry-run, --Werror: exit non-zero if reformatting is needed
if ! printf '%s\0' "${C_FILES[@]}" | xargs -0 -n50 -P "$CPU_JOBS" clang-format -style=file -n --Werror; then
echo -e "${YELLOW}clang-format suggests changes. Run with --fix-format to apply.${NC}"
fail=1
ok "Tools installed"
fi
fi
else
echo -e "${YELLOW}clang-format not available; skipping formatting check.${NC}"
fi
}
if have cppcheck; then
echo -e "${CYAN}Running cppcheck (aggressive)...${NC}"
# Build include args for cppcheck
CPPCHECK_INC=()
for f in "${INC_FLAGS[@]}"; do
# convert -Ipath into --include=path for cppcheck? cppcheck uses -I as well
if [[ "$f" == -I* ]]; then CPPCHECK_INC+=("$f"); fi
ensure_configs() {
# Provide default aggressive configs if missing
if [[ ! -f "${C_DIR}/.clang-tidy" ]]; then
warn ".clang-tidy not found in C/. Creating a default aggressive config."
cat >"${C_DIR}/.clang-tidy" <<'YAML'
Checks: >
clang-analyzer-*,bugprone-*,cert-*,concurrency-*,hicpp-*,misc-*,performance-*,
portability-*,readability-*,clang-diagnostic-*,cppcoreguidelines-*
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: true
FormatStyle: none
YAML
fi
if [[ ! -f "${C_DIR}/.clang-format" ]]; then
warn ".clang-format not found in C/. Creating a default style."
cat >"${C_DIR}/.clang-format" <<'YAML'
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 100
SortIncludes: true
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AllowShortIfStatementsOnASingleLine: false
BreakBeforeBraces: Allman
Standard: C23
YAML
fi
}
collect_files() {
# shellcheck disable=SC2207
C_FILES=($(find "${C_DIR}" -type f \( -name '*.c' -o -name '*.h' -o -name '*.inc' \) \
-not -path '*/.*' -not -path '*/build/*' -not -path '*/dist/*' -not -path '*/out/*' \
-not -path '*/bin/*' -not -path '*/obj/*'))
if [[ ${#C_FILES[@]} -eq 0 ]]; then
warn "No C files found under ${C_DIR}"
else
ok "Found ${#C_FILES[@]} C-related files to check"
fi
}
run_clang_format() {
if ! command -v clang-format >/dev/null 2>&1; then
warn "clang-format unavailable; skipping format check"
return
fi
info "Checking formatting with clang-format (--dry-run --Werror)"
local bad=0
for f in "${C_FILES[@]}"; do
if ! clang-format --dry-run --Werror "$f" >/dev/null 2>&1; then
echo "format issue: $f"
bad=$((bad+1))
fi
done
# Use --project if compile_commands.json exists; otherwise lint folder
if [ -f "$ROOT_DIR/compile_commands.json" ]; then
cppcheck --enable=all --inconclusive --std=c11 --force --platform=unix64 \
--library=posix --suppress=missingIncludeSystem \
--project="$ROOT_DIR/compile_commands.json" || fail=1
if [[ $bad -gt 0 ]]; then
warn "clang-format found $bad files needing formatting"
ISSUES=$((ISSUES+bad))
else
cppcheck --enable=all --inconclusive --std=c11 --force --platform=unix64 \
--library=posix --suppress=missingIncludeSystem \
"${CPPCHECK_INC[@]}" "$ROOT_DIR" || fail=1
ok "Formatting OK"
fi
else
echo -e "${YELLOW}cppcheck not available; skipping.${NC}"
fi
}
if have flawfinder; then
echo -e "${CYAN}Running flawfinder (security scan)...${NC}"
# error-level 1+ to be noisy; set to 0 for all messages
flawfinder --error-level=0 --columns --followdotdirs "$ROOT_DIR" || fail=1
else
echo -e "${YELLOW}flawfinder not available; skipping.${NC}"
fi
if have clang-tidy; then
echo -e "${CYAN}Running clang-tidy (aggressive)...${NC}"
# Prefer compile_commands.json if present
TIDY_ARGS=("-warnings-as-errors=*" "-header-filter=.*")
if [ -f "$ROOT_DIR/compile_commands.json" ]; then
TIDY_ARGS+=("-p" "$ROOT_DIR")
run_cppcheck() {
if ! command -v cppcheck >/dev/null 2>&1; then
warn "cppcheck unavailable; skipping"
return
fi
info "Running cppcheck (aggressive, recursive)"
# Use a temp report file to avoid noisy exit codes stopping script
local report
report=$(mktemp)
local opts=(--enable=all --inconclusive --std=c23 --check-level=exhaustive --force \
--quiet --error-exitcode=2 --inline-suppr --suppress=missingIncludeSystem \
--library=posix)
# Exclude common non-source dirs
opts+=(--exclude=build --exclude=dist --exclude=out --exclude=.git --exclude=bin --exclude=obj)
if ! cppcheck "${opts[@]}" "${C_DIR}" 2>"$report"; then
warn "cppcheck reported issues (see summary below)"
ISSUES=$((ISSUES+1))
else
# Provide basic args so analysis can proceed without a build database
TIDY_ARGS+=("--extra-arg=-std=c11")
for inc in "${INC_FLAGS[@]}"; do
TIDY_ARGS+=("--extra-arg=$inc")
ok "cppcheck passed"
fi
if [[ -s "$report" ]]; then
echo
echo "cppcheck output:" && sed -e 's/^/ /' "$report"
fi
rm -f "$report"
}
run_clang_tidy() {
if ! command -v clang-tidy >/dev/null 2>&1; then
warn "clang-tidy unavailable; skipping"
return
fi
info "Running clang-tidy on .c files"
local db="${C_DIR}/compile_commands.json"
local used_db="no"
local files=()
while IFS= read -r -d '' f; do files+=("$f"); done < <(find "${C_DIR}" -type f -name '*.c' -print0)
if [[ ${#files[@]} -eq 0 ]]; then
warn "No .c files for clang-tidy"
return
fi
if [[ -f "$db" ]]; then
# Basic validation: ensure JSON array starts with [ and includes "directory"
if head -n 1 "$db" | grep -q '\['; then
used_db="yes"
else
warn "compile_commands.json seems malformed; ignoring"
fi
fi
local failures=0
for f in "${files[@]}"; do
if [[ "$used_db" == "yes" ]]; then
clang-tidy "$f" -p "${C_DIR}" --quiet || failures=$((failures+1))
else
# Fallback args: try C23 and include local dir
clang-tidy "$f" --quiet -- -std=c2x -I"$(dirname "$f")" -I"${C_DIR}" || failures=$((failures+1))
fi
done
if [[ $failures -gt 0 ]]; then
warn "clang-tidy found issues in $failures file(s)"
ISSUES=$((ISSUES+failures))
else
ok "clang-tidy passed"
fi
# clang-tidy supports parallelism via -j
clang-tidy -j "$CPU_JOBS" "${TIDY_ARGS[@]}" "${C_FILES[@]}" || fail=1
else
echo -e "${YELLOW}clang-tidy not available; skipping.${NC}"
fi
}
echo
if [ "$fail" -ne 0 ]; then
echo -e "${RED}Linting completed with issues. See output above.${NC}"
else
echo -e "${GREEN}All lint checks passed.${NC}"
fi
run_flawfinder() {
if ! command -v flawfinder >/dev/null 2>&1; then
warn "flawfinder unavailable; skipping"
return
fi
info "Running flawfinder (security-focused scan)"
local report
report=$(mktemp)
if ! flawfinder --quiet --columns --minlevel=1 --falsepositive "${C_DIR}" >"$report" 2>/dev/null; then
warn "flawfinder reported issues"
ISSUES=$((ISSUES+1))
else
ok "flawfinder completed"
fi
if [[ -s "$report" ]]; then
echo
echo "flawfinder notable findings:" && head -n 200 "$report" | sed -e 's/^/ /'
fi
rm -f "$report"
}
exit "$fail"
summary_exit() {
echo
if [[ $ISSUES -gt 0 ]]; then
err "Lint completed with $ISSUES issue(s) detected"
echo "Tip: run 'clang-format -i' to fix formatting; many clang-tidy checks support '--fix'"
exit 1
else
ok "All checks passed with no issues"
fi
}
main() {
echo -e "${BLUE}C folder aggressive lint suite${NC}"
echo
install_tools
ensure_configs
collect_files
run_clang_format
run_cppcheck
run_clang_tidy
run_flawfinder
summary_exit
}
main "$@"