Bug Summary

File:src/lib/libcurses/tinfo/alloc_ttype.c
Warning:line 353, column 11
Although the value stored to 'k' is used in the enclosing expression, the value is never actually read from 'k'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name alloc_ttype.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 -setup-static-analyzer -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libcurses/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -I /usr/src/lib/libcurses -D PIC -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libcurses/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libcurses/tinfo/alloc_ttype.c
1/* $OpenBSD: alloc_ttype.c,v 1.6 2010/01/12 23:22:06 nicm Exp $ */
2
3/****************************************************************************
4 * Copyright (c) 1999-2006,2008 Free Software Foundation, Inc. *
5 * *
6 * Permission is hereby granted, free of charge, to any person obtaining a *
7 * copy of this software and associated documentation files (the *
8 * "Software"), to deal in the Software without restriction, including *
9 * without limitation the rights to use, copy, modify, merge, publish, *
10 * distribute, distribute with modifications, sublicense, and/or sell *
11 * copies of the Software, and to permit persons to whom the Software is *
12 * furnished to do so, subject to the following conditions: *
13 * *
14 * The above copyright notice and this permission notice shall be included *
15 * in all copies or substantial portions of the Software. *
16 * *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
24 * *
25 * Except as contained in this notice, the name(s) of the above copyright *
26 * holders shall not be used in advertising or otherwise to promote the *
27 * sale, use or other dealings in this Software without prior written *
28 * authorization. *
29 ****************************************************************************/
30
31/****************************************************************************
32 * Author: Thomas E. Dickey <dickey@clark.net> 1999-on *
33 ****************************************************************************/
34
35/*
36 * align_ttype.c -- functions for TERMTYPE
37 *
38 * _nc_align_termtype()
39 * _nc_copy_termtype()
40 *
41 */
42
43#include <curses.priv.h>
44
45#include <tic.h>
46#include <term_entry.h>
47
48MODULE_ID("$Id: alloc_ttype.c,v 1.6 2010/01/12 23:22:06 nicm Exp $")
49
50#if NCURSES_XNAMES1
51/*
52 * Merge the a/b lists into dst. Both a/b are sorted (see _nc_extend_names()),
53 * so we do not have to worry about order dependencies.
54 */
55static int
56merge_names(char **dst, char **a, int na, char **b, int nb)
57{
58 int n = 0;
59 while (na > 0 && nb > 0) {
60 int cmp = strcmp(*a, *b);
61 if (cmp < 0) {
62 dst[n++] = *a++;
63 na--;
64 } else if (cmp > 0) {
65 dst[n++] = *b++;
66 nb--;
67 } else if (cmp == 0) {
68 dst[n++] = *a;
69 a++, b++;
70 na--, nb--;
71 }
72 }
73 while (na-- > 0) {
74 dst[n++] = *a++;
75 }
76 while (nb-- > 0) {
77 dst[n++] = *b++;
78 }
79 DEBUG(4, ("merge_names -> %d", n));
80 return n;
81}
82
83static bool_Bool
84find_name(char **table, int length, char *name)
85{
86 while (length-- > 0) {
87 if (!strcmp(*table++, name)) {
88 DEBUG(4, ("found name '%s'", name));
89 return TRUE1;
90 }
91 }
92 DEBUG(4, ("did not find name '%s'", name));
93 return FALSE0;
94}
95
96static void
97realign_data(TERMTYPE *to, char **ext_Names,
98 int ext_Booleans,
99 int ext_Numbers,
100 int ext_Strings)
101{
102 int n, m, base;
103 int limit = (to->ext_Booleans + to->ext_Numbers + to->ext_Strings);
104
105 if (to->ext_Booleans != ext_Booleans) {
106 to->num_Booleans += (ext_Booleans - to->ext_Booleans);
107 to->Booleans = typeRealloc(NCURSES_SBOOL, to->num_Booleans, to->Booleans)(signed char *)_nc_doalloc(to->Booleans, (to->num_Booleans
)*sizeof(signed char))
;
108 for (n = to->ext_Booleans - 1,
109 m = ext_Booleans - 1,
110 base = to->num_Booleans - (m + 1); m >= 0; m--) {
111 if (find_name(to->ext_Names, limit, ext_Names[m])) {
112 to->Booleans[base + m] = to->Booleans[base + n--];
113 } else {
114 to->Booleans[base + m] = FALSE0;
115 }
116 }
117 to->ext_Booleans = ext_Booleans;
118 }
119 if (to->ext_Numbers != ext_Numbers) {
120 to->num_Numbers += (ext_Numbers - to->ext_Numbers);
121 to->Numbers = typeRealloc(short, to->num_Numbers, to->Numbers)(short *)_nc_doalloc(to->Numbers, (to->num_Numbers)*sizeof
(short))
;
122 for (n = to->ext_Numbers - 1,
123 m = ext_Numbers - 1,
124 base = to->num_Numbers - (m + 1); m >= 0; m--) {
125 if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans])) {
126 to->Numbers[base + m] = to->Numbers[base + n--];
127 } else {
128 to->Numbers[base + m] = ABSENT_NUMERIC(-1);
129 }
130 }
131 to->ext_Numbers = ext_Numbers;
132 }
133 if (to->ext_Strings != ext_Strings) {
134 to->num_Strings += (ext_Strings - to->ext_Strings);
135 to->Strings = typeRealloc(char *, to->num_Strings, to->Strings)(char * *)_nc_doalloc(to->Strings, (to->num_Strings)*sizeof
(char *))
;
136 for (n = to->ext_Strings - 1,
137 m = ext_Strings - 1,
138 base = to->num_Strings - (m + 1); m >= 0; m--) {
139 if (find_name(to->ext_Names, limit, ext_Names[m + ext_Booleans + ext_Numbers])) {
140 to->Strings[base + m] = to->Strings[base + n--];
141 } else {
142 to->Strings[base + m] = ABSENT_STRING(char *)0;
143 }
144 }
145 to->ext_Strings = ext_Strings;
146 }
147}
148
149/*
150 * Returns the first index in ext_Names[] for the given token-type
151 */
152static int
153_nc_first_ext_name(TERMTYPE *tp, int token_type)
154{
155 int first;
156
157 switch (token_type) {
158 case BOOLEAN0:
159 first = 0;
160 break;
161 case NUMBER1:
162 first = tp->ext_Booleans;
163 break;
164 case STRING2:
165 first = tp->ext_Booleans + tp->ext_Numbers;
166 break;
167 default:
168 first = 0;
169 break;
170 }
171 return first;
172}
173
174/*
175 * Returns the last index in ext_Names[] for the given token-type
176 */
177static int
178_nc_last_ext_name(TERMTYPE *tp, int token_type)
179{
180 int last;
181
182 switch (token_type) {
183 case BOOLEAN0:
184 last = tp->ext_Booleans;
185 break;
186 case NUMBER1:
187 last = tp->ext_Booleans + tp->ext_Numbers;
188 break;
189 default:
190 case STRING2:
191 last = NUM_EXT_NAMES(tp)((tp)->ext_Booleans + (tp)->ext_Numbers + (tp)->ext_Strings
)
;
192 break;
193 }
194 return last;
195}
196
197/*
198 * Lookup an entry from extended-names, returning -1 if not found
199 */
200static int
201_nc_find_ext_name(TERMTYPE *tp, char *name, int token_type)
202{
203 unsigned j;
204 unsigned first = _nc_first_ext_name(tp, token_type);
205 unsigned last = _nc_last_ext_name(tp, token_type);
206
207 for (j = first; j < last; j++) {
208 if (!strcmp(name, tp->ext_Names[j])) {
209 return j;
210 }
211 }
212 return -1;
213}
214
215/*
216 * Translate an index into ext_Names[] into the corresponding index into data
217 * (e.g., Booleans[]).
218 */
219static int
220_nc_ext_data_index(TERMTYPE *tp, int n, int token_type)
221{
222 switch (token_type) {
223 case BOOLEAN0:
224 n += (tp->num_Booleans - tp->ext_Booleans);
225 break;
226 case NUMBER1:
227 n += (tp->num_Numbers - tp->ext_Numbers)
228 - (tp->ext_Booleans);
229 break;
230 default:
231 case STRING2:
232 n += (tp->num_Strings - tp->ext_Strings)
233 - (tp->ext_Booleans + tp->ext_Numbers);
234 }
235 return n;
236}
237
238/*
239 * Adjust tables to remove (not free) an extended name and its corresponding
240 * data.
241 */
242static bool_Bool
243_nc_del_ext_name(TERMTYPE *tp, char *name, int token_type)
244{
245 int j;
246 int first, last;
247
248 if ((first = _nc_find_ext_name(tp, name, token_type)) >= 0) {
249 last = NUM_EXT_NAMES(tp)((tp)->ext_Booleans + (tp)->ext_Numbers + (tp)->ext_Strings
)
- 1;
250 for (j = first; j < last; j++) {
251 tp->ext_Names[j] = tp->ext_Names[j + 1];
252 }
253 first = _nc_ext_data_index(tp, first, token_type);
254 switch (token_type) {
255 case BOOLEAN0:
256 last = tp->num_Booleans - 1;
257 for (j = first; j < last; j++)
258 tp->Booleans[j] = tp->Booleans[j + 1];
259 tp->ext_Booleans -= 1;
260 tp->num_Booleans -= 1;
261 break;
262 case NUMBER1:
263 last = tp->num_Numbers - 1;
264 for (j = first; j < last; j++)
265 tp->Numbers[j] = tp->Numbers[j + 1];
266 tp->ext_Numbers -= 1;
267 tp->num_Numbers -= 1;
268 break;
269 case STRING2:
270 last = tp->num_Strings - 1;
271 for (j = first; j < last; j++)
272 tp->Strings[j] = tp->Strings[j + 1];
273 tp->ext_Strings -= 1;
274 tp->num_Strings -= 1;
275 break;
276 }
277 return TRUE1;
278 }
279 return FALSE0;
280}
281
282/*
283 * Adjust tables to insert an extended name, making room for new data. The
284 * index into the corresponding data array is returned.
285 */
286static int
287_nc_ins_ext_name(TERMTYPE *tp, char *name, int token_type)
288{
289 unsigned first = _nc_first_ext_name(tp, token_type);
290 unsigned last = _nc_last_ext_name(tp, token_type);
291 unsigned total = NUM_EXT_NAMES(tp)((tp)->ext_Booleans + (tp)->ext_Numbers + (tp)->ext_Strings
)
+ 1;
292 unsigned j, k;
293
294 for (j = first; j < last; j++) {
295 int cmp = strcmp(name, tp->ext_Names[j]);
296 if (cmp == 0)
297 /* already present */
298 return _nc_ext_data_index(tp, (int) j, token_type);
299 if (cmp < 0) {
300 break;
301 }
302 }
303
304 tp->ext_Names = typeRealloc(char *, total, tp->ext_Names)(char * *)_nc_doalloc(tp->ext_Names, (total)*sizeof(char *
))
;
305 for (k = total - 1; k > j; k--)
306 tp->ext_Names[k] = tp->ext_Names[k - 1];
307 tp->ext_Names[j] = name;
308 j = _nc_ext_data_index(tp, (int) j, token_type);
309
310 switch (token_type) {
311 case BOOLEAN0:
312 tp->ext_Booleans += 1;
313 tp->num_Booleans += 1;
314 tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans)(signed char *)_nc_doalloc(tp->Booleans, (tp->num_Booleans
)*sizeof(signed char))
;
315 for (k = tp->num_Booleans - 1; k > j; k--)
316 tp->Booleans[k] = tp->Booleans[k - 1];
317 break;
318 case NUMBER1:
319 tp->ext_Numbers += 1;
320 tp->num_Numbers += 1;
321 tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers)(short *)_nc_doalloc(tp->Numbers, (tp->num_Numbers)*sizeof
(short))
;
322 for (k = tp->num_Numbers - 1; k > j; k--)
323 tp->Numbers[k] = tp->Numbers[k - 1];
324 break;
325 case STRING2:
326 tp->ext_Strings += 1;
327 tp->num_Strings += 1;
328 tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings)(char * *)_nc_doalloc(tp->Strings, (tp->num_Strings)*sizeof
(char *))
;
329 for (k = tp->num_Strings - 1; k > j; k--)
330 tp->Strings[k] = tp->Strings[k - 1];
331 break;
332 }
333 return j;
334}
335
336/*
337 * Look for strings that are marked cancelled, which happen to be the same name
338 * as a boolean or number. We'll get this as a special case when we get a
339 * cancellation of a name that is inherited from another entry.
340 */
341static void
342adjust_cancels(TERMTYPE *to, TERMTYPE *from)
343{
344 int first = to->ext_Booleans + to->ext_Numbers;
345 int last = first + to->ext_Strings;
346 int j, k;
347
348 for (j = first; j < last;) {
349 char *name = to->ext_Names[j];
350 unsigned j_str = to->num_Strings - first - to->ext_Strings;
351
352 if (to->Strings[j + j_str] == CANCELLED_STRING(char *)(-1)) {
353 if ((k = _nc_find_ext_name(from, to->ext_Names[j], BOOLEAN0)) >= 0) {
Although the value stored to 'k' is used in the enclosing expression, the value is never actually read from 'k'
354 if (_nc_del_ext_name(to, name, STRING2)
355 || _nc_del_ext_name(to, name, NUMBER1)) {
356 k = _nc_ins_ext_name(to, name, BOOLEAN0);
357 to->Booleans[k] = FALSE0;
358 } else {
359 j++;
360 }
361 } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
362 NUMBER1)) >= 0) {
363 if (_nc_del_ext_name(to, name, STRING2)
364 || _nc_del_ext_name(to, name, BOOLEAN0)) {
365 k = _nc_ins_ext_name(to, name, NUMBER1);
366 to->Numbers[k] = CANCELLED_NUMERIC(-2);
367 } else {
368 j++;
369 }
370 } else if ((k = _nc_find_ext_name(from, to->ext_Names[j],
371 STRING2)) >= 0) {
372 if (_nc_del_ext_name(to, name, NUMBER1)
373 || _nc_del_ext_name(to, name, BOOLEAN0)) {
374 k = _nc_ins_ext_name(to, name, STRING2);
375 to->Strings[k] = CANCELLED_STRING(char *)(-1);
376 } else {
377 j++;
378 }
379 } else {
380 j++;
381 }
382 } else {
383 j++;
384 }
385 }
386}
387
388NCURSES_EXPORT(void)void
389_nc_align_termtype(TERMTYPE *to, TERMTYPE *from)
390{
391 int na = NUM_EXT_NAMES(to)((to)->ext_Booleans + (to)->ext_Numbers + (to)->ext_Strings
)
;
392 int nb = NUM_EXT_NAMES(from)((from)->ext_Booleans + (from)->ext_Numbers + (from)->
ext_Strings)
;
393 int n;
394 bool_Bool same;
395 char **ext_Names;
396 int ext_Booleans, ext_Numbers, ext_Strings;
397 bool_Bool used_ext_Names = FALSE0;
398
399 DEBUG(2, ("align_termtype to(%d:%s), from(%d:%s)", na, to->term_names,
400 nb, from->term_names));
401
402 if (na != 0 || nb != 0) {
403 if ((na == nb) /* check if the arrays are equivalent */
404 &&(to->ext_Booleans == from->ext_Booleans)
405 && (to->ext_Numbers == from->ext_Numbers)
406 && (to->ext_Strings == from->ext_Strings)) {
407 for (n = 0, same = TRUE1; n < na; n++) {
408 if (strcmp(to->ext_Names[n], from->ext_Names[n])) {
409 same = FALSE0;
410 break;
411 }
412 }
413 if (same)
414 return;
415 }
416 /*
417 * This is where we pay for having a simple extension representation.
418 * Allocate a new ext_Names array and merge the two ext_Names arrays
419 * into it, updating to's counts for booleans, etc. Fortunately we do
420 * this only for the terminfo compiler (tic) and comparer (infocmp).
421 */
422 ext_Names = typeMalloc(char *, na + nb)(char * *)malloc((na + nb)*sizeof(char *));
423
424 if (to->ext_Strings && (from->ext_Booleans + from->ext_Numbers))
425 adjust_cancels(to, from);
426
427 if (from->ext_Strings && (to->ext_Booleans + to->ext_Numbers))
428 adjust_cancels(from, to);
429
430 ext_Booleans = merge_names(ext_Names,
431 to->ext_Names,
432 to->ext_Booleans,
433 from->ext_Names,
434 from->ext_Booleans);
435 ext_Numbers = merge_names(ext_Names + ext_Booleans,
436 to->ext_Names
437 + to->ext_Booleans,
438 to->ext_Numbers,
439 from->ext_Names
440 + from->ext_Booleans,
441 from->ext_Numbers);
442 ext_Strings = merge_names(ext_Names + ext_Numbers + ext_Booleans,
443 to->ext_Names
444 + to->ext_Booleans
445 + to->ext_Numbers,
446 to->ext_Strings,
447 from->ext_Names
448 + from->ext_Booleans
449 + from->ext_Numbers,
450 from->ext_Strings);
451 /*
452 * Now we must reallocate the Booleans, etc., to allow the data to be
453 * overlaid.
454 */
455 if (na != (ext_Booleans + ext_Numbers + ext_Strings)) {
456 realign_data(to, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);
457 FreeIfNeeded(to->ext_Names)if ((to->ext_Names) != 0) free(to->ext_Names);
458 to->ext_Names = ext_Names;
459 DEBUG(2, ("realigned %d extended names for '%s' (to)",
460 NUM_EXT_NAMES(to), to->term_names));
461 used_ext_Names = TRUE1;
462 }
463 if (nb != (ext_Booleans + ext_Numbers + ext_Strings)) {
464 nb = (ext_Booleans + ext_Numbers + ext_Strings);
465 realign_data(from, ext_Names, ext_Booleans, ext_Numbers, ext_Strings);
466 from->ext_Names = typeRealloc(char *, nb, from->ext_Names)(char * *)_nc_doalloc(from->ext_Names, (nb)*sizeof(char *)
)
;
467 memcpy(from->ext_Names, ext_Names, sizeof(char *) * nb);
468 DEBUG(2, ("realigned %d extended names for '%s' (from)",
469 NUM_EXT_NAMES(from), from->term_names));
470 }
471 if (!used_ext_Names)
472 free(ext_Names);
473 }
474}
475#endif
476
477NCURSES_EXPORT(void)void
478_nc_copy_termtype(TERMTYPE *dst, TERMTYPE *src)
479{
480 unsigned i;
481
482 *dst = *src; /* ...to copy the sizes and string-tables */
483 dst->Booleans = typeMalloc(NCURSES_SBOOL, NUM_BOOLEANS(dst))(signed char *)malloc(((dst)->num_Booleans)*sizeof(signed char
))
;
484 dst->Numbers = typeMalloc(short, NUM_NUMBERS(dst))(short *)malloc(((dst)->num_Numbers)*sizeof(short));
485 dst->Strings = typeMalloc(char *, NUM_STRINGS(dst))(char * *)malloc(((dst)->num_Strings)*sizeof(char *));
486
487 /* FIXME: use memcpy for these and similar loops */
488 for_each_boolean(i, dst)for(i = 0; i < (dst)->num_Booleans; i++)
489 dst->Booleans[i] = src->Booleans[i];
490 for_each_number(i, dst)for(i = 0; i < (dst)->num_Numbers; i++)
491 dst->Numbers[i] = src->Numbers[i];
492 for_each_string(i, dst)for(i = 0; i < (dst)->num_Strings; i++)
493 dst->Strings[i] = src->Strings[i];
494
495 /* FIXME: we probably should also copy str_table and ext_str_table,
496 * but tic and infocmp are not written to exploit that (yet).
497 */
498
499#if NCURSES_XNAMES1
500 if ((i = NUM_EXT_NAMES(src)((src)->ext_Booleans + (src)->ext_Numbers + (src)->ext_Strings
)
) != 0) {
501 dst->ext_Names = typeMalloc(char *, i)(char * *)malloc((i)*sizeof(char *));
502 memcpy(dst->ext_Names, src->ext_Names, i * sizeof(char *));
503 } else {
504 dst->ext_Names = 0;
505 }
506#endif
507
508}