Bug Summary

File:src/checkpoint.c
Warning:line 182, column 4
Array access results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name checkpoint.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-config-compatibility-mode=true -mrelocation-model static -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -resource-dir /home/nodeapp/petablox-clang/build/lib/clang/9.0.0 -D HAVE_CONFIG_H -I . -I .. -I ../gnu -I ../ -I ../gnu -I ../lib -I ../lib -internal-isystem /usr/local/include -internal-isystem /home/nodeapp/petablox-clang/build/lib/clang/9.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir /home/nodeapp/PetabloxApp/head.176139622.18.d273534c95c487409242f3f4e90e0b6e9a10a4a0.de8879f4db0baa271d9d0422a22f6739bc0cab81/github-demo-tar/src -ferror-limit 19 -fmessage-length 0 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker core.NullDereference -analyzer-checker core.builtin.BuiltinFunctions -analyzer-checker core.builtin.NoReturnFunctions -analyzer-checker core.NonnilStringConstants -analyzer-disable-checker core.NonNullParamChecker -analyzer-disable-checker nullability -analyzer-disable-checker debug.ExprInspection -analyzer-disable-checker debug.DumpCalls -analyzer-disable-checker unix.Malloc -analyzer-disable-checker alpha.security.ArrayBound -analyzer-disable-checker alpha.security.ArrayBoundV2 -analyzer-disable-checker alpha.security.MallocOverflow -analyzer-disable-checker apiModeling.google.GTest -analyzer-disable-checker core.CallAndMessage -analyzer-disable-checker core.DivideZero -analyzer-disable-checker core.DynamicTypePropagation -analyzer-disable-checker core.StackAddressEscape -analyzer-disable-checker core.UndefinedBinaryOperatorResult -analyzer-disable-checker core.VLASize -analyzer-disable-checker core.uninitialized.ArraySubscript -analyzer-disable-checker core.uninitialized.Assign -analyzer-disable-checker core.uninitialized.Branch -analyzer-disable-checker core.uninitialized.CapturedBlockVariable -analyzer-disable-checker core.uninitialized.UndefReturn -analyzer-disable-checker cplusplus.NewDelete -analyzer-disable-checker cplusplus.NewDeleteLeaks -analyzer-disable-checker cplusplus.SelfAssignment -analyzer-disable-checker deadcode.DeadStores -analyzer-disable-checker security.insecureAPI.UncheckedReturn -analyzer-disable-checker security.insecureAPI.getpw -analyzer-disable-checker security.insecureAPI.gets -analyzer-disable-checker security.insecureAPI.mkstemp -analyzer-disable-checker security.insecureAPI.mktemp -analyzer-disable-checker security.insecureAPI.vfork -analyzer-disable-checker unix.API -analyzer-disable-checker unix.MallocSizeof -analyzer-disable-checker unix.MismatchedDeallocator -analyzer-disable-checker unix.Vfork -analyzer-disable-checker unix.cstring.BadSizeArg -analyzer-disable-checker unix.cstring.NullArg -analyzer-output=plist-html -analyzer-config suppress-null-return-paths=false -analyzer-config widen-loops=true -o /home/nodeapp/PetabloxApp/head.176139622.18.d273534c95c487409242f3f4e90e0b6e9a10a4a0.de8879f4db0baa271d9d0422a22f6739bc0cab81/analysis/2020-02-13-105730-21962-1/report-ViK_Iv.plist -x c checkpoint.c -faddrsig
1/* Checkpoint management for tar.
2
3 Copyright 2007, 2013-2014 Free Software Foundation, Inc.
4
5 This file is part of GNU tar.
6
7 GNU tar is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU tar is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include <system.h>
21#include "common.h"
22#include "wordsplit.h"
23#include <sys/ioctl.h>
24#include <termios.h>
25#include "fprintftime.h"
26
27enum checkpoint_opcode
28 {
29 cop_dot,
30 cop_bell,
31 cop_echo,
32 cop_ttyout,
33 cop_sleep,
34 cop_exec,
35 cop_totals
36 };
37
38struct checkpoint_action
39{
40 struct checkpoint_action *next;
41 enum checkpoint_opcode opcode;
42 union
43 {
44 time_t time;
45 char *command;
46 } v;
47};
48
49/* Checkpointing counter */
50static unsigned checkpoint;
51
52/* List of checkpoint actions */
53static struct checkpoint_action *checkpoint_action, *checkpoint_action_tail;
54
55static struct checkpoint_action *
56alloc_action (enum checkpoint_opcode opcode)
57{
58 struct checkpoint_action *p = xzalloc (sizeof *p);
59 if (checkpoint_action_tail)
60 checkpoint_action_tail->next = p;
61 else
62 checkpoint_action = p;
63 checkpoint_action_tail = p;
64 p->opcode = opcode;
65 return p;
66}
67
68static char *
69copy_string_unquote (const char *str)
70{
71 char *output = xstrdup (str);
72 size_t len = strlen (output);
73 if ((*output == '"' || *output == '\'')
74 && output[len-1] == *output)
75 {
76 memmove (output, output+1, len-2);
77 output[len-2] = 0;
78 }
79 unquote_string (output);
80 return output;
81}
82
83void
84checkpoint_compile_action (const char *str)
85{
86 struct checkpoint_action *act;
87
88 if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0)
89 alloc_action (cop_dot);
90 else if (strcmp (str, "bell") == 0)
91 alloc_action (cop_bell);
92 else if (strcmp (str, "echo") == 0)
93 alloc_action (cop_echo);
94 else if (strncmp (str, "echo=", 5) == 0)
95 {
96 act = alloc_action (cop_echo);
97 act->v.command = copy_string_unquote (str + 5);
98 }
99 else if (strncmp (str, "exec=", 5) == 0)
100 {
101 act = alloc_action (cop_exec);
102 act->v.command = copy_string_unquote (str + 5);
103 }
104 else if (strncmp (str, "ttyout=", 7) == 0)
105 {
106 act = alloc_action (cop_ttyout);
107 act->v.command = copy_string_unquote (str + 7);
108 }
109 else if (strncmp (str, "sleep=", 6) == 0)
110 {
111 char *p;
112 time_t n = strtoul (str+6, &p, 10);
113 if (*p)
114 FATAL_ERROR ((0, 0, _("%s: not a valid timeout"), str))do { if (error_hook) error_hook (); error (0, 0, dcgettext ((
(void*)0), "%s: not a valid timeout", 5), str); fatal_exit ()
; } while (0)
;
115 act = alloc_action (cop_sleep);
116 act->v.time = n;
117 }
118 else if (strcmp (str, "totals") == 0)
119 alloc_action (cop_totals);
120 else
121 FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str))do { if (error_hook) error_hook (); error (0, 0, dcgettext ((
(void*)0), "%s: unknown checkpoint action", 5), str); fatal_exit
(); } while (0)
;
122}
123
124void
125checkpoint_finish_compile (void)
126{
127 if (checkpoint_option)
128 {
129 if (!checkpoint_action)
130 /* Provide a historical default */
131 checkpoint_compile_action ("echo");
132 }
133 else if (checkpoint_action)
134 /* Otherwise, set default checkpoint rate */
135 checkpoint_option = DEFAULT_CHECKPOINT10;
136}
137
138static const char *checkpoint_total_format[] = {
139 "R",
140 "W",
141 "D"
142};
143
144static long
145getwidth (FILE *fp)
146{
147 char const *columns;
148
149#ifdef TIOCGWINSZ0x5413
150 struct winsize ws;
151 if (ioctl (fileno (fp), TIOCGWINSZ0x5413, &ws) == 0 && 0 < ws.ws_col)
152 return ws.ws_col;
153#endif
154
155 columns = getenv ("COLUMNS");
156 if (columns)
157 {
158 long int col = strtol (columns, NULL((void*)0), 10);
159 if (0 < col)
160 return col;
161 }
162
163 return 80;
164}
165
166static char *
167getarg (const char *input, const char ** endp, char **argbuf, size_t *arglen)
168{
169 if (input[0] == '{')
22
Taking true branch
170 {
171 char *p = strchr (input + 1, '}');
172 if (p)
23
Assuming 'p' is non-null
24
Taking true branch
173 {
174 size_t n = p - input;
175 if (n > *arglen)
25
Assuming the condition is false
26
Taking false branch
176 {
177 *arglen = n;
178 *argbuf = xrealloc (*argbuf, *arglen);
179 }
180 n--;
181 memcpy (*argbuf, input + 1, n);
182 (*argbuf)[n] = 0;
27
Array access results in a null pointer dereference (BUGPROB:0.531441)
183 *endp = p + 1;
184 return *argbuf;
185 }
186 }
187
188 *endp = input;
189 return NULL((void*)0);
190}
191
192static int tty_cleanup;
193
194static const char *def_format =
195 "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r";
196
197static int
198format_checkpoint_string (FILE *fp, size_t len,
199 const char *input, bool_Bool do_write,
200 unsigned cpn)
201{
202 const char *opstr = do_write ? gettext ("write")dcgettext (((void*)0), "write", 5) : gettext ("read")dcgettext (((void*)0), "read", 5);
11
Assuming 'do_write' is 0
12
'?' condition is false
203 char uintbuf[UINTMAX_STRSIZE_BOUND(((((sizeof (uintmax_t) * 8 - (! ((__typeof__ (uintmax_t)) 0 <
(__typeof__ (uintmax_t)) -1))) * 146 + 484) / 485) + (! ((__typeof__
(uintmax_t)) 0 < (__typeof__ (uintmax_t)) -1))) + 1)
];
204 char *cps = STRINGIFY_BIGINT (cpn, uintbuf)umaxtostr (cpn, uintbuf);
205 const char *ip;
206
207 static char *argbuf = NULL((void*)0);
13
'argbuf' initialized to a null pointer value
208 static size_t arglen = 0;
209 char *arg = NULL((void*)0);
210
211 if (!input)
14
Assuming 'input' is non-null
15
Taking false branch
212 {
213 if (do_write)
214 /* TRANSLATORS: This is a "checkpoint of write operation",
215 *not* "Writing a checkpoint".
216 E.g. in Spanish "Punto de comprobaci@'on de escritura",
217 *not* "Escribiendo un punto de comprobaci@'on" */
218 input = gettext ("Write checkpoint %u")dcgettext (((void*)0), "Write checkpoint %u", 5);
219 else
220 /* TRANSLATORS: This is a "checkpoint of read operation",
221 *not* "Reading a checkpoint".
222 E.g. in Spanish "Punto de comprobaci@'on de lectura",
223 *not* "Leyendo un punto de comprobaci@'on" */
224 input = gettext ("Read checkpoint %u")dcgettext (((void*)0), "Read checkpoint %u", 5);
225 }
226
227 for (ip = input; *ip; ip++)
16
Loop condition is true. Entering loop body
228 {
229 if (*ip == '%')
17
Assuming the condition is true
18
Taking true branch
230 {
231 if (*++ip == '{')
19
Assuming the condition is true
20
Taking true branch
232 {
233 arg = getarg (ip, &ip, &argbuf, &arglen);
21
Calling 'getarg'
234 if (!arg)
235 {
236 fputc ('%', fp)fputc_unlocked ('%',fp);
237 fputc (*ip, fp)fputc_unlocked (*ip,fp);
238 len += 2;
239 continue;
240 }
241 }
242 switch (*ip)
243 {
244 case 'c':
245 len += format_checkpoint_string (fp, len, def_format, do_write,
246 cpn);
247 break;
248
249 case 'u':
250 fputs (cps, fp)fputs_unlocked (cps,fp);
251 len += strlen (cps);
252 break;
253
254 case 's':
255 fputs (opstr, fp)fputs_unlocked (opstr,fp);
256 len += strlen (opstr);
257 break;
258
259 case 'd':
260 len += fprintf (fp, "%.0f", compute_duration ())__fprintf_chk (fp, 2 - 1, "%.0f", compute_duration ());
261 break;
262
263 case 'T':
264 {
265 const char **fmt = checkpoint_total_format, *fmtbuf[3];
266 struct wordsplit ws;
267 compute_duration ();
268
269 if (arg)
270 {
271 ws.ws_delim = ",";
272 if (wordsplit (arg, &ws, WRDSF_NOVAR0x00000040 | WRDSF_NOCMD0x00000004 |
273 WRDSF_QUOTE(0x00000200|0x00000400) | WRDSF_DELIM0x00004000))
274 ERROR ((0, 0, _("cannot split string '%s': %s"),do { if (error_hook) error_hook (); error (0, 0, dcgettext ((
(void*)0), "cannot split string '%s': %s", 5), arg, wordsplit_strerror
(&ws)); exit_status = 2; } while (0)
275 arg, wordsplit_strerror (&ws)))do { if (error_hook) error_hook (); error (0, 0, dcgettext ((
(void*)0), "cannot split string '%s': %s", 5), arg, wordsplit_strerror
(&ws)); exit_status = 2; } while (0)
;
276 else
277 {
278 int i;
279
280 for (i = 0; i < ws.ws_wordc; i++)
281 fmtbuf[i] = ws.ws_wordv[i];
282 for (; i < 3; i++)
283 fmtbuf[i] = NULL((void*)0);
284 fmt = fmtbuf;
285 }
286 }
287 len += format_total_stats (fp, fmt, ',', 0);
288 if (arg)
289 wordsplit_free (&ws);
290 }
291 break;
292
293 case 't':
294 {
295 struct timeval tv;
296 struct tm *tm;
297 const char *fmt = arg ? arg : "%c";
298
299 gettimeofday (&tv, NULL((void*)0));
300 tm = localtime (&tv.tv_sec);
301 len += fprintftime (fp, fmt, tm, 0, tv.tv_usec * 1000);
302 }
303 break;
304
305 case '*':
306 {
307 long w = arg ? strtol (arg, NULL((void*)0), 10) : getwidth (fp);
308 for (; w > len; len++)
309 fputc (' ', fp)fputc_unlocked (' ',fp);
310 }
311 break;
312
313 default:
314 fputc ('%', fp)fputc_unlocked ('%',fp);
315 fputc (*ip, fp)fputc_unlocked (*ip,fp);
316 len += 2;
317 break;
318 }
319 arg = NULL((void*)0);
320 }
321 else
322 {
323 fputc (*ip, fp)fputc_unlocked (*ip,fp);
324 if (*ip == '\r')
325 {
326 len = 0;
327 tty_cleanup = 1;
328 }
329 else
330 len++;
331 }
332 }
333 fflush (fp)fflush_unlocked (fp);
334 return len;
335}
336
337static FILE *tty = NULL((void*)0);
338
339static void
340run_checkpoint_actions (bool_Bool do_write)
341{
342 struct checkpoint_action *p;
343
344 for (p = checkpoint_action; p; p = p->next)
5
Loop condition is true. Entering loop body
345 {
346 switch (p->opcode)
6
Control jumps to 'case cop_ttyout:' at line 372
347 {
348 case cop_dot:
349 fputc ('.', stdlis)fputc_unlocked ('.',stdlis);
350 fflush (stdlis)fflush_unlocked (stdlis);
351 break;
352
353 case cop_bell:
354 if (!tty)
355 tty = fopen ("/dev/tty", "w");
356 if (tty)
357 {
358 fputc ('\a', tty)fputc_unlocked ('\a',tty);
359 fflush (tty)fflush_unlocked (tty);
360 }
361 break;
362
363 case cop_echo:
364 {
365 int n = fprintf (stderr, "%s: ", program_name)__fprintf_chk (stderr, 2 - 1, "%s: ", program_name);
366 format_checkpoint_string (stderrstderr, n, p->v.command, do_write,
367 checkpoint);
368 fputc ('\n', stderr)fputc_unlocked ('\n',stderr);
369 }
370 break;
371
372 case cop_ttyout:
373 if (!tty)
7
Assuming 'tty' is non-null
8
Taking false branch
374 tty = fopen ("/dev/tty", "w");
375 if (tty)
9
Taking true branch
376 format_checkpoint_string (tty, 0, p->v.command, do_write,
10
Calling 'format_checkpoint_string'
377 checkpoint);
378 break;
379
380 case cop_sleep:
381 sleep (p->v.time);
382 break;
383
384 case cop_exec:
385 sys_exec_checkpoint_script (p->v.command,
386 archive_name_cursor[0],
387 checkpoint);
388 break;
389
390 case cop_totals:
391 compute_duration ();
392 print_total_stats ();
393 }
394 }
395}
396
397void
398checkpoint_flush_actions (void)
399{
400 struct checkpoint_action *p;
401
402 for (p = checkpoint_action; p; p = p->next)
403 {
404 switch (p->opcode)
405 {
406 case cop_ttyout:
407 if (tty && tty_cleanup)
408 {
409 long w = getwidth (tty);
410 while (w--)
411 fputc (' ', tty)fputc_unlocked (' ',tty);
412 fputc ('\r', tty)fputc_unlocked ('\r',tty);
413 fflush (tty)fflush_unlocked (tty);
414 }
415 break;
416 default:
417 /* nothing */;
418 }
419 }
420}
421
422void
423checkpoint_run (bool_Bool do_write)
424{
425 if (checkpoint_option && !(++checkpoint % checkpoint_option))
1
Assuming 'checkpoint_option' is not equal to 0
2
Assuming the condition is true
3
Taking true branch
426 run_checkpoint_actions (do_write);
4
Calling 'run_checkpoint_actions'
427}
428
429void
430checkpoint_finish (void)
431{
432 if (checkpoint_option)
433 {
434 checkpoint_flush_actions ();
435 if (tty)
436 fclose (tty);
437 }
438}