cppcheck-py 2.16.0__py3-none-win_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cppcheck/__init__.py +55 -0
- cppcheck/cppcheck-2.16.0.tar.gz +0 -0
- cppcheck/data/addons/__init__.py +0 -0
- cppcheck/data/addons/cppcheck.py +41 -0
- cppcheck/data/addons/cppcheckdata.py +1718 -0
- cppcheck/data/addons/findcasts.py +32 -0
- cppcheck/data/addons/misc.py +163 -0
- cppcheck/data/addons/misra.py +4992 -0
- cppcheck/data/addons/misra_9.py +559 -0
- cppcheck/data/addons/naming.py +91 -0
- cppcheck/data/addons/namingng.py +420 -0
- cppcheck/data/addons/runaddon.py +16 -0
- cppcheck/data/addons/threadsafety.py +350 -0
- cppcheck/data/addons/y2038.py +241 -0
- cppcheck/data/cfg/avr.cfg +402 -0
- cppcheck/data/cfg/bento4.cfg +142 -0
- cppcheck/data/cfg/boost.cfg +1284 -0
- cppcheck/data/cfg/bsd.cfg +567 -0
- cppcheck/data/cfg/cairo.cfg +89 -0
- cppcheck/data/cfg/cppcheck-lib.cfg +72 -0
- cppcheck/data/cfg/cppunit.cfg +48 -0
- cppcheck/data/cfg/dpdk.cfg +11 -0
- cppcheck/data/cfg/embedded_sql.cfg +4 -0
- cppcheck/data/cfg/emscripten.cfg +108 -0
- cppcheck/data/cfg/ginac.cfg +12848 -0
- cppcheck/data/cfg/gnu.cfg +1699 -0
- cppcheck/data/cfg/googletest.cfg +60 -0
- cppcheck/data/cfg/gtk.cfg +21364 -0
- cppcheck/data/cfg/icu.cfg +221 -0
- cppcheck/data/cfg/kde.cfg +87 -0
- cppcheck/data/cfg/libcerror.cfg +203 -0
- cppcheck/data/cfg/libcurl.cfg +487 -0
- cppcheck/data/cfg/libsigc++.cfg +36 -0
- cppcheck/data/cfg/lua.cfg +316 -0
- cppcheck/data/cfg/mfc.cfg +271 -0
- cppcheck/data/cfg/microsoft_atl.cfg +40 -0
- cppcheck/data/cfg/microsoft_sal.cfg +490 -0
- cppcheck/data/cfg/microsoft_unittest.cfg +20 -0
- cppcheck/data/cfg/motif.cfg +318 -0
- cppcheck/data/cfg/nspr.cfg +38 -0
- cppcheck/data/cfg/ntl.cfg +6907 -0
- cppcheck/data/cfg/opencv2.cfg +132 -0
- cppcheck/data/cfg/opengl.cfg +581 -0
- cppcheck/data/cfg/openmp.cfg +157 -0
- cppcheck/data/cfg/openssl.cfg +174 -0
- cppcheck/data/cfg/pcre.cfg +165 -0
- cppcheck/data/cfg/posix.cfg +6438 -0
- cppcheck/data/cfg/protobuf.cfg +9 -0
- cppcheck/data/cfg/python.cfg +674 -0
- cppcheck/data/cfg/qt.cfg +5468 -0
- cppcheck/data/cfg/ruby.cfg +142 -0
- cppcheck/data/cfg/sdl.cfg +354 -0
- cppcheck/data/cfg/selinux.cfg +3621 -0
- cppcheck/data/cfg/sfml.cfg +301 -0
- cppcheck/data/cfg/sqlite3.cfg +1571 -0
- cppcheck/data/cfg/std.cfg +9143 -0
- cppcheck/data/cfg/tinyxml2.cfg +37 -0
- cppcheck/data/cfg/vcl.cfg +4 -0
- cppcheck/data/cfg/windows.cfg +17181 -0
- cppcheck/data/cfg/wxsqlite3.cfg +1955 -0
- cppcheck/data/cfg/wxsvg.cfg +16905 -0
- cppcheck/data/cfg/wxwidgets.cfg +17229 -0
- cppcheck/data/cfg/zephyr.cfg +113 -0
- cppcheck/data/cfg/zlib.cfg +1450 -0
- cppcheck/data/cppcheck-htmlreport +990 -0
- cppcheck/data/cppcheck.exe +0 -0
- cppcheck/data/platforms/aix_ppc64.xml +18 -0
- cppcheck/data/platforms/arm32-wchar_t2.xml +18 -0
- cppcheck/data/platforms/arm32-wchar_t4.xml +18 -0
- cppcheck/data/platforms/arm64-wchar_t2.xml +18 -0
- cppcheck/data/platforms/arm64-wchar_t4.xml +18 -0
- cppcheck/data/platforms/avr8.xml +18 -0
- cppcheck/data/platforms/cray_sv1.xml +18 -0
- cppcheck/data/platforms/elbrus-e1cp.xml +18 -0
- cppcheck/data/platforms/mips32.xml +18 -0
- cppcheck/data/platforms/msp430_eabi_large_datamodel.xml +18 -0
- cppcheck/data/platforms/pic16.xml +18 -0
- cppcheck/data/platforms/pic8-enhanced.xml +18 -0
- cppcheck/data/platforms/pic8.xml +18 -0
- cppcheck/data/platforms/unix32-unsigned.xml +18 -0
- cppcheck/data/platforms/unix64-unsigned.xml +18 -0
- cppcheck_py-2.16.0.dist-info/METADATA +76 -0
- cppcheck_py-2.16.0.dist-info/RECORD +86 -0
- cppcheck_py-2.16.0.dist-info/WHEEL +5 -0
- cppcheck_py-2.16.0.dist-info/entry_points.txt +4 -0
- cppcheck_py-2.16.0.dist-info/licenses/LICENSE.md +191 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
cppcheck addon for threadsafety detection.
|
|
4
|
+
|
|
5
|
+
This script analyses Cppcheck dump files to locate threadsafety issues.
|
|
6
|
+
It warns about
|
|
7
|
+
- static local objects
|
|
8
|
+
- MT-Unsafe symbols listed in the "Attributes" sections of man pages.
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
import cppcheckdata
|
|
16
|
+
|
|
17
|
+
# --------------------------------
|
|
18
|
+
# List of MT-Unsafe identifiers
|
|
19
|
+
# --------------------------------
|
|
20
|
+
|
|
21
|
+
# This is Work In Progress.
|
|
22
|
+
# Eventually it should contain all identifiers (types
|
|
23
|
+
# and functions) which are MT-Unsafe.
|
|
24
|
+
|
|
25
|
+
# The script tools/MT-Unsafe.py can help to re-generate this list.
|
|
26
|
+
# It reads a man-page tree and report identifiers marked as "MT-Unsafe"
|
|
27
|
+
# (see man 7 attributes for what this means), eg
|
|
28
|
+
# MT-Unsafe.py /usr/share/man/man3
|
|
29
|
+
|
|
30
|
+
id_MTunsafe_full = {
|
|
31
|
+
# MT-Unsafe types by definition
|
|
32
|
+
# 'pthread_t',
|
|
33
|
+
# Types marked MT-Unsafe
|
|
34
|
+
'const:env',
|
|
35
|
+
'const:hostid',
|
|
36
|
+
'const:mallopt',
|
|
37
|
+
'const:sigintr',
|
|
38
|
+
'race:LogMask',
|
|
39
|
+
'race:asctime',
|
|
40
|
+
'race:crypt',
|
|
41
|
+
'race:crypt_gensalt',
|
|
42
|
+
'race:cuserid/!string',
|
|
43
|
+
'race:dirstream',
|
|
44
|
+
'race:drand48',
|
|
45
|
+
'race:ecvt',
|
|
46
|
+
'race:exit',
|
|
47
|
+
'race:fcvt',
|
|
48
|
+
'race:fgetgrent',
|
|
49
|
+
'race:fgetpwent',
|
|
50
|
+
'race:fgetspent',
|
|
51
|
+
'race:fsent',
|
|
52
|
+
'race:getdate',
|
|
53
|
+
'race:getlogin',
|
|
54
|
+
'race:getopt',
|
|
55
|
+
'race:getspent',
|
|
56
|
+
'race:getspnam',
|
|
57
|
+
'race:grent',
|
|
58
|
+
'race:grgid',
|
|
59
|
+
'race:grnam',
|
|
60
|
+
'race:hostbyaddr',
|
|
61
|
+
'race:hostbyname',
|
|
62
|
+
'race:hostbyname2',
|
|
63
|
+
'race:hostent',
|
|
64
|
+
'race:hsearch',
|
|
65
|
+
'race:l64a',
|
|
66
|
+
'race:localeconv',
|
|
67
|
+
'race:mbrlen/!ps',
|
|
68
|
+
'race:mbrtowc/!ps',
|
|
69
|
+
'race:mbsnrtowcs/!ps',
|
|
70
|
+
'race:mbsrtowcs/!ps',
|
|
71
|
+
'race:mcheck',
|
|
72
|
+
'race:mntentbuf',
|
|
73
|
+
'race:netbyaddr',
|
|
74
|
+
'race:netbyname',
|
|
75
|
+
'race:netent',
|
|
76
|
+
'race:netgrent',
|
|
77
|
+
'race:protobyname',
|
|
78
|
+
'race:protobynumber',
|
|
79
|
+
'race:protoent',
|
|
80
|
+
'race:ptsname',
|
|
81
|
+
'race:pwent',
|
|
82
|
+
'race:pwnam',
|
|
83
|
+
'race:pwuid',
|
|
84
|
+
'race:qecvt',
|
|
85
|
+
'race:qfcvt',
|
|
86
|
+
'race:servbyname',
|
|
87
|
+
'race:servbyport',
|
|
88
|
+
'race:servent',
|
|
89
|
+
'race:sgetspent',
|
|
90
|
+
'race:signgam',
|
|
91
|
+
'race:stdin',
|
|
92
|
+
'race:stdout',
|
|
93
|
+
'race:streams',
|
|
94
|
+
'race:strerror',
|
|
95
|
+
'race:strsignal',
|
|
96
|
+
'race:strtok',
|
|
97
|
+
'race:tmbuf',
|
|
98
|
+
'race:tmpnam/!s',
|
|
99
|
+
'race:ttyent',
|
|
100
|
+
'race:ttyname',
|
|
101
|
+
'race:utent',
|
|
102
|
+
'race:wcrtomb/!ps',
|
|
103
|
+
'race:wcsnrtombs/!ps',
|
|
104
|
+
'race:wcsrtombs/!ps',
|
|
105
|
+
'sig:ALRM',
|
|
106
|
+
'sig:SIGCHLD/linux',
|
|
107
|
+
# APIs marked MT-Unsafe
|
|
108
|
+
'asctime',
|
|
109
|
+
'clearenv',
|
|
110
|
+
'ctime',
|
|
111
|
+
'cuserid',
|
|
112
|
+
'drand48',
|
|
113
|
+
'ecvt',
|
|
114
|
+
'encrypt',
|
|
115
|
+
'endfsent',
|
|
116
|
+
'endgrent',
|
|
117
|
+
'endhostent',
|
|
118
|
+
'endnetent',
|
|
119
|
+
'endnetgrent',
|
|
120
|
+
'endprotoent',
|
|
121
|
+
'endpwent',
|
|
122
|
+
'endservent',
|
|
123
|
+
'endspent',
|
|
124
|
+
'endttyent',
|
|
125
|
+
'endusershell',
|
|
126
|
+
'endutent',
|
|
127
|
+
'erand48',
|
|
128
|
+
'error_at_line',
|
|
129
|
+
'ether_aton',
|
|
130
|
+
'ether_ntoa',
|
|
131
|
+
'exit',
|
|
132
|
+
'fcloseall',
|
|
133
|
+
'fcvt',
|
|
134
|
+
'fgetgrent',
|
|
135
|
+
'fgetpwent',
|
|
136
|
+
'fgetspent',
|
|
137
|
+
'fts_children',
|
|
138
|
+
'fts_read',
|
|
139
|
+
'gamma',
|
|
140
|
+
'gammaf',
|
|
141
|
+
'gammal',
|
|
142
|
+
'getaliasbyname',
|
|
143
|
+
'getaliasent',
|
|
144
|
+
'getchar_unlocked',
|
|
145
|
+
'getdate',
|
|
146
|
+
'getfsent',
|
|
147
|
+
'getfsfile',
|
|
148
|
+
'getfsspec',
|
|
149
|
+
'getgrent',
|
|
150
|
+
'getgrent_r',
|
|
151
|
+
'getgrgid',
|
|
152
|
+
'getgrnam',
|
|
153
|
+
'gethostbyaddr',
|
|
154
|
+
'gethostbyname',
|
|
155
|
+
'gethostbyname2',
|
|
156
|
+
'gethostent',
|
|
157
|
+
'gethostent_r',
|
|
158
|
+
'getlogin',
|
|
159
|
+
'getlogin_r',
|
|
160
|
+
'getmntent',
|
|
161
|
+
'getnetbyaddr',
|
|
162
|
+
'getnetbyname',
|
|
163
|
+
'getnetent',
|
|
164
|
+
'getnetgrent',
|
|
165
|
+
'getnetgrent_r',
|
|
166
|
+
'getopt',
|
|
167
|
+
'getopt_long',
|
|
168
|
+
'getopt_long_only',
|
|
169
|
+
'getpass',
|
|
170
|
+
'getprotobyname',
|
|
171
|
+
'getprotobynumber',
|
|
172
|
+
'getprotoent',
|
|
173
|
+
'getpwent',
|
|
174
|
+
'getpwent_r',
|
|
175
|
+
'getpwnam',
|
|
176
|
+
'getpwuid',
|
|
177
|
+
'getrpcbyname',
|
|
178
|
+
'getrpcbynumber',
|
|
179
|
+
'getrpcent',
|
|
180
|
+
'getservbyname',
|
|
181
|
+
'getservbyport',
|
|
182
|
+
'getservent',
|
|
183
|
+
'getspent',
|
|
184
|
+
'getspent_r',
|
|
185
|
+
'getspnam',
|
|
186
|
+
'getttyent',
|
|
187
|
+
'getttynam',
|
|
188
|
+
'getusershell',
|
|
189
|
+
'getutent',
|
|
190
|
+
'getutid',
|
|
191
|
+
'getutline',
|
|
192
|
+
'getwchar_unlocked',
|
|
193
|
+
'glob',
|
|
194
|
+
'gmtime',
|
|
195
|
+
'hcreate',
|
|
196
|
+
'hdestroy',
|
|
197
|
+
'hsearch',
|
|
198
|
+
'innetgr',
|
|
199
|
+
'jrand48',
|
|
200
|
+
'l64a',
|
|
201
|
+
'lcong48',
|
|
202
|
+
'localeconv',
|
|
203
|
+
'localtime',
|
|
204
|
+
'login',
|
|
205
|
+
'login_tty',
|
|
206
|
+
'logout',
|
|
207
|
+
'logwtmp',
|
|
208
|
+
'lrand48',
|
|
209
|
+
'mallinfo',
|
|
210
|
+
'mallinfo2',
|
|
211
|
+
'mblen',
|
|
212
|
+
'mbrlen',
|
|
213
|
+
'mbrtowc',
|
|
214
|
+
'mbsnrtowcs',
|
|
215
|
+
'mbsrtowcs',
|
|
216
|
+
'mbtowc',
|
|
217
|
+
'mcheck',
|
|
218
|
+
'mcheck_check_all',
|
|
219
|
+
'mcheck_pedantic',
|
|
220
|
+
'mprobe',
|
|
221
|
+
'mrand48',
|
|
222
|
+
'mtrace',
|
|
223
|
+
'muntrace',
|
|
224
|
+
'nrand48',
|
|
225
|
+
'profil',
|
|
226
|
+
'ptsname',
|
|
227
|
+
'putchar_unlocked',
|
|
228
|
+
'putenv',
|
|
229
|
+
'pututline',
|
|
230
|
+
'putwchar_unlocked',
|
|
231
|
+
'pvalloc',
|
|
232
|
+
'qecvt',
|
|
233
|
+
'qfcvt',
|
|
234
|
+
'rcmd',
|
|
235
|
+
'rcmd_af',
|
|
236
|
+
're_comp',
|
|
237
|
+
're_exec',
|
|
238
|
+
'readdir',
|
|
239
|
+
'rexec',
|
|
240
|
+
'rexec_af',
|
|
241
|
+
'seed48',
|
|
242
|
+
'setenv',
|
|
243
|
+
'setfsent',
|
|
244
|
+
'setgrent',
|
|
245
|
+
'sethostent',
|
|
246
|
+
'sethostid',
|
|
247
|
+
'setkey',
|
|
248
|
+
'setlogmask',
|
|
249
|
+
'setnetent',
|
|
250
|
+
'setnetgrent',
|
|
251
|
+
'setprotoent',
|
|
252
|
+
'setpwent',
|
|
253
|
+
'setservent',
|
|
254
|
+
'setspent',
|
|
255
|
+
'setttyent',
|
|
256
|
+
'setusershell',
|
|
257
|
+
'setutent',
|
|
258
|
+
'sgetspent',
|
|
259
|
+
'siginterrupt',
|
|
260
|
+
'sleep',
|
|
261
|
+
'srand48',
|
|
262
|
+
'strerror',
|
|
263
|
+
'strsignal',
|
|
264
|
+
'strtok',
|
|
265
|
+
'tmpnam',
|
|
266
|
+
'ttyname',
|
|
267
|
+
'ttyslot',
|
|
268
|
+
'unsetenv',
|
|
269
|
+
'updwtmp',
|
|
270
|
+
'utmpname',
|
|
271
|
+
'valloc',
|
|
272
|
+
'wcrtomb',
|
|
273
|
+
'wcsnrtombs',
|
|
274
|
+
'wcsrtombs',
|
|
275
|
+
'wctomb',
|
|
276
|
+
'wordexp'
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
# From man 7 attributes
|
|
280
|
+
# the full token could be feature:function/condition - we just want function.
|
|
281
|
+
id_MTunsafe = [re.sub('^.*:', '', re.sub('/.*$', '', x))
|
|
282
|
+
for x in id_MTunsafe_full
|
|
283
|
+
]
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def reportError(token, severity, msg, errid): # noqa: D103
|
|
287
|
+
cppcheckdata.reportError(token, severity, msg, 'threadsafety', errid)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def checkstatic(data): # noqa: D103
|
|
291
|
+
for var in data.variables:
|
|
292
|
+
if var.isStatic and var.isLocal:
|
|
293
|
+
vartype = None
|
|
294
|
+
if var.isClass:
|
|
295
|
+
vartype = 'object'
|
|
296
|
+
else:
|
|
297
|
+
vartype = 'variable'
|
|
298
|
+
if var.isConst:
|
|
299
|
+
if data.standards.cpp == 'c++03':
|
|
300
|
+
reportError(
|
|
301
|
+
var.typeStartToken,
|
|
302
|
+
'warning',
|
|
303
|
+
'Local constant static '
|
|
304
|
+
+ vartype + "'" + var.nameToken.str
|
|
305
|
+
+ "', dangerous if it is initialized"
|
|
306
|
+
+ ' in parallel threads',
|
|
307
|
+
'threadsafety-const')
|
|
308
|
+
else:
|
|
309
|
+
reportError(var.typeStartToken, 'warning',
|
|
310
|
+
'Local static ' + vartype + ': '
|
|
311
|
+
+ var.nameToken.str,
|
|
312
|
+
'threadsafety')
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def check_MTunsafe(cfg):
|
|
316
|
+
"""
|
|
317
|
+
Look for functions marked MT-unsafe in their man pages.
|
|
318
|
+
|
|
319
|
+
The MT-unsafe functions are listed in id_MTunsafe (and id_MTunsafe_full).
|
|
320
|
+
That section of code can be regenerated by the external script MT-Unsafe.py
|
|
321
|
+
"""
|
|
322
|
+
for token in cfg.tokenlist:
|
|
323
|
+
if token.str in id_MTunsafe:
|
|
324
|
+
reportError(token, 'warning', token.str + ' is MT-unsafe',
|
|
325
|
+
'unsafe-call')
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
if __name__ == '__main__':
|
|
329
|
+
parser = cppcheckdata.ArgumentParser()
|
|
330
|
+
args = parser.parse_args()
|
|
331
|
+
|
|
332
|
+
quiet = args.quiet or args.cli
|
|
333
|
+
|
|
334
|
+
if not args.dumpfile:
|
|
335
|
+
if not args.quiet:
|
|
336
|
+
print('no input files.')
|
|
337
|
+
sys.exit(0)
|
|
338
|
+
|
|
339
|
+
for dumpfile in args.dumpfile:
|
|
340
|
+
# load XML from .dump file
|
|
341
|
+
data = cppcheckdata.CppcheckData(dumpfile)
|
|
342
|
+
|
|
343
|
+
for cfg in data.iterconfigurations():
|
|
344
|
+
if not args.quiet:
|
|
345
|
+
srcfile = data.files[0]
|
|
346
|
+
print('Checking %s, config %s...' % (srcfile, cfg.name))
|
|
347
|
+
check_MTunsafe(cfg)
|
|
348
|
+
checkstatic(cfg)
|
|
349
|
+
|
|
350
|
+
sys.exit(cppcheckdata.EXIT_CODE)
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# cppcheck addon for Y2038 safeness detection
|
|
4
|
+
#
|
|
5
|
+
# Detects:
|
|
6
|
+
#
|
|
7
|
+
# 1. _TIME_BITS being defined to something else than 64 bits
|
|
8
|
+
# 2. _USE_TIME_BITS64 being defined when _TIME_BITS is not
|
|
9
|
+
# 3. Any Y2038-unsafe symbol when _USE_TIME_BITS64 is not defined.
|
|
10
|
+
#
|
|
11
|
+
# Example usage:
|
|
12
|
+
# $ cppcheck --addon=y2038 path-to-src/test.c
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
from __future__ import print_function
|
|
16
|
+
|
|
17
|
+
import cppcheckdata
|
|
18
|
+
import sys
|
|
19
|
+
import re
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# --------------------------------------------
|
|
23
|
+
# #define/#undef detection regular expressions
|
|
24
|
+
# --------------------------------------------
|
|
25
|
+
|
|
26
|
+
# test for '#define _TIME_BITS 64'
|
|
27
|
+
re_define_time_bits_64 = re.compile(r'^\s*#\s*define\s+_TIME_BITS\s+64\s*$')
|
|
28
|
+
|
|
29
|
+
# test for '#define _TIME_BITS ...' (combine w/ above to test for 'not 64')
|
|
30
|
+
re_define_time_bits = re.compile(r'^\s*#\s*define\s+_TIME_BITS\s+.*$')
|
|
31
|
+
|
|
32
|
+
# test for '#undef _TIME_BITS' (if it ever happens)
|
|
33
|
+
re_undef_time_bits = re.compile(r'^\s*#\s*undef\s+_TIME_BITS\s*$')
|
|
34
|
+
|
|
35
|
+
# test for '#define _USE_TIME_BITS64'
|
|
36
|
+
re_define_use_time_bits64 = re.compile(r'^\s*#\s*define\s+_USE_TIME_BITS64\s*$')
|
|
37
|
+
|
|
38
|
+
# test for '#undef _USE_TIME_BITS64' (if it ever happens)
|
|
39
|
+
re_undef_use_time_bits64 = re.compile(r'^\s*#\s*undef\s+_USE_TIME_BITS64\s*$')
|
|
40
|
+
|
|
41
|
+
# --------------------------------
|
|
42
|
+
# List of Y2038-unsafe identifiers
|
|
43
|
+
# --------------------------------
|
|
44
|
+
|
|
45
|
+
# This is WIP. Eventually it should contain all identifiers (types
|
|
46
|
+
# and functions) which would be affected by the Y2038 bug.
|
|
47
|
+
|
|
48
|
+
id_Y2038 = {
|
|
49
|
+
# Y2038-unsafe types by definition
|
|
50
|
+
'time_t'
|
|
51
|
+
# Types using Y2038-unsafe types
|
|
52
|
+
'lastlog',
|
|
53
|
+
'msqid_ds',
|
|
54
|
+
'semid_ds',
|
|
55
|
+
'timeb',
|
|
56
|
+
'timespec',
|
|
57
|
+
'timeval',
|
|
58
|
+
'utimbuf',
|
|
59
|
+
'itimerspec',
|
|
60
|
+
'clnt_ops',
|
|
61
|
+
'elf_prstatus',
|
|
62
|
+
'itimerval',
|
|
63
|
+
'ntptimeval',
|
|
64
|
+
'rusage',
|
|
65
|
+
'timex',
|
|
66
|
+
'utmp',
|
|
67
|
+
'utmpx',
|
|
68
|
+
# APIs using 2038-unsafe types
|
|
69
|
+
'ctime',
|
|
70
|
+
'ctime_r',
|
|
71
|
+
'difftime',
|
|
72
|
+
'gmtime',
|
|
73
|
+
'gmtime_r',
|
|
74
|
+
'localtime',
|
|
75
|
+
'localtime_r',
|
|
76
|
+
'mktime',
|
|
77
|
+
'stime',
|
|
78
|
+
'timegm',
|
|
79
|
+
'timelocal',
|
|
80
|
+
'time',
|
|
81
|
+
'msgctl',
|
|
82
|
+
'ftime',
|
|
83
|
+
'aio_suspend',
|
|
84
|
+
'clock_getres',
|
|
85
|
+
'clock_gettime',
|
|
86
|
+
'clock_nanosleep',
|
|
87
|
+
'clock_settime',
|
|
88
|
+
'futimens',
|
|
89
|
+
'mq_timedreceive',
|
|
90
|
+
'mq_timedsend',
|
|
91
|
+
'nanosleep',
|
|
92
|
+
'pselect',
|
|
93
|
+
'pthread_cond_timedwait',
|
|
94
|
+
'pthread_mutex_timedlock',
|
|
95
|
+
'pthread_rwlock_timedrdlock',
|
|
96
|
+
'pthread_rwlock_timedwrlock',
|
|
97
|
+
'sched_rr_get_interval',
|
|
98
|
+
'sem_timedwait',
|
|
99
|
+
'sigtimedwait',
|
|
100
|
+
'timespec_get',
|
|
101
|
+
'utimensat',
|
|
102
|
+
'adjtime',
|
|
103
|
+
'pmap_rmtcall',
|
|
104
|
+
'clntudp_bufcreate',
|
|
105
|
+
'clntudp_create',
|
|
106
|
+
'futimes',
|
|
107
|
+
'gettimeofday',
|
|
108
|
+
'lutimes',
|
|
109
|
+
'select',
|
|
110
|
+
'settimeofday',
|
|
111
|
+
'utimes',
|
|
112
|
+
'utime',
|
|
113
|
+
'timerfd_gettime',
|
|
114
|
+
'timerfd_settime',
|
|
115
|
+
'timer_gettime',
|
|
116
|
+
'timer_settime',
|
|
117
|
+
'fstatat',
|
|
118
|
+
'fstat',
|
|
119
|
+
'__fxstatat',
|
|
120
|
+
'__fxstat',
|
|
121
|
+
'lstat',
|
|
122
|
+
'__lxstat',
|
|
123
|
+
'stat',
|
|
124
|
+
'__xstat',
|
|
125
|
+
'struct itimerval',
|
|
126
|
+
'setitimer',
|
|
127
|
+
'getitimer',
|
|
128
|
+
'ntp_gettime',
|
|
129
|
+
'getrusage',
|
|
130
|
+
'wait3',
|
|
131
|
+
'wait4',
|
|
132
|
+
'adjtimex',
|
|
133
|
+
'ntp_adjtime',
|
|
134
|
+
'getutent_r',
|
|
135
|
+
'getutent',
|
|
136
|
+
'getutid_r',
|
|
137
|
+
'getutid',
|
|
138
|
+
'getutline_r',
|
|
139
|
+
'getutline',
|
|
140
|
+
'login',
|
|
141
|
+
'pututline',
|
|
142
|
+
'updwtmp',
|
|
143
|
+
'getutxent',
|
|
144
|
+
'getutxid',
|
|
145
|
+
'getutxline',
|
|
146
|
+
'pututxline'
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def check_y2038_safe(dumpfile, quiet=False):
|
|
151
|
+
# Assume that the code is Y2038 safe until proven otherwise
|
|
152
|
+
y2038safe = True
|
|
153
|
+
# load XML from .dump file
|
|
154
|
+
data = cppcheckdata.CppcheckData(dumpfile)
|
|
155
|
+
|
|
156
|
+
srcfile = data.files[0]
|
|
157
|
+
for cfg in data.iterconfigurations():
|
|
158
|
+
if not quiet:
|
|
159
|
+
print('Checking %s, config %s...' % (srcfile, cfg.name))
|
|
160
|
+
safe_ranges = []
|
|
161
|
+
safe = -1
|
|
162
|
+
time_bits_defined = False
|
|
163
|
+
srclinenr = 0
|
|
164
|
+
|
|
165
|
+
for directive in cfg.directives:
|
|
166
|
+
# track source line number
|
|
167
|
+
if directive.file == srcfile:
|
|
168
|
+
srclinenr = directive.linenr
|
|
169
|
+
# check for correct _TIME_BITS if present
|
|
170
|
+
if re_define_time_bits_64.match(directive.str):
|
|
171
|
+
time_bits_defined = True
|
|
172
|
+
elif re_define_time_bits.match(directive.str):
|
|
173
|
+
cppcheckdata.reportError(directive, 'error',
|
|
174
|
+
'_TIME_BITS must be defined equal to 64',
|
|
175
|
+
'y2038',
|
|
176
|
+
'type-bits-not-64')
|
|
177
|
+
time_bits_defined = False
|
|
178
|
+
y2038safe = False
|
|
179
|
+
elif re_undef_time_bits.match(directive.str):
|
|
180
|
+
time_bits_defined = False
|
|
181
|
+
# check for _USE_TIME_BITS64 (un)definition
|
|
182
|
+
if re_define_use_time_bits64.match(directive.str):
|
|
183
|
+
safe = int(srclinenr)
|
|
184
|
+
# warn about _TIME_BITS not being defined
|
|
185
|
+
if not time_bits_defined:
|
|
186
|
+
cppcheckdata.reportError(directive, 'warning',
|
|
187
|
+
'_USE_TIME_BITS64 is defined but _TIME_BITS was not',
|
|
188
|
+
'y2038',
|
|
189
|
+
'type-bits-undef')
|
|
190
|
+
elif re_undef_use_time_bits64.match(directive.str):
|
|
191
|
+
unsafe = int(srclinenr)
|
|
192
|
+
# do we have a safe..unsafe area?
|
|
193
|
+
if unsafe > safe > 0:
|
|
194
|
+
safe_ranges.append((safe, unsafe))
|
|
195
|
+
safe = -1
|
|
196
|
+
|
|
197
|
+
# check end of source beyond last directive
|
|
198
|
+
if len(cfg.tokenlist) > 0:
|
|
199
|
+
unsafe = int(cfg.tokenlist[-1].linenr)
|
|
200
|
+
if unsafe > safe > 0:
|
|
201
|
+
safe_ranges.append((safe, unsafe))
|
|
202
|
+
|
|
203
|
+
# go through all tokens
|
|
204
|
+
for token in cfg.tokenlist:
|
|
205
|
+
if token.str in id_Y2038:
|
|
206
|
+
if not any(lower <= int(token.linenr) <= upper
|
|
207
|
+
for (lower, upper) in safe_ranges):
|
|
208
|
+
cppcheckdata.reportError(token, 'warning',
|
|
209
|
+
token.str + ' is Y2038-unsafe',
|
|
210
|
+
'y2038',
|
|
211
|
+
'unsafe-call')
|
|
212
|
+
y2038safe = False
|
|
213
|
+
token = token.next
|
|
214
|
+
|
|
215
|
+
return y2038safe
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def get_args_parser():
|
|
219
|
+
parser = cppcheckdata.ArgumentParser()
|
|
220
|
+
return parser
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
if __name__ == '__main__':
|
|
224
|
+
parser = get_args_parser()
|
|
225
|
+
args = parser.parse_args()
|
|
226
|
+
|
|
227
|
+
exit_code = 0
|
|
228
|
+
quiet = args.quiet or args.cli
|
|
229
|
+
|
|
230
|
+
if not args.dumpfile:
|
|
231
|
+
if not args.quiet:
|
|
232
|
+
print("no input files.")
|
|
233
|
+
sys.exit(0)
|
|
234
|
+
|
|
235
|
+
for dumpfile in args.dumpfile:
|
|
236
|
+
if not quiet:
|
|
237
|
+
print('Checking ' + dumpfile + '...')
|
|
238
|
+
|
|
239
|
+
check_y2038_safe(dumpfile, quiet)
|
|
240
|
+
|
|
241
|
+
sys.exit(cppcheckdata.EXIT_CODE)
|