clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name line.c -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 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/usr.bin/mg/obj -resource-dir /usr/local/llvm16/lib/clang/16 -D REGEX -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/mg/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.bin/mg/line.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | #include <sys/queue.h> |
21 | #include <ctype.h> |
22 | #include <limits.h> |
23 | #include <signal.h> |
24 | #include <stdio.h> |
25 | #include <stdlib.h> |
26 | #include <string.h> |
27 | |
28 | #include "def.h" |
29 | |
30 | int casereplace = TRUE; |
31 | |
32 | |
33 | |
34 | |
35 | int |
36 | setcasereplace(int f, int n) |
37 | { |
38 | if (f & FFARG) |
39 | casereplace = n > 0; |
40 | else |
41 | casereplace = !casereplace; |
42 | ewprintf("Case-replace is %sabled", casereplace ? "en" : "dis"); |
43 | return (TRUE); |
44 | } |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | struct line * |
51 | lalloc(int used) |
52 | { |
53 | struct line *lp; |
54 | |
55 | if ((lp = malloc(sizeof(*lp))) == NULL) |
| 39 | | Assuming the condition is false | |
|
| |
56 | return (NULL); |
57 | lp->l_text = NULL; |
| 41 | | Null pointer value stored to field 'l_text' | |
|
58 | lp->l_size = 0; |
59 | lp->l_used = used; |
60 | if (lrealloc(lp, used) == FALSE) { |
| |
| 46 | | Returning from 'lrealloc' | |
|
| |
61 | free(lp); |
62 | return (NULL); |
63 | } |
64 | return (lp); |
65 | } |
66 | |
67 | int |
68 | lrealloc(struct line *lp, int newsize) |
69 | { |
70 | char *tmp; |
71 | |
72 | if (lp->l_size < newsize) { |
| 43 | | Assuming 'newsize' is <= field 'l_size' | |
|
| |
73 | if ((tmp = realloc(lp->l_text, newsize)) == NULL) |
74 | return (FALSE); |
75 | lp->l_text = tmp; |
76 | lp->l_size = newsize; |
77 | } |
78 | return (TRUE); |
| 45 | | Returning without writing to '->l_text' | |
|
79 | } |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | void |
88 | lfree(struct line *lp) |
89 | { |
90 | struct buffer *bp; |
91 | struct mgwin *wp; |
92 | |
93 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
94 | if (wp->w_linep == lp) |
95 | wp->w_linep = lp->l_fp; |
96 | if (wp->w_dotp == lp) { |
97 | wp->w_dotp = lp->l_fp; |
98 | wp->w_doto = 0; |
99 | } |
100 | if (wp->w_markp == lp) { |
101 | wp->w_markp = lp->l_fp; |
102 | wp->w_marko = 0; |
103 | } |
104 | } |
105 | for (bp = bheadp; bp != NULL; bp = bp->b_bufp) { |
106 | if (bp->b_nwnd == 0) { |
107 | if (bp->b_dotp == lp) { |
108 | bp->b_dotp = lp->l_fp; |
109 | bp->b_doto = 0; |
110 | } |
111 | if (bp->b_markp == lp) { |
112 | bp->b_markp = lp->l_fp; |
113 | bp->b_marko = 0; |
114 | } |
115 | } |
116 | } |
117 | lp->l_bp->l_fp = lp->l_fp; |
118 | lp->l_fp->l_bp = lp->l_bp; |
119 | free(lp->l_text); |
120 | free(lp); |
121 | } |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | void |
131 | lchange(int flag) |
132 | { |
133 | struct mgwin *wp; |
134 | |
135 | |
136 | if ((curbp->b_flag & BFCHG) == 0) { |
137 | flag |= WFMODE; |
138 | curbp->b_flag |= BFCHG; |
139 | } |
140 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
141 | if (wp->w_bufp == curbp) { |
142 | wp->w_rflag |= flag; |
143 | if (wp != curwp) |
144 | wp->w_rflag |= WFFULL; |
145 | } |
146 | } |
147 | } |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | int |
159 | linsert(int n, int c) |
160 | { |
161 | struct line *lp1; |
162 | struct mgwin *wp; |
163 | RSIZE i; |
164 | int doto; |
165 | int s; |
166 | |
167 | if (!n) |
168 | return (TRUE); |
169 | |
170 | if ((s = checkdirty(curbp)) != TRUE) |
171 | return (s); |
172 | |
173 | if (curbp->b_flag & BFREADONLY) { |
174 | dobeep(); |
175 | ewprintf("Buffer is read only"); |
176 | return (FALSE); |
177 | } |
178 | |
179 | lchange(WFEDIT); |
180 | |
181 | |
182 | lp1 = curwp->w_dotp; |
183 | |
184 | |
185 | if (lp1 == curbp->b_headp) { |
186 | struct line *lp2, *lp3; |
187 | |
188 | |
189 | if (curwp->w_doto != 0) { |
190 | dobeep(); |
191 | ewprintf("bug: linsert"); |
192 | return (FALSE); |
193 | } |
194 | |
195 | if ((lp2 = lalloc(n)) == NULL) |
196 | return (FALSE); |
197 | |
198 | lp3 = lp1->l_bp; |
199 | |
200 | lp3->l_fp = lp2; |
201 | lp2->l_fp = lp1; |
202 | lp1->l_bp = lp2; |
203 | lp2->l_bp = lp3; |
204 | for (i = 0; i < n; ++i) |
205 | lp2->l_text[i] = c; |
206 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
207 | if (wp->w_linep == lp1) |
208 | wp->w_linep = lp2; |
209 | if (wp->w_dotp == lp1) |
210 | wp->w_dotp = lp2; |
211 | if (wp->w_markp == lp1) |
212 | wp->w_markp = lp2; |
213 | } |
214 | undo_add_insert(lp2, 0, n); |
215 | curwp->w_doto = n; |
216 | return (TRUE); |
217 | } |
218 | |
219 | doto = curwp->w_doto; |
220 | |
221 | if ((lp1->l_used + n) > lp1->l_size) { |
222 | if (lrealloc(lp1, lp1->l_used + n) == FALSE) |
223 | return (FALSE); |
224 | } |
225 | lp1->l_used += n; |
226 | if (lp1->l_used != n) |
227 | memmove(&lp1->l_text[doto + n], &lp1->l_text[doto], |
228 | lp1->l_used - n - doto); |
229 | |
230 | |
231 | for (i = 0; i < n; ++i) |
232 | lp1->l_text[doto + i] = c; |
233 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
234 | if (wp->w_dotp == lp1) { |
235 | if (wp == curwp || wp->w_doto > doto) |
236 | wp->w_doto += n; |
237 | } |
238 | if (wp->w_markp == lp1) { |
239 | if (wp->w_marko > doto) |
240 | wp->w_marko += n; |
241 | } |
242 | } |
243 | undo_add_insert(curwp->w_dotp, doto, n); |
244 | return (TRUE); |
245 | } |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | int |
255 | lnewline_at(struct line *lp1, int doto) |
256 | { |
257 | struct line *lp2; |
258 | struct mgwin *wp; |
259 | int nlen, tcurwpdotline; |
260 | |
261 | lchange(WFFULL); |
262 | |
263 | curwp->w_bufp->b_lines++; |
264 | |
265 | if (curwp->w_markline > curwp->w_dotline || |
266 | (curwp->w_dotline == curwp->w_markline && |
267 | curwp->w_marko >= doto)) |
268 | curwp->w_markline++; |
269 | |
270 | tcurwpdotline = curwp->w_dotline; |
271 | |
272 | |
273 | if (doto == 0) { |
274 | |
275 | if ((lp2 = lalloc(0)) == NULL) |
276 | return (FALSE); |
277 | lp2->l_bp = lp1->l_bp; |
278 | lp1->l_bp->l_fp = lp2; |
279 | lp2->l_fp = lp1; |
280 | lp1->l_bp = lp2; |
281 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
282 | if (wp->w_linep == lp1) |
283 | wp->w_linep = lp2; |
284 | if (wp->w_dotline >= tcurwpdotline && |
285 | wp->w_bufp == curwp->w_bufp) |
286 | wp->w_dotline++; |
287 | } |
288 | undo_add_boundary(FFRAND, 1); |
289 | undo_add_insert(lp2, 0, 1); |
290 | undo_add_boundary(FFRAND, 1); |
291 | return (TRUE); |
292 | } |
293 | |
294 | |
295 | nlen = llength(lp1) - doto; |
296 | |
297 | |
298 | if ((lp2 = lalloc(nlen)) == NULL) |
299 | return (FALSE); |
300 | if (nlen != 0) |
301 | bcopy(&lp1->l_text[doto], &lp2->l_text[0], nlen); |
302 | lp1->l_used = doto; |
303 | lp2->l_bp = lp1; |
304 | lp2->l_fp = lp1->l_fp; |
305 | lp1->l_fp = lp2; |
306 | lp2->l_fp->l_bp = lp2; |
307 | |
308 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
309 | if (wp->w_dotp == lp1 && wp->w_doto >= doto) { |
310 | wp->w_dotp = lp2; |
311 | wp->w_doto -= doto; |
312 | wp->w_dotline++; |
313 | } else if (wp->w_dotline > tcurwpdotline && |
314 | wp->w_bufp == curwp->w_bufp) |
315 | wp->w_dotline++; |
316 | if (wp->w_markp == lp1 && wp->w_marko >= doto) { |
317 | wp->w_markp = lp2; |
318 | wp->w_marko -= doto; |
319 | } |
320 | } |
321 | undo_add_boundary(FFRAND, 1); |
322 | undo_add_insert(lp1, llength(lp1), 1); |
323 | undo_add_boundary(FFRAND, 1); |
324 | return (TRUE); |
325 | } |
326 | |
327 | |
328 | |
329 | |
330 | |
331 | int |
332 | lnewline(void) |
333 | { |
334 | int s; |
335 | |
336 | if ((s = checkdirty(curbp)) != TRUE) |
337 | return (s); |
338 | if (curbp->b_flag & BFREADONLY) { |
339 | dobeep(); |
340 | ewprintf("Buffer is read only"); |
341 | return (FALSE); |
342 | } |
343 | return (lnewline_at(curwp->w_dotp, curwp->w_doto)); |
344 | } |
345 | |
346 | |
347 | |
348 | |
349 | |
350 | |
351 | |
352 | |
353 | |
354 | int |
355 | ldelete(RSIZE n, int kflag) |
356 | { |
357 | struct line *dotp; |
358 | RSIZE chunk; |
359 | struct mgwin *wp; |
360 | int doto; |
361 | char *cp1, *cp2; |
362 | size_t len; |
363 | char *sv = NULL; |
364 | int end; |
365 | int s; |
366 | int rval = FALSE; |
367 | |
368 | if ((s = checkdirty(curbp)) != TRUE) |
| 11 | | Assuming the condition is false | |
|
| |
369 | return (s); |
370 | if (curbp->b_flag & BFREADONLY) { |
| 13 | | Assuming the condition is false | |
|
| |
371 | dobeep(); |
372 | ewprintf("Buffer is read only"); |
373 | goto out; |
374 | } |
375 | len = n; |
376 | if ((sv = calloc(1, len + 1)) == NULL) |
| 15 | | Assuming the condition is false | |
|
| |
377 | goto out; |
378 | end = 0; |
379 | |
380 | undo_add_delete(curwp->w_dotp, curwp->w_doto, n, (kflag & KREG)); |
381 | |
382 | while (n != 0) { |
| 17 | | Assuming 'n' is not equal to 0 | |
|
| 18 | | Loop condition is true. Entering loop body | |
|
383 | dotp = curwp->w_dotp; |
384 | doto = curwp->w_doto; |
385 | |
386 | if (dotp == curbp->b_headp) |
| 19 | | Assuming 'dotp' is not equal to field 'b_headp' | |
|
| |
387 | goto out; |
388 | |
389 | chunk = dotp->l_used - doto; |
390 | |
391 | if (chunk > n) |
| 21 | | Assuming 'chunk' is <= 'n' | |
|
| |
392 | chunk = n; |
393 | |
394 | if (chunk == 0) { |
| 23 | | Assuming 'chunk' is equal to 0 | |
|
| |
395 | if (dotp == blastlp(curbp)) |
| 25 | | Assuming 'dotp' is not equal to field 'l_bp' | |
|
| |
396 | goto out; |
397 | lchange(WFFULL); |
398 | if (ldelnewline() == FALSE) |
| |
399 | goto out; |
400 | end = strlcat(sv, curbp->b_nlchr, len + 1); |
401 | --n; |
402 | continue; |
403 | } |
404 | lchange(WFEDIT); |
405 | |
406 | cp1 = &dotp->l_text[doto]; |
407 | memcpy(&sv[end], cp1, chunk); |
408 | end += chunk; |
409 | sv[end] = '\0'; |
410 | for (cp2 = cp1 + chunk; cp2 < &dotp->l_text[dotp->l_used]; |
411 | cp2++) |
412 | *cp1++ = *cp2; |
413 | dotp->l_used -= (int)chunk; |
414 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
415 | if (wp->w_dotp == dotp && wp->w_doto >= doto) { |
416 | wp->w_doto -= chunk; |
417 | if (wp->w_doto < doto) |
418 | wp->w_doto = doto; |
419 | } |
420 | if (wp->w_markp == dotp && wp->w_marko >= doto) { |
421 | wp->w_marko -= chunk; |
422 | if (wp->w_marko < doto) |
423 | wp->w_marko = doto; |
424 | } |
425 | } |
426 | n -= chunk; |
427 | } |
428 | if (kchunk(sv, (RSIZE)len, kflag) != TRUE) |
429 | goto out; |
430 | rval = TRUE; |
431 | out: |
432 | free(sv); |
433 | return (rval); |
434 | } |
435 | |
436 | |
437 | |
438 | |
439 | |
440 | |
441 | |
442 | |
443 | |
444 | |
445 | |
446 | |
447 | |
448 | int |
449 | ldelnewline(void) |
450 | { |
451 | struct line *lp1, *lp2, *lp3; |
452 | struct mgwin *wp; |
453 | int s; |
454 | |
455 | if ((s = checkdirty(curbp)) != TRUE) |
| 28 | | Assuming the condition is false | |
|
| |
456 | return (s); |
457 | if (curbp->b_flag & BFREADONLY) { |
| 30 | | Assuming the condition is false | |
|
| |
458 | dobeep(); |
459 | ewprintf("Buffer is read only"); |
460 | return (FALSE); |
461 | } |
462 | |
463 | lp1 = curwp->w_dotp; |
464 | lp2 = lp1->l_fp; |
465 | |
466 | if (lp2 == curbp->b_headp) |
| 32 | | Assuming 'lp2' is not equal to field 'b_headp' | |
|
| |
467 | return (TRUE); |
468 | |
469 | curwp->w_bufp->b_lines--; |
470 | if (curwp->w_markline > curwp->w_dotline) |
| 34 | | Assuming field 'w_markline' is <= field 'w_dotline' | |
|
| |
471 | curwp->w_markline--; |
472 | if (lp2->l_used <= lp1->l_size - lp1->l_used) { |
| 36 | | Assuming the condition is false | |
|
| |
473 | bcopy(&lp2->l_text[0], &lp1->l_text[lp1->l_used], lp2->l_used); |
474 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
475 | if (wp->w_linep == lp2) |
476 | wp->w_linep = lp1; |
477 | if (wp->w_dotp == lp2) { |
478 | wp->w_dotp = lp1; |
479 | wp->w_doto += lp1->l_used; |
480 | } |
481 | if (wp->w_markp == lp2) { |
482 | wp->w_markp = lp1; |
483 | wp->w_marko += lp1->l_used; |
484 | } |
485 | } |
486 | lp1->l_used += lp2->l_used; |
487 | lp1->l_fp = lp2->l_fp; |
488 | lp2->l_fp->l_bp = lp1; |
489 | free(lp2); |
490 | return (TRUE); |
491 | } |
492 | if ((lp3 = lalloc(lp1->l_used + lp2->l_used)) == NULL) |
| |
| 48 | | Returning from 'lalloc' | |
|
| |
493 | return (FALSE); |
494 | bcopy(&lp1->l_text[0], &lp3->l_text[0], lp1->l_used); |
| 50 | | Null pointer passed as 2nd argument to memory copy function |
|
495 | bcopy(&lp2->l_text[0], &lp3->l_text[lp1->l_used], lp2->l_used); |
496 | lp1->l_bp->l_fp = lp3; |
497 | lp3->l_fp = lp2->l_fp; |
498 | lp2->l_fp->l_bp = lp3; |
499 | lp3->l_bp = lp1->l_bp; |
500 | for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
501 | if (wp->w_linep == lp1 || wp->w_linep == lp2) |
502 | wp->w_linep = lp3; |
503 | if (wp->w_dotp == lp1) |
504 | wp->w_dotp = lp3; |
505 | else if (wp->w_dotp == lp2) { |
506 | wp->w_dotp = lp3; |
507 | wp->w_doto += lp1->l_used; |
508 | } |
509 | if (wp->w_markp == lp1) |
510 | wp->w_markp = lp3; |
511 | else if (wp->w_markp == lp2) { |
512 | wp->w_markp = lp3; |
513 | wp->w_marko += lp1->l_used; |
514 | } |
515 | } |
516 | free(lp1); |
517 | free(lp2); |
518 | return (TRUE); |
519 | } |
520 | |
521 | |
522 | |
523 | |
524 | |
525 | |
526 | |
527 | int |
528 | lreplace(RSIZE plen, char *st) |
529 | { |
530 | RSIZE rlen; |
531 | struct line *lp; |
532 | RSIZE n; |
533 | int s, doto, is_query_capitalised = 0, is_query_allcaps = 0; |
534 | int is_replace_alllower = 0; |
535 | char *repl = NULL; |
536 | |
537 | if ((s = checkdirty(curbp)) != TRUE) |
| 1 | Assuming the condition is false | |
|
| |
538 | return (s); |
539 | if (curbp->b_flag & BFREADONLY) { |
| 3 | | Assuming the condition is false | |
|
| |
540 | dobeep(); |
541 | ewprintf("Buffer is read only"); |
542 | return (FALSE); |
543 | } |
544 | |
545 | if ((repl = strdup(st)) == NULL) { |
| 5 | | Assuming the condition is false | |
|
| |
546 | dobeep(); |
547 | ewprintf("out of memory"); |
548 | return (FALSE); |
549 | } |
550 | rlen = strlen(repl); |
551 | |
552 | undo_boundary_enable(FFRAND, 0); |
553 | (void)backchar(FFARG | FFRAND, (int)plen); |
554 | |
555 | if (casereplace != TRUE) |
| 7 | | Assuming 'casereplace' is not equal to TRUE | |
|
| |
556 | goto done; |
| 9 | | Control jumps to line 594 | |
|
557 | |
558 | lp = curwp->w_dotp; |
559 | if (ltext(lp) == NULL) |
560 | goto done; |
561 | doto = curwp->w_doto; |
562 | n = plen; |
563 | |
564 | is_query_capitalised = isupper((unsigned char)lgetc(lp, doto)); |
565 | |
566 | if (is_query_capitalised) { |
567 | for (n = 0, is_query_allcaps = 1; n < plen && is_query_allcaps; |
568 | n++) { |
569 | is_query_allcaps = !isalpha((unsigned char)lgetc(lp, |
570 | doto)) || isupper((unsigned char)lgetc(lp, doto)); |
571 | doto++; |
572 | if (doto == llength(lp)) { |
573 | doto = 0; |
574 | lp = lforw(lp); |
575 | n++; |
576 | } |
577 | } |
578 | } |
579 | |
580 | for (n = 0, is_replace_alllower = 1; n < rlen && is_replace_alllower; |
581 | n++) |
582 | is_replace_alllower = !isupper((unsigned char)repl[n]); |
583 | |
584 | if (is_replace_alllower) { |
585 | if (is_query_allcaps) { |
586 | for (n = 0; n < rlen; n++) |
587 | repl[n] = toupper((unsigned char)repl[n]); |
588 | } else if (is_query_capitalised) { |
589 | repl[0] = toupper((unsigned char)repl[0]); |
590 | } |
591 | } |
592 | |
593 | done: |
594 | (void)ldelete(plen, KNONE); |
| |
595 | region_put_data(repl, rlen); |
596 | lchange(WFFULL); |
597 | |
598 | undo_boundary_enable(FFRAND, 1); |
599 | |
600 | free(repl); |
601 | return (TRUE); |
602 | } |
603 | |
604 | |
605 | |
606 | |
607 | char * |
608 | linetostr(const struct line *ln) |
609 | { |
610 | int len; |
611 | char *line; |
612 | |
613 | len = llength(ln); |
614 | if (len == INT_MAX) |
615 | return (NULL); |
616 | |
617 | if ((line = malloc(len + 1)) == NULL) |
618 | return (NULL); |
619 | |
620 | (void)memcpy(line, ltext(ln), len); |
621 | line[len] = '\0'; |
622 | |
623 | return (line); |
624 | } |