-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path.check-code.sh
executable file
·228 lines (194 loc) · 9.12 KB
/
.check-code.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#!/bin/bash
# Licensed to Systerel under one or more contributor license
# agreements. See the NOTICE file distributed with this work
# for additional information regarding copyright ownership.
# Systerel licenses this file to you under the Apache
# License, Version 2.0 (the "License"); you may not use this
# file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Script to check properties on code of the S2OPC project:
# - check absence of use of functions and includes which guarantee compliance with some CERT rules
# - run C sources compilation with Clang compiler using specific options to guarantee some CERT rules
# - run C sources analysis using Clang tidy tool using specific options to guarantee some CERT rules
# - run C sources automatic formatting using Clang format tool to normalize code presentation
#
# OPTIONS:
# - if first argument provided is "advanced", the clang-tidy tool will be used with the default options in addition to CERT specific analyses. It could allow to detect more programming errors but could also contains false positives.
ISADVANCED=$1
BSRC=bsrc
CSRC=src
TST=tests
DEMO=samples
EXITCODE=0
LOGPATH=$(pwd)/pre-build-check.log
# Redirect all output and errors to log file
echo "Pre-build-check log" > $LOGPATH
#### Check contributor list ####
echo "Contributors list verification" | tee -a $LOGPATH
ifs_save=$IFS
IFS=$'\n'
LIST_CONTRIB=(`git log --format="%an <%ae>" | sort -u`)
for contrib in ${LIST_CONTRIB[*]}
do
grep $contrib Contributors.md &> /dev/null
if [[ $? != 0 ]]; then
echo "ERROR: contributor not declared: $contrib" | tee -a $LOGPATH
EXITCODE=1
fi
done
IFS=$ifs_save
#### Check absence of functions / includes ####
echo "Checking specific functions or headers not used in code" | tee -a $LOGPATH
EXLUDE_CERT_VERIFIED_MANUALLY="*\/linux\/p_sopc_askpass.c"
CHECK_CERT_RULE_ABSENCE_FAILED=false
CHECK_CERT_RULE_ABSENCE="(restrict|fgets|fgetws|getc|putc|getwc|putwc|fsetpos|rand|readlink|vfork|putenv|lstat|setuid|setgid|getuid|getgid|seteuid|geteuid|fork|pthread_kill|pthread_cancel|pthread_exit)"
for FILE in $(find $CSRC -not -path $EXLUDE_CERT_VERIFIED_MANUALLY -not -path "*/pikeos/time/*" -name "*.c" -or -not -path "*/pikeos/time/*" -not -path "*/pikeos/p_time_c99.h" -name "*.h") ;
do
# We choose to remove:
# - (L1) comments inside /* .. */
# - (L2) comments after //
# - (L3) : - remove sequence \" to avoid interpreting that as a string ending
# - replace all string content by "..." to avoid false detection in strings
RESULT=$(sed 's/\/\/.*$//g' ${FILE} | \
sed 's/\/\*.*\*\///g' | \
sed 's/\\"//g' | sed 's/"[^"]*"/"..."/g' | \
grep -nwiE $CHECK_CERT_RULE_ABSENCE)
if ! [[ -z ${RESULT} ]] ; then
echo "${FILE}:${RESULT}" | tee -a $LOGPATH
CHECK_CERT_RULE_ABSENCE_FAILED=true
fi
done
$CHECK_CERT_RULE_ABSENCE_FAILED && EXITCODE=1 && echo "ERROR: checking absence of functions or headers: $CHECK_CERT_RULE_ABSENCE" | tee -a $LOGPATH
CHECK_DIRECT_ABSENCE_FAILED=false
CHECK_DIRECT_ABSENCE="(printf)"
for FILE in $(find $CSRC -name "*.c" -or -name "*.h") ;
do
# We choose to remove:
# - (L1) comments inside /* .. */
# - (L2) comments after //
# - (L3) : - remove sequence \" to avoid interpreting that as a string ending
# - replace all string content by "..." to avoid false detection in strings
# - (L4) preprocessor lines (this allow explicit overrides)
RESULT=$(sed 's/\/\/.*$//g' ${FILE} | \
sed 's/\/\*.*\*\///g' | \
sed 's/\\"//g' | sed 's/"[^"]*"/"..."/g' | \
sed 's/^ *#.*$//g' | \
grep -nwiE $CHECK_DIRECT_ABSENCE )
if ! [[ -z "${RESULT}" ]] ; then
echo "${FILE}:${RESULT}" | tee -a $LOGPATH
CHECK_DIRECT_ABSENCE_FAILED=true
fi
done
$CHECK_DIRECT_ABSENCE_FAILED && EXITCODE=1 && echo "ERROR: checking absence of functions or headers: $CHECK_DIRECT_ABSENCE" | tee -a $LOGPATH
#### Additionnal check for function, where we want to ensure that there is no false detection due to common wording.
CHECK_ABSENCE='(\bassert *[\(])'
echo "Checking specific functions not used in code" | tee -a $LOGPATH
find $CSRC -name "*.c" -or -name "*.h" | xargs grep -Ec "$CHECK_ABSENCE" | grep -Ec ":[^0]+" | xargs test 0 -eq
if [[ $? != 0 ]]; then
echo "ERROR: checking absence of functions: $CHECK_ABSENCE" | tee -a $LOGPATH
find $CSRC -name "*.c" -or -name "*.h" | xargs grep -nE "$CHECK_ABSENCE" | tee -a $LOGPATH
EXITCODE=1
fi
CHECK_STD_MEM_ALLOC_ABSENCE="(\bfree\b\(|\bmalloc\b\(|\bcalloc\b\(|\brealloc\b\(|=.*\bfree\b|=.*\bmalloc\b|=.*\bcalloc\b|=.*\brealloc\b)"
EXCLUDE_STD_MEM_IMPLEM="*\/p_sopc_mem_alloc.c"
find $CSRC -not -path $EXCLUDE_STD_MEM_IMPLEM -name "*.c" | xargs grep -E $CHECK_STD_MEM_ALLOC_ABSENCE | grep -Ec ":[^0]+" | xargs test 0 -eq
if [[ $? != 0 ]]; then
echo "ERROR: checking absence of std library use for memory allocation in tookit" | tee -a $LOGPATH
find $CSRC -not -path $EXCLUDE_STD_MEM_IMPLEM -name "*.c" | xargs grep -nE $CHECK_STD_MEM_ALLOC_ABSENCE | tee -a $LOGPATH
EXITCODE=1
fi
find $TST -name "*.c" | xargs grep -E $CHECK_STD_MEM_ALLOC_ABSENCE | grep -Ec ":[^0]+" | xargs test 0 -eq
if [[ $? != 0 ]]; then
echo "ERROR: checking absence of std library use for memory allocation in tests" | tee -a $LOGPATH
find $TST -name "*.c" | xargs grep -nE $CHECK_STD_MEM_ALLOC_ABSENCE | tee -a $LOGPATH
EXITCODE=1
fi
find $DEMO -name "*.c" | xargs grep -E $CHECK_STD_MEM_ALLOC_ABSENCE | grep -Ec ":[^0]+" | xargs test 0 -eq
if [[ $? != 0 ]]; then
echo "ERROR: checking absence of std library use for memory allocation in tests" | tee -a $LOGPATH
find $DEMO -name "*.c" | xargs grep -nE $CHECK_STD_MEM_ALLOC_ABSENCE | tee -a $LOGPATH
EXITCODE=1
fi
#### Clang static analyzer ####
echo "Compilation with Clang static analyzer" | tee -a $LOGPATH
rm -fr build-analyzer && ./.run-clang-static-analyzer.sh 2>&1 | tee -a $LOGPATH
# Keep result
STATIC_ANALYSIS_STATUS=${PIPESTATUS[0]}
## Analyze C sources with clang-tidy ####
echo "Checking specific CERT rules using clang-tidy tool" | tee -a $LOGPATH
# CERT rules to verify
if [[ -z $ISADVANCED || $ISADVANCED != "advanced" ]]; then
# remove default rules
REMOVE_DEFAULT_RULES="-*,"
else
# do not remove default rules
echo "clang-tidy tool: keep default rules for advanced analysis of code" | tee -a $LOGPATH
REMOVE_DEFAULT_RULES=""
fi
CERT_RULES=cert-flp30-c,cert-fio38-c,cert-env33-c,cert-err34-c,cert-msc30-c
# Define include directories
SRC_DIRS=(`find $CSRC -not -path "*windows*" -not -path "*freertos*" -not -path "*zephyr*" -not -path "*pikeos*" -type d`)
SRC_INCL=${SRC_DIRS[@]/#/-I}
# includes the generated export file
SRC_INCL="$SRC_INCL -Ibuild-analyzer/src/Common"
# mandatory include for CycloneCRYPTO
SRC_INCL="$SRC_INCL -I/usr/local/include/cyclone_crypto"
CLANG_TIDY_LOG=clang_tidy.log
# Run clang-tidy removing default checks (-*) and adding CERT rules verification
find $CSRC -not -path "*windows*" -not -path "*freertos*" -not -path "*zephyr*" -not -path "*uanodeset_expat*" -not -path "*pikeos*" -name "*.c" -exec clang-tidy {} -warnings-as-errors -header-filter=.* -checks=$REMOVE_DEFAULT_RULES$CERT_RULES -- $SRC_INCL -D_GNU_SOURCE -D__error_t_defined \; &> $CLANG_TIDY_LOG
# Check if resulting log contains error or warnings
grep -wiEc "(error|warning)" $CLANG_TIDY_LOG | xargs test 0 -eq
if [[ $? != 0 ]]; then
echo "ERROR: checking CERT rules $CERT_RULES with clang-tidy: see log $CLANG_TIDY_LOG" | tee -a $LOGPATH
# Note: for default checks the scan-build tool can be use to build the project (scan-build ./build.sh).
# It generates an HTML report providing diagnostics of the warning
EXITCODE=1
else
\rm $CLANG_TIDY_LOG
fi
# Remove static analysis build since it is not necessary anymore
if [[ $STATIC_ANALYSIS_STATUS != 0 ]]; then
# Do not remove in case of analysis failure
EXITCODE=1
else
rm -fr build-analyzer
fi
#### Format C sources with clang-format ####
echo "Clang automatic formatting check" | tee -a $LOGPATH
./.format.sh >> $LOGPATH
ALREADY_FORMAT=`git ls-files -m $BSRC $CSRC $TST $DEMO | grep -v bgenc`
if [[ -z $ALREADY_FORMAT ]]; then
echo "C source code formatting already done" | tee -a $LOGPATH
else
echo "ERROR: C source code code formatting not done or not committed" | tee -a $LOGPATH
git diff | tee -a $LOGPATH
EXITCODE=1
fi
if [[ $EXITCODE -eq 0 ]]; then
echo "Completed with SUCCESS" | tee -a $LOGPATH
else
echo "Completed with ERRORS" | tee -a $LOGPATH
fi
#### Check license in files ####
echo "License in files verification" | tee -a $LOGPATH
./.license-check.sh >> $LOGPATH
if [[ $? != 0 ]]; then
echo "ERROR: license in files verification failed, see $LOGPATH" | tee -a $LOGPATH
EXITCODE=1
fi
#### Check final result:
if [[ $EXITCODE -eq 0 ]]; then
echo "Completed with SUCCESS" | tee -a $LOGPATH
else
echo "Completed with ERRORS, see $LOGPATH" | tee -a $LOGPATH
fi
exit $EXITCODE