Bug Summary

File:src/lib/libmenu/m_post.c
Warning:line 231, column 18
Access to field 'right' results in a dereference of a null pointer (loaded from variable 'hitem')

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 m_post.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 -pic-is-pie -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/libmenu/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/lib/libmenu -I /usr/src/lib/libmenu/../libcurses -D HAVE_CONFIG_H -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libmenu/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/libmenu/m_post.c
1/* $OpenBSD: m_post.c,v 1.7 2010/01/12 23:22:08 nicm Exp $ */
2
3/****************************************************************************
4 * Copyright (c) 1998-2003,2004 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: Juergen Pfeifer, 1995,1997 *
33 ****************************************************************************/
34
35/***************************************************************************
36* Module m_post *
37* Write or erase menus from associated subwindows *
38***************************************************************************/
39
40#include "menu.priv.h"
41
42MODULE_ID("$Id: m_post.c,v 1.7 2010/01/12 23:22:08 nicm Exp $")
43
44/*---------------------------------------------------------------------------
45| Facility : libnmenu
46| Function : void _nc_Post_Item(MENU *menu, ITEM *item)
47|
48| Description : Draw the item in the menus window at the current
49| window position
50|
51| Return Values : -
52+--------------------------------------------------------------------------*/
53NCURSES_EXPORT(void)void
54_nc_Post_Item(const MENU * menu, const ITEM * item)
55{
56 int i;
57 chtype ch;
58 int item_x, item_y;
59 int count = 0;
60 bool_Bool isfore = FALSE0, isback = FALSE0, isgrey = FALSE0;
61 int name_len;
62 int desc_len;
63
64 assert(menu->win)((void)0);
65
66 getyx(menu->win, item_y, item_x)(item_y = ((menu->win) ? (menu->win)->_cury : (-1)),
item_x = ((menu->win) ? (menu->win)->_curx : (-1)))
;
67
68 /* We need a marker iff
69 - it is a onevalued menu and it is the current item
70 - or it has a selection value
71 */
72 wattron(menu->win, menu->back)wattr_on(menu->win, (attr_t)(menu->back), ((void*)0));
73 if (item->value || (item == menu->curitem))
74 {
75 if (menu->marklen)
76 {
77 /* In a multi selection menu we use the fore attribute
78 for a selected marker that is not the current one.
79 This improves visualization of the menu, because now
80 always the 'normal' marker denotes the current
81 item. */
82 if (!(menu->opt & O_ONEVALUE(0x01)) && item->value && item != menu->curitem)
83 {
84 wattron(menu->win, menu->fore)wattr_on(menu->win, (attr_t)(menu->fore), ((void*)0));
85 isfore = TRUE1;
86 }
87 waddstr(menu->win, menu->mark)waddnstr(menu->win,menu->mark,-1);
88 if (isfore)
89 {
90 wattron(menu->win, menu->fore)wattr_on(menu->win, (attr_t)(menu->fore), ((void*)0));
91 isfore = FALSE0;
92 }
93 }
94 }
95 else /* otherwise we have to wipe out the marker area */
96 for (ch = ' ', i = menu->marklen; i > 0; i--)
97 waddch(menu->win, ch);
98 wattroff(menu->win, menu->back)wattr_off(menu->win, (attr_t)(menu->back), ((void*)0));
99 count += menu->marklen;
100
101 /* First we have to calculate the attribute depending on selectability
102 and selection status
103 */
104 if (!(item->opt & O_SELECTABLE(0x01)))
105 {
106 wattron(menu->win, menu->grey)wattr_on(menu->win, (attr_t)(menu->grey), ((void*)0));
107 isgrey = TRUE1;
108 }
109 else
110 {
111 if (item->value || item == menu->curitem)
112 {
113 wattron(menu->win, menu->fore)wattr_on(menu->win, (attr_t)(menu->fore), ((void*)0));
114 isfore = TRUE1;
115 }
116 else
117 {
118 wattron(menu->win, menu->back)wattr_on(menu->win, (attr_t)(menu->back), ((void*)0));
119 isback = TRUE1;
120 }
121 }
122
123 waddnstr(menu->win, item->name.str, item->name.length);
124 name_len = _nc_Calculate_Text_Width(&(item->name));
125 for (ch = ' ', i = menu->namelen - name_len; i > 0; i--)
126 {
127 waddch(menu->win, ch);
128 }
129 count += menu->namelen;
130
131 /* Show description if required and available */
132 if ((menu->opt & O_SHOWDESC(0x02)) && menu->desclen > 0)
133 {
134 int m = menu->spc_desc / 2;
135 int cy = -1, cx = -1;
136
137 for (ch = ' ', i = 0; i < menu->spc_desc; i++)
138 {
139 if (i == m)
140 {
141 waddch(menu->win, menu->pad);
142 getyx(menu->win, cy, cx)(cy = ((menu->win) ? (menu->win)->_cury : (-1)), cx =
((menu->win) ? (menu->win)->_curx : (-1)))
;
143 }
144 else
145 waddch(menu->win, ch);
146 }
147 if (item->description.length)
148 waddnstr(menu->win, item->description.str, item->description.length);
149 desc_len = _nc_Calculate_Text_Width(&(item->description));
150 for (ch = ' ', i = menu->desclen - desc_len; i > 0; i--)
151 {
152 waddch(menu->win, ch);
153 }
154 count += menu->desclen + menu->spc_desc;
155
156 if (menu->spc_rows > 1)
157 {
158 int j, k, ncy, ncx;
159
160 assert(cx >= 0 && cy >= 0)((void)0);
161 getyx(menu->win, ncy, ncx)(ncy = ((menu->win) ? (menu->win)->_cury : (-1)), ncx
= ((menu->win) ? (menu->win)->_curx : (-1)))
;
162 if (isgrey)
163 wattroff(menu->win, menu->grey)wattr_off(menu->win, (attr_t)(menu->grey), ((void*)0));
164 else if (isfore)
165 wattroff(menu->win, menu->fore)wattr_off(menu->win, (attr_t)(menu->fore), ((void*)0));
166 wattron(menu->win, menu->back)wattr_on(menu->win, (attr_t)(menu->back), ((void*)0));
167 for (j = 1; j < menu->spc_rows; j++)
168 {
169 if ((item_y + j) < getmaxy(menu->win)((menu->win) ? ((menu->win)->_maxy + 1) : (-1)))
170 {
171 wmove(menu->win, item_y + j, item_x);
172 for (k = 0; k < count; k++)
173 waddch(menu->win, ' ');
174 }
175 if ((cy + j) < getmaxy(menu->win)((menu->win) ? ((menu->win)->_maxy + 1) : (-1)))
176 mvwaddch(menu->win, cy + j, cx - 1, menu->pad)(wmove(menu->win,cy + j,cx - 1) == (-1) ? (-1) : waddch(menu
->win,menu->pad))
;
177 }
178 wmove(menu->win, ncy, ncx);
179 if (!isback)
180 wattroff(menu->win, menu->back)wattr_off(menu->win, (attr_t)(menu->back), ((void*)0));
181 }
182 }
183
184 /* Remove attributes */
185 if (isfore)
186 wattroff(menu->win, menu->fore)wattr_off(menu->win, (attr_t)(menu->fore), ((void*)0));
187 if (isback)
188 wattroff(menu->win, menu->back)wattr_off(menu->win, (attr_t)(menu->back), ((void*)0));
189 if (isgrey)
190 wattroff(menu->win, menu->grey)wattr_off(menu->win, (attr_t)(menu->grey), ((void*)0));
191}
192
193/*---------------------------------------------------------------------------
194| Facility : libnmenu
195| Function : void _nc_Draw_Menu(const MENU *)
196|
197| Description : Display the menu in its windows
198|
199| Return Values : -
200+--------------------------------------------------------------------------*/
201NCURSES_EXPORT(void)void
202_nc_Draw_Menu(const MENU * menu)
203{
204 ITEM *item = menu->items[0];
31
'item' initialized to a null pointer value
205 ITEM *lasthor, *lastvert;
206 ITEM *hitem;
207 int y = 0;
208 chtype s_bkgd;
209
210 assert(item && menu->win)((void)0);
211
212 s_bkgd = getbkgd(menu->win)((menu->win)->_bkgd);
213 wbkgdset(menu->win, menu->back);
214 werase(menu->win);
215 wbkgdset(menu->win, s_bkgd);
216
217 lastvert = (menu->opt & O_NONCYCLIC(0x20)) ? (ITEM *) 0 : item;
32
Assuming the condition is true
33
'?' condition is true
218
219 do
220 {
221 wmove(menu->win, y, 0);
222
223 hitem = item;
34
Null pointer value stored to 'hitem'
224 lasthor = (menu->opt & O_NONCYCLIC(0x20)) ? (ITEM *) 0 : hitem;
35
'?' condition is true
225
226 do
227 {
228 _nc_Post_Item(menu, hitem);
229
230 wattron(menu->win, menu->back)wattr_on(menu->win, (attr_t)(menu->back), ((void*)0));
231 if (((hitem = hitem->right) != lasthor) && hitem)
36
Access to field 'right' results in a dereference of a null pointer (loaded from variable 'hitem')
232 {
233 int i, j, cy, cx;
234 chtype ch = ' ';
235
236 getyx(menu->win, cy, cx)(cy = ((menu->win) ? (menu->win)->_cury : (-1)), cx =
((menu->win) ? (menu->win)->_curx : (-1)))
;
237 for (j = 0; j < menu->spc_rows; j++)
238 {
239 wmove(menu->win, cy + j, cx);
240 for (i = 0; i < menu->spc_cols; i++)
241 {
242 waddch(menu->win, ch);
243 }
244 }
245 wmove(menu->win, cy, cx + menu->spc_cols);
246 }
247 }
248 while (hitem && (hitem != lasthor));
249 wattroff(menu->win, menu->back)wattr_off(menu->win, (attr_t)(menu->back), ((void*)0));
250
251 item = item->down;
252 y += menu->spc_rows;
253
254 }
255 while (item && (item != lastvert));
256}
257
258/*---------------------------------------------------------------------------
259| Facility : libnmenu
260| Function : int post_menu(MENU *)
261|
262| Description : Post a menu to the screen. This makes it visible.
263|
264| Return Values : E_OK - success
265| E_BAD_ARGUMENT - not a valid menu pointer
266| E_SYSTEM_ERROR - error in lower layers
267| E_NOT_CONNECTED - No items connected to menu
268| E_BAD_STATE - Menu in userexit routine
269| E_POSTED - Menu already posted
270+--------------------------------------------------------------------------*/
271NCURSES_EXPORT(int)int
272post_menu(MENU * menu)
273{
274 T((T_CALLED("post_menu(%p)"), menu));
275
276 if (!menu)
1
Assuming 'menu' is non-null
2
Taking false branch
277 RETURN(E_BAD_ARGUMENT)return( ((*__errno())=((-2))) );
278
279 if (menu->status & _IN_DRIVER(0x02U))
3
Assuming the condition is false
4
Taking false branch
280 RETURN(E_BAD_STATE)return( ((*__errno())=((-5))) );
281
282 if (menu->status & _POSTED(0x01U))
5
Assuming the condition is false
6
Taking false branch
283 RETURN(E_POSTED)return( ((*__errno())=((-3))) );
284
285 if (menu->items && *(menu->items))
7
Assuming field 'items' is non-null
8
Assuming the condition is true
9
Taking true branch
286 {
287 int y;
288 int h = 1 + menu->spc_rows * (menu->rows - 1);
289
290 WINDOW *win = Get_Menu_Window(menu)((menu)->usersub ? (menu)->usersub : ((menu)->userwin
? (menu)->userwin : stdscr))
;
10
Assuming field 'usersub' is null
11
'?' condition is false
12
Assuming field 'userwin' is null
13
'?' condition is false
291 int maxy = getmaxy(win)((win) ? ((win)->_maxy + 1) : (-1));
14
Assuming 'win' is null
15
'?' condition is false
292
293 if ((menu->win = newpad(h, menu->width)))
16
Assuming field 'win' is non-null
17
Taking true branch
294 {
295 y = (maxy >= h) ? h : maxy;
18
Assuming 'maxy' is < 'h'
19
'?' condition is false
296 if (y >= menu->height)
20
Assuming 'y' is < field 'height'
21
Taking false branch
297 y = menu->height;
298 if (!(menu->sub = subpad(menu->win, y, menu->width, 0, 0)))
22
Assuming field 'sub' is non-null
23
Taking false branch
299 RETURN(E_SYSTEM_ERROR)return( ((*__errno())=((-1))) );
300 }
301 else
302 RETURN(E_SYSTEM_ERROR)return( ((*__errno())=((-1))) );
303
304 if (menu->status & _LINK_NEEDED(0x04))
24
Assuming the condition is true
25
Taking true branch
305 _nc_Link_Items(menu);
306 }
307 else
308 RETURN(E_NOT_CONNECTED)return( ((*__errno())=((-11))) );
309
310 menu->status |= _POSTED(0x01U);
311
312 if (!(menu->opt & O_ONEVALUE(0x01)))
26
Assuming the condition is true
27
Taking true branch
313 {
314 ITEM **items;
315
316 for (items = menu->items; *items; items++)
28
Assuming pointer value is null
29
Loop condition is false. Execution continues on line 322
317 {
318 (*items)->value = FALSE0;
319 }
320 }
321
322 _nc_Draw_Menu(menu);
30
Calling '_nc_Draw_Menu'
323
324 Call_Hook(menu, menuinit)if ( (menu) != 0 && ((menu)->menuinit) != (void *)
0 ) { (menu)->status |= (0x02U); (menu)->menuinit(menu
); (menu)->status &= ~(0x02U); }
;
325 Call_Hook(menu, iteminit)if ( (menu) != 0 && ((menu)->iteminit) != (void *)
0 ) { (menu)->status |= (0x02U); (menu)->iteminit(menu
); (menu)->status &= ~(0x02U); }
;
326
327 _nc_Show_Menu(menu);
328
329 RETURN(E_OK)return( ((*__errno())=((0))) );
330}
331
332/*---------------------------------------------------------------------------
333| Facility : libnmenu
334| Function : int unpost_menu(MENU *)
335|
336| Description : Detach menu from screen
337|
338| Return Values : E_OK - success
339| E_BAD_ARGUMENT - not a valid menu pointer
340| E_BAD_STATE - menu in userexit routine
341| E_NOT_POSTED - menu is not posted
342+--------------------------------------------------------------------------*/
343NCURSES_EXPORT(int)int
344unpost_menu(MENU * menu)
345{
346 WINDOW *win;
347
348 T((T_CALLED("unpost_menu(%p)"), menu));
349
350 if (!menu)
351 RETURN(E_BAD_ARGUMENT)return( ((*__errno())=((-2))) );
352
353 if (menu->status & _IN_DRIVER(0x02U))
354 RETURN(E_BAD_STATE)return( ((*__errno())=((-5))) );
355
356 if (!(menu->status & _POSTED(0x01U)))
357 RETURN(E_NOT_POSTED)return( ((*__errno())=((-7))) );
358
359 Call_Hook(menu, itemterm)if ( (menu) != 0 && ((menu)->itemterm) != (void *)
0 ) { (menu)->status |= (0x02U); (menu)->itemterm(menu
); (menu)->status &= ~(0x02U); }
;
360 Call_Hook(menu, menuterm)if ( (menu) != 0 && ((menu)->menuterm) != (void *)
0 ) { (menu)->status |= (0x02U); (menu)->menuterm(menu
); (menu)->status &= ~(0x02U); }
;
361
362 win = Get_Menu_Window(menu)((menu)->usersub ? (menu)->usersub : ((menu)->userwin
? (menu)->userwin : stdscr))
;
363 werase(win);
364 wsyncup(win);
365
366 assert(menu->sub)((void)0);
367 delwin(menu->sub);
368 menu->sub = (WINDOW *)0;
369
370 assert(menu->win)((void)0);
371 delwin(menu->win);
372 menu->win = (WINDOW *)0;
373
374 menu->status &= ~_POSTED(0x01U);
375
376 RETURN(E_OK)return( ((*__errno())=((0))) );
377}
378
379/* m_post.c ends here */