Bug Summary

File:src/lib/libedit/el.c
Warning:line 426, column 4
Value stored to 'rv' is never read

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 el.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/libedit/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -I /usr/src/lib/libedit -I . -I /usr/src/lib/libedit -D PIC -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libedit/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/libedit/el.c
1/* $OpenBSD: el.c,v 1.37 2017/04/12 18:24:37 tb Exp $ */
2/* $NetBSD: el.c,v 1.61 2011/01/27 23:11:40 christos Exp $ */
3
4/*-
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Christos Zoulas of Cornell University.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "config.h"
37
38/*
39 * el.c: EditLine interface functions
40 */
41#include <sys/types.h>
42#include <ctype.h>
43#include <langinfo.h>
44#include <limits.h>
45#include <locale.h>
46#include <stdarg.h>
47#include <stdlib.h>
48#include <string.h>
49
50#include "el.h"
51#include "parse.h"
52#include "read.h"
53
54/* el_init():
55 * Initialize editline and set default parameters.
56 */
57EditLine *
58el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
59{
60 EditLine *el = (EditLine *) calloc(1, sizeof(EditLine));
61
62 if (el == NULL((void *)0))
63 return NULL((void *)0);
64
65 el->el_infile = fin;
66 el->el_outfile = fout;
67 el->el_errfile = ferr;
68
69 el->el_infd = fileno(fin)(!__isthreaded ? ((fin)->_file) : (fileno)(fin));
70 el->el_outfd = fileno(fout)(!__isthreaded ? ((fout)->_file) : (fileno)(fout));
71 el->el_errfd = fileno(ferr)(!__isthreaded ? ((ferr)->_file) : (fileno)(ferr));
72
73 el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));
74 if (el->el_prog == NULL((void *)0)) {
75 free(el);
76 return NULL((void *)0);
77 }
78
79 /*
80 * Initialize all the modules. Order is important!!!
81 */
82 el->el_flags = 0;
83 if (setlocale(LC_CTYPE2, NULL((void *)0)) != NULL((void *)0)){
84 if (strcmp(nl_langinfo(CODESET51), "UTF-8") == 0)
85 el->el_flags |= CHARSET_IS_UTF80x10;
86 }
87
88 if (terminal_init(el) == -1) {
89 free(el->el_prog);
90 free(el);
91 return NULL((void *)0);
92 }
93 (void) keymacro_init(el);
94 (void) map_init(el);
95 if (tty_init(el) == -1)
96 el->el_flags |= NO_TTY0x02;
97 (void) ch_init(el);
98 (void) search_init(el);
99 (void) hist_init(el);
100 (void) prompt_init(el);
101 (void) sig_init(el);
102 if (read_init(el) == -1) {
103 el_end(el);
104 return NULL((void *)0);
105 }
106 return el;
107}
108
109
110/* el_end():
111 * Clean up.
112 */
113void
114el_end(EditLine *el)
115{
116
117 if (el == NULL((void *)0))
118 return;
119
120 el_reset(el);
121
122 terminal_end(el);
123 keymacro_end(el);
124 map_end(el);
125 tty_end(el);
126 ch_end(el);
127 read_end(el->el_read);
128 search_end(el);
129 hist_end(el);
130 prompt_end(el);
131 sig_end(el);
132
133 free(el->el_prog);
134 free(el->el_scratch.cbuff);
135 free(el->el_scratch.wbuff);
136 free(el->el_lgcyconv.cbuff);
137 free(el->el_lgcyconv.wbuff);
138 free(el);
139}
140
141
142/* el_reset():
143 * Reset the tty and the parser
144 */
145void
146el_reset(EditLine *el)
147{
148
149 tty_cookedmode(el);
150 ch_reset(el); /* XXX: Do we want that? */
151}
152
153
154/* el_set():
155 * set the editline parameters
156 */
157int
158el_wset(EditLine *el, int op, ...)
159{
160 va_list ap;
161 int rv = 0;
162
163 if (el == NULL((void *)0))
164 return -1;
165 va_start(ap, op)__builtin_va_start(ap, op);
166
167 switch (op) {
168 case EL_PROMPT0:
169 case EL_RPROMPT12: {
170 el_pfunc_t p = va_arg(ap, el_pfunc_t)__builtin_va_arg(ap, el_pfunc_t);
171
172 rv = prompt_set(el, p, 0, op, 1);
173 break;
174 }
175
176 case EL_RESIZE23: {
177 el_zfunc_t p = va_arg(ap, el_zfunc_t)__builtin_va_arg(ap, el_zfunc_t);
178 void *arg = va_arg(ap, void *)__builtin_va_arg(ap, void *);
179 rv = ch_resizefun(el, p, arg);
180 break;
181 }
182
183 case EL_PROMPT_ESC21:
184 case EL_RPROMPT_ESC22: {
185 el_pfunc_t p = va_arg(ap, el_pfunc_t)__builtin_va_arg(ap, el_pfunc_t);
186 int c = va_arg(ap, int)__builtin_va_arg(ap, int);
187
188 rv = prompt_set(el, p, c, op, 1);
189 break;
190 }
191
192 case EL_TERMINAL1:
193 rv = terminal_set(el, va_arg(ap, char *)__builtin_va_arg(ap, char *));
194 break;
195
196 case EL_EDITOR2:
197 rv = map_set_editor(el, va_arg(ap, wchar_t *)__builtin_va_arg(ap, wchar_t *));
198 break;
199
200 case EL_SIGNAL3:
201 if (va_arg(ap, int)__builtin_va_arg(ap, int))
202 el->el_flags |= HANDLE_SIGNALS0x01;
203 else
204 el->el_flags &= ~HANDLE_SIGNALS0x01;
205 break;
206
207 case EL_BIND4:
208 case EL_TELLTC5:
209 case EL_SETTC6:
210 case EL_ECHOTC7:
211 case EL_SETTY8:
212 {
213 const wchar_t *argv[20];
214 int i;
215
216 for (i = 1; i < 20; i++)
217 if ((argv[i] = va_arg(ap, wchar_t *)__builtin_va_arg(ap, wchar_t *)) == NULL((void *)0))
218 break;
219
220 switch (op) {
221 case EL_BIND4:
222 argv[0] = L"bind";
223 rv = map_bind(el, i, argv);
224 break;
225
226 case EL_TELLTC5:
227 argv[0] = L"telltc";
228 rv = terminal_telltc(el, i, argv);
229 break;
230
231 case EL_SETTC6:
232 argv[0] = L"settc";
233 rv = terminal_settc(el, i, argv);
234 break;
235
236 case EL_ECHOTC7:
237 argv[0] = L"echotc";
238 rv = terminal_echotc(el, i, argv);
239 break;
240
241 case EL_SETTY8:
242 argv[0] = L"setty";
243 rv = tty_stty(el, i, argv);
244 break;
245
246 default:
247 rv = -1;
248 EL_ABORT((el->el_errfile, "Bad op %d\n", op))abort();
249 break;
250 }
251 break;
252 }
253
254 case EL_ADDFN9:
255 {
256 wchar_t *name = va_arg(ap, wchar_t *)__builtin_va_arg(ap, wchar_t *);
257 wchar_t *help = va_arg(ap, wchar_t *)__builtin_va_arg(ap, wchar_t *);
258 el_func_t func = va_arg(ap, el_func_t)__builtin_va_arg(ap, el_func_t);
259
260 rv = map_addfunc(el, name, help, func);
261 break;
262 }
263
264 case EL_HIST10:
265 {
266 hist_fun_t func = va_arg(ap, hist_fun_t)__builtin_va_arg(ap, hist_fun_t);
267 void *ptr = va_arg(ap, void *)__builtin_va_arg(ap, void *);
268
269 rv = hist_set(el, func, ptr);
270 if (!(el->el_flags & CHARSET_IS_UTF80x10))
271 el->el_flags &= ~NARROW_HISTORY0x40;
272 break;
273 }
274
275 case EL_EDITMODE11:
276 if (va_arg(ap, int)__builtin_va_arg(ap, int))
277 el->el_flags &= ~EDIT_DISABLED0x04;
278 else
279 el->el_flags |= EDIT_DISABLED0x04;
280 rv = 0;
281 break;
282
283 case EL_GETCFN13:
284 {
285 el_rfunc_t rc = va_arg(ap, el_rfunc_t)__builtin_va_arg(ap, el_rfunc_t);
286 rv = el_read_setfn(el->el_read, rc);
287 break;
288 }
289
290 case EL_CLIENTDATA14:
291 el->el_data = va_arg(ap, void *)__builtin_va_arg(ap, void *);
292 break;
293
294 case EL_UNBUFFERED15:
295 rv = va_arg(ap, int)__builtin_va_arg(ap, int);
296 if (rv && !(el->el_flags & UNBUFFERED0x08)) {
297 el->el_flags |= UNBUFFERED0x08;
298 read_prepare(el);
299 } else if (!rv && (el->el_flags & UNBUFFERED0x08)) {
300 el->el_flags &= ~UNBUFFERED0x08;
301 read_finish(el);
302 }
303 rv = 0;
304 break;
305
306 case EL_PREP_TERM16:
307 rv = va_arg(ap, int)__builtin_va_arg(ap, int);
308 if (rv)
309 (void) tty_rawmode(el);
310 else
311 (void) tty_cookedmode(el);
312 rv = 0;
313 break;
314
315 case EL_SETFP19:
316 {
317 FILE *fp;
318 int what;
319
320 what = va_arg(ap, int)__builtin_va_arg(ap, int);
321 fp = va_arg(ap, FILE *)__builtin_va_arg(ap, FILE *);
322
323 rv = 0;
324 switch (what) {
325 case 0:
326 el->el_infile = fp;
327 el->el_infd = fileno(fp)(!__isthreaded ? ((fp)->_file) : (fileno)(fp));
328 break;
329 case 1:
330 el->el_outfile = fp;
331 el->el_outfd = fileno(fp)(!__isthreaded ? ((fp)->_file) : (fileno)(fp));
332 break;
333 case 2:
334 el->el_errfile = fp;
335 el->el_errfd = fileno(fp)(!__isthreaded ? ((fp)->_file) : (fileno)(fp));
336 break;
337 default:
338 rv = -1;
339 break;
340 }
341 break;
342 }
343
344 case EL_REFRESH20:
345 re_clear_display(el);
346 re_refresh(el);
347 terminal__flush(el);
348 break;
349
350 default:
351 rv = -1;
352 break;
353 }
354
355 va_end(ap)__builtin_va_end(ap);
356 return rv;
357}
358
359
360/* el_get():
361 * retrieve the editline parameters
362 */
363int
364el_wget(EditLine *el, int op, ...)
365{
366 va_list ap;
367 int rv;
368
369 if (el == NULL((void *)0))
370 return -1;
371
372 va_start(ap, op)__builtin_va_start(ap, op);
373
374 switch (op) {
375 case EL_PROMPT0:
376 case EL_RPROMPT12: {
377 el_pfunc_t *p = va_arg(ap, el_pfunc_t *)__builtin_va_arg(ap, el_pfunc_t *);
378 rv = prompt_get(el, p, 0, op);
379 break;
380 }
381 case EL_PROMPT_ESC21:
382 case EL_RPROMPT_ESC22: {
383 el_pfunc_t *p = va_arg(ap, el_pfunc_t *)__builtin_va_arg(ap, el_pfunc_t *);
384 wchar_t *c = va_arg(ap, wchar_t *)__builtin_va_arg(ap, wchar_t *);
385
386 rv = prompt_get(el, p, c, op);
387 break;
388 }
389
390 case EL_EDITOR2:
391 rv = map_get_editor(el, va_arg(ap, const wchar_t **)__builtin_va_arg(ap, const wchar_t **));
392 break;
393
394 case EL_SIGNAL3:
395 *va_arg(ap, int *)__builtin_va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS0x01);
396 rv = 0;
397 break;
398
399 case EL_EDITMODE11:
400 *va_arg(ap, int *)__builtin_va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED0x04);
401 rv = 0;
402 break;
403
404 case EL_TERMINAL1:
405 terminal_get(el, va_arg(ap, const char **)__builtin_va_arg(ap, const char **));
406 rv = 0;
407 break;
408
409 case EL_GETTC17:
410 {
411 static char name[] = "gettc";
412 char *argv[20];
413 int i;
414
415 for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
416 if ((argv[i] = va_arg(ap, char *)__builtin_va_arg(ap, char *)) == NULL((void *)0))
417 break;
418
419 switch (op) {
420 case EL_GETTC17:
421 argv[0] = name;
422 rv = terminal_gettc(el, i, argv);
423 break;
424
425 default:
426 rv = -1;
Value stored to 'rv' is never read
427 EL_ABORT((el->el_errfile, "Bad op %d\n", op))abort();
428 break;
429 }
430 break;
431 }
432
433 case EL_GETCFN13:
434 *va_arg(ap, el_rfunc_t *)__builtin_va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);
435 rv = 0;
436 break;
437
438 case EL_CLIENTDATA14:
439 *va_arg(ap, void **)__builtin_va_arg(ap, void **) = el->el_data;
440 rv = 0;
441 break;
442
443 case EL_UNBUFFERED15:
444 *va_arg(ap, int *)__builtin_va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED0x08));
445 rv = 0;
446 break;
447
448 case EL_GETFP18:
449 {
450 int what;
451 FILE **fpp;
452
453 what = va_arg(ap, int)__builtin_va_arg(ap, int);
454 fpp = va_arg(ap, FILE **)__builtin_va_arg(ap, FILE **);
455 rv = 0;
456 switch (what) {
457 case 0:
458 *fpp = el->el_infile;
459 break;
460 case 1:
461 *fpp = el->el_outfile;
462 break;
463 case 2:
464 *fpp = el->el_errfile;
465 break;
466 default:
467 rv = -1;
468 break;
469 }
470 break;
471 }
472 default:
473 rv = -1;
474 break;
475 }
476 va_end(ap)__builtin_va_end(ap);
477
478 return rv;
479}
480
481
482/* el_line():
483 * Return editing info
484 */
485const LineInfoW *
486el_wline(EditLine *el)
487{
488
489 return (const LineInfoW *)(void *)&el->el_line;
490}
491
492
493/* el_source():
494 * Source a file
495 */
496int
497el_source(EditLine *el, const char *fname)
498{
499 FILE *fp;
500 size_t len;
501 ssize_t slen;
502 char *ptr;
503#ifdef HAVE_ISSETUGID1
504 char path[PATH_MAX1024];
505#endif
506 const wchar_t *dptr;
507
508 fp = NULL((void *)0);
509 if (fname == NULL((void *)0)) {
510#ifdef HAVE_ISSETUGID1
511 static const char elpath[] = "/.editrc";
512
513 if (issetugid())
514 return -1;
515 if ((ptr = getenv("HOME")) == NULL((void *)0))
516 return -1;
517 if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
518 return -1;
519 if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
520 return -1;
521 fname = path;
522#else
523 /*
524 * If issetugid() is missing, always return an error, in order
525 * to keep from inadvertently opening up the user to a security
526 * hole.
527 */
528 return -1;
529#endif
530 }
531 if (fp == NULL((void *)0))
532 fp = fopen(fname, "r");
533 if (fp == NULL((void *)0))
534 return -1;
535
536 ptr = NULL((void *)0);
537 len = 0;
538 while ((slen = getline(&ptr, &len, fp)) != -1) {
539 if (*ptr == '\n')
540 continue; /* Empty line. */
541 if (slen > 0 && ptr[--slen] == '\n')
542 ptr[slen] = '\0';
543
544 dptr = ct_decode_string(ptr, &el->el_scratch);
545 if (!dptr)
546 continue;
547 /* loop until first non-space char or EOL */
548 while (*dptr != '\0' && iswspace(*dptr))
549 dptr++;
550 if (*dptr == '#')
551 continue; /* ignore, this is a comment line */
552 if (parse_line(el, dptr) == -1) {
553 free(ptr);
554 (void) fclose(fp);
555 return -1;
556 }
557 }
558 free(ptr);
559 (void) fclose(fp);
560 return 0;
561}
562
563
564/* el_resize():
565 * Called from program when terminal is resized
566 */
567void
568el_resize(EditLine *el)
569{
570 int lins, cols;
571 sigset_t oset, nset;
572
573 (void) sigemptyset(&nset);
574 (void) sigaddset(&nset, SIGWINCH28);
575 (void) sigprocmask(SIG_BLOCK1, &nset, &oset);
576
577 /* get the correct window size */
578 if (terminal_get_size(el, &lins, &cols))
579 terminal_change_size(el, lins, cols);
580
581 (void) sigprocmask(SIG_SETMASK3, &oset, NULL((void *)0));
582}
583
584
585/* el_beep():
586 * Called from the program to beep
587 */
588void
589el_beep(EditLine *el)
590{
591
592 terminal_beep(el);
593}
594
595
596/* el_editmode()
597 * Set the state of EDIT_DISABLED from the `edit' command.
598 */
599protected__attribute__((__visibility__("hidden"))) int
600/*ARGSUSED*/
601el_editmode(EditLine *el, int argc, const wchar_t **argv)
602{
603 const wchar_t *how;
604
605 if (argv == NULL((void *)0) || argc != 2 || argv[1] == NULL((void *)0))
606 return -1;
607
608 how = argv[1];
609 if (wcscmp(how, L"on") == 0) {
610 el->el_flags &= ~EDIT_DISABLED0x04;
611 tty_rawmode(el);
612 } else if (wcscmp(how, L"off") == 0) {
613 tty_cookedmode(el);
614 el->el_flags |= EDIT_DISABLED0x04;
615 }
616 else {
617 (void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",
618 how);
619 return -1;
620 }
621 return 0;
622}