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 BasedOnStyle: LLVM
Language: Cpp
DisableFormat: false
IndentWidth: 4 IndentWidth: 4
TabWidth: 4 TabWidth: 4
UseTab: Never UseTab: Never
ColumnLimit: 100 ColumnLimit: 100
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Allman
SpaceAfterCStyleCast: true
SpaceBeforeParens: ControlStatements
PointerAlignment: Left
AlignConsecutiveAssignments: Consecutive
AlignOperands: Align
AlignAfterOpenBracket: Align
SortIncludes: true SortIncludes: true
IncludeBlocks: Regroup AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AllowShortIfStatementsOnASingleLine: false
BreakBeforeBraces: Allman

View File

@ -1,34 +1,6 @@
Checks: > Checks: >
-*, clang-analyzer-*,bugprone-*,cert-*,concurrency-*,hicpp-*,misc-*,performance-*,
bugprone-*, portability-*,readability-*,clang-diagnostic-*,cppcoreguidelines-*
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
WarningsAsErrors: '*' WarningsAsErrors: '*'
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: true FormatStyle: none
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'

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.

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

@ -1,201 +1,276 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Aggressive linting for all C code in this C/ folder and subfolders # Lint all C code in C/ and its subfolders with aggressive rules
# - Installs missing tools when possible # - Installs required tools if missing (clang-tidy, clang-format, cppcheck, flawfinder)
# - Runs: clang-format (check), cppcheck, flawfinder, clang-tidy (aggressive) # - Uses compile_commands.json if present for clang-tidy; otherwise uses sane defaults
# # - Checks formatting with clang-format --dry-run --Werror
# Usage: # - Runs cppcheck with exhaustive rules
# ./lint_all.sh [--fix-format] # - Runs flawfinder for security issues
#
# If --fix-format is provided, it will format files in-place with clang-format before linting.
set -euo pipefail set -u
IFS=$'\n\t'
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" RED='\033[0;31m'
ROOT_DIR="$SCRIPT_DIR" 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="" if [[ ! -d "${C_DIR}" ]]; then
detect_pm() { err "C directory not found at ${C_DIR}"
if have apt-get; then pm=apt; return 0; fi exit 1
if have dnf; then pm=dnf; return 0; fi fi
if have yum; then pm=yum; return 0; fi
if have pacman; then pm=pacman; return 0; fi ISSUES=0
if have zypper; then pm=zypper; return 0; fi MISSING=()
if have brew; then pm=brew; return 0; fi
return 1 need_cmd() {
command -v "$1" >/dev/null 2>&1 || MISSING+=("$1")
} }
sudo_prefix() { detect_pkg_manager() {
if [ "$EUID" -ne 0 ] && have sudo; then echo sudo; else echo; fi 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
} }
install_packages() { install_tools() {
local pkgs=("clang" "clang-tidy" "clang-format" "cppcheck" "flawfinder" "bear") info "Checking required tools..."
detect_pm || { echo -e "${YELLOW}No supported package manager detected. Skipping auto-install.${NC}"; return 0; } need_cmd clang-tidy
need_cmd clang-format
need_cmd cppcheck
need_cmd flawfinder
echo -e "${CYAN}Attempting to install missing tools using $pm...${NC}" if [[ ${#MISSING[@]} -eq 0 ]]; then
case "$pm" in ok "All tools present: clang-tidy, clang-format, cppcheck, flawfinder"
apt) return 0
# Prefer non-interactive installs; ignore missing packages gracefully fi
$(sudo_prefix) apt-get update -y || true
# Try common variants for clang tools warn "Missing tools: ${MISSING[*]} — attempting to install with sudo"
$(sudo_prefix) apt-get install -y --no-install-recommends \ local pm
clang clang-tidy clang-format cppcheck flawfinder bear || true pm=$(detect_pkg_manager)
;; case "$pm" in
dnf) pacman)
$(sudo_prefix) dnf install -y clang clang-tools-extra cppcheck flawfinder bear || true sudo pacman -S --needed --noconfirm clang clang-tools-extra clang-format cppcheck flawfinder || true
;; ;;
yum) apt|apt-get)
$(sudo_prefix) yum install -y clang clang-tools-extra cppcheck flawfinder bear || true sudo "$pm" update -y || true
;; # clang-tidy and clang-format may be versioned; prefer unversioned meta pkgs
pacman) sudo "$pm" install -y clang-tidy clang-format cppcheck flawfinder || true
$(sudo_prefix) pacman --noconfirm -Sy || true ;;
$(sudo_prefix) pacman --noconfirm -S clang clang-tools-extra cppcheck flawfinder bear || true dnf)
;; sudo dnf install -y clang-tools-extra clang cppcheck flawfinder || true
zypper) ;;
$(sudo_prefix) zypper --non-interactive refresh || true zypper)
$(sudo_prefix) zypper --non-interactive install clang clang-tools cppcheck flawfinder bear || true sudo zypper --non-interactive install clang-tools clang-tools-extra cppcheck flawfinder || true
;; ;;
brew) apk)
brew update || true sudo apk add clang-extra-tools clang cppcheck flawfinder || true
# llvm contains clang-tidy/format; add others separately ;;
brew install llvm cppcheck flawfinder bear || true *)
# Add llvm tools to PATH if not present warn "Unsupported package manager. Please install: clang-tidy clang-format cppcheck flawfinder"
if ! have clang-tidy && [ -d "/home/linuxbrew/.linuxbrew/opt/llvm/bin" ]; then ;;
export PATH="/home/linuxbrew/.linuxbrew/opt/llvm/bin:$PATH" esac
fi
;; # Re-check after attempted install
esac 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
ok "Tools installed"
fi
} }
ensure_tools() { ensure_configs() {
local missing=() # Provide default aggressive configs if missing
for t in clang clang-tidy clang-format cppcheck flawfinder; do if [[ ! -f "${C_DIR}/.clang-tidy" ]]; then
have "$t" || missing+=("$t") warn ".clang-tidy not found in C/. Creating a default aggressive config."
done cat >"${C_DIR}/.clang-tidy" <<'YAML'
if [ ${#missing[@]} -gt 0 ]; then Checks: >
echo -e "${YELLOW}Missing tools: ${missing[*]}${NC}" clang-analyzer-*,bugprone-*,cert-*,concurrency-*,hicpp-*,misc-*,performance-*,
install_packages portability-*,readability-*,clang-diagnostic-*,cppcoreguidelines-*
fi WarningsAsErrors: '*'
local still_missing=() HeaderFilterRegex: '.*'
for t in clang clang-tidy clang-format cppcheck flawfinder; do AnalyzeTemporaryDtors: true
have "$t" || still_missing+=("$t") FormatStyle: none
done YAML
if [ ${#still_missing[@]} -gt 0 ]; then fi
echo -e "${YELLOW}Still missing after install attempt: ${still_missing[*]}${NC}"
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 collect_files() {
mapfile -t C_FILES < <(find "$ROOT_DIR" \ # shellcheck disable=SC2207
-type f \( -name '*.c' -o -name '*.h' \) \ C_FILES=($(find "${C_DIR}" -type f \( -name '*.c' -o -name '*.h' -o -name '*.inc' \) \
-not -path '*/.*/*' \ -not -path '*/.*' -not -path '*/build/*' -not -path '*/dist/*' -not -path '*/out/*' \
-not -path '*/.git/*' \ -not -path '*/bin/*' -not -path '*/obj/*'))
-not -path '*/build/*' \ if [[ ${#C_FILES[@]} -eq 0 ]]; then
-not -path '*/bin/*' \ warn "No C files found under ${C_DIR}"
-not -path '*/obj/*' \ else
-print | sort) ok "Found ${#C_FILES[@]} C-related files to check"
fi
}
if [ ${#C_FILES[@]} -eq 0 ]; then run_clang_format() {
echo -e "${RED}No C source/header files found under: $ROOT_DIR${NC}" if ! command -v clang-format >/dev/null 2>&1; then
exit 1 warn "clang-format unavailable; skipping format check"
fi 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
if [[ $bad -gt 0 ]]; then
warn "clang-format found $bad files needing formatting"
ISSUES=$((ISSUES+bad))
else
ok "Formatting OK"
fi
}
# Unique include dirs where headers live run_cppcheck() {
mapfile -t INCLUDE_DIRS < <(printf '%s\n' "${C_FILES[@]}" | awk -F/ '{ $NF=""; print $0 }' | sed 's# $##;s#[^/]*$##' | sed 's#/$##' | sort -u) 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
ok "cppcheck passed"
fi
if [[ -s "$report" ]]; then
echo
echo "cppcheck output:" && sed -e 's/^/ /' "$report"
fi
rm -f "$report"
}
INC_FLAGS=("-I$ROOT_DIR") run_clang_tidy() {
for d in "${INCLUDE_DIRS[@]}"; do if ! command -v clang-tidy >/dev/null 2>&1; then
[ -n "$d" ] && INC_FLAGS+=("-I$d") warn "clang-tidy unavailable; skipping"
done 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
}
CPU_JOBS=1 run_flawfinder() {
if have nproc; then CPU_JOBS="$(nproc)"; elif have getconf; then CPU_JOBS="$(getconf _NPROCESSORS_ONLN || echo 1)"; fi 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"
}
ensure_tools 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
}
FORMAT_ONLY=false main() {
if [ "${1:-}" = "--fix-format" ]; then echo -e "${BLUE}C folder aggressive lint suite${NC}"
FORMAT_ONLY=true echo
fi install_tools
ensure_configs
collect_files
run_clang_format
run_cppcheck
run_clang_tidy
run_flawfinder
summary_exit
}
fail=0 main "$@"
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
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
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
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
else
cppcheck --enable=all --inconclusive --std=c11 --force --platform=unix64 \
--library=posix --suppress=missingIncludeSystem \
"${CPPCHECK_INC[@]}" "$ROOT_DIR" || fail=1
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")
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")
done
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
exit "$fail"