Bug Summary

File:cli/src/cli-rl.c
Location:line 240, column 15
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/*
2 Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13#include <stdint.h>
14#include <pthread.h>
15
16#ifndef _CONFIG_H
17#define _CONFIG_H
18#include "config.h"
19#endif
20
21#include "cli.h"
22#include "cli-cmd.h"
23#include "cli-mem-types.h"
24
25#include "event.h"
26
27#include <fnmatch.h>
28
29#ifdef HAVE_READLINE1
30
31#include <stdio.h>
32#include <readline/readline.h>
33#include <readline/history.h>
34
35
36int
37cli_rl_out (struct cli_state *state, const char *fmt, va_list ap)
38{
39 int tmp_rl_point = rl_point;
40 int n = rl_end;
41 int ret = 0;
42
43 if (rl_end >= 0 ) {
44 rl_kill_text (0, rl_end);
45 rl_redisplay ();
46 }
47
48 printf ("\r%*s\r", (int)strlen (state->prompt), "");
49
50 ret = vprintf (fmt, ap);
51
52 printf ("\n");
53 fflush(stdoutstdout);
54
55 if (n) {
56 rl_do_undo ();
57 rl_point = tmp_rl_point;
58 rl_reset_line_state ();
59 }
60
61 return ret;
62}
63
64int
65cli_rl_err (struct cli_state *state, const char *fmt, va_list ap)
66{
67 int tmp_rl_point = rl_point;
68 int n = rl_end;
69 int ret = 0;
70
71 if (rl_end >= 0 ) {
72 rl_kill_text (0, rl_end);
73 rl_redisplay ();
74 }
75
76 fprintf (stderrstderr, "\r%*s\r", (int)strlen (state->prompt), "");
77
78 ret = vfprintf (stderrstderr, fmt, ap);
79
80 fprintf (stderrstderr, "\n");
81 fflush(stderrstderr);
82
83 if (n) {
84 rl_do_undo ();
85 rl_point = tmp_rl_point;
86 rl_reset_line_state ();
87 }
88
89 return ret;
90}
91
92
93void
94cli_rl_process_line (char *line)
95{
96 struct cli_state *state = NULL((void*)0);
97 int ret = 0;
98
99 state = global_state;
100
101 state->rl_processing = 1;
102 {
103 ret = cli_cmd_process_line (state, line);
104 if (ret)
105 gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to process line"); } while (
0); _gf_log ((*__glusterfs_this_location())->name, "cli-rl.c"
, __FUNCTION__, 106, GF_LOG_WARNING, "failed to process line"
); } while (0)
106 "failed to process line")do { do { if (0) printf ("failed to process line"); } while (
0); _gf_log ((*__glusterfs_this_location())->name, "cli-rl.c"
, __FUNCTION__, 106, GF_LOG_WARNING, "failed to process line"
); } while (0)
;
107
108 add_history (line);
109 }
110 state->rl_processing = 0;
111
112}
113
114
115int
116cli_rl_stdin (int fd, int idx, void *data,
117 int poll_out, int poll_in, int poll_err)
118{
119 rl_callback_read_char ();
120
121 return 0;
122}
123
124
125char *
126cli_rl_autocomplete_entry (const char *text, int times)
127{
128 struct cli_state *state = NULL((void*)0);
129 char *retp = NULL((void*)0);
130
131 state = global_state;
132
133 if (!state->matchesp)
134 return NULL((void*)0);
135
136 retp = *state->matchesp;
137
138 state->matchesp++;
139
140 return retp ? strdup (retp) : NULL((void*)0);
141}
142
143
144int
145cli_rl_token_count (const char *text)
146{
147 int count = 0;
148 const char *trav = NULL((void*)0);
149 int is_spc = 1;
150
151 for (trav = text; *trav; trav++) {
152 if (*trav == ' ') {
153 is_spc = 1;
154 } else {
155 if (is_spc) {
156 count++;
157 is_spc = 0;
158 }
159 }
160 }
161
162 if (is_spc)
163 /* what needs to be autocompleted is a full
164 new word, and not extend the last word
165 */
166 count++;
167
168 return count;
169}
170
171
172char **
173cli_rl_tokenize (const char *text)
174{
175 int count = 0;
176 char **tokens = NULL((void*)0);
177 char **tokenp = NULL((void*)0);
178 char *token = NULL((void*)0);
179 char *copy = NULL((void*)0);
180 char *saveptr = NULL((void*)0);
181 int i = 0;
182
183 count = cli_rl_token_count (text);
184
185 tokens = calloc (count + 1, sizeof (*tokens));
186 if (!tokens)
187 return NULL((void*)0);
188
189 copy = strdup (text);
190 if (!copy)
191 goto out;
192
193 tokenp = tokens;
194
195 for (token = strtok_r (copy, " \t\r\n", &saveptr); token;
196 token = strtok_r (NULL((void*)0), " \t\r\n", &saveptr)) {
197 *tokenp = strdup (token);
198
199 if (!*tokenp)
200 goto out;
201 tokenp++;
202 i++;
203
204 }
205
206 if (i < count) {
207 /* symbolize that what needs to be autocompleted is
208 the full set of possible nextwords, and not extend
209 the last word
210 */
211 *tokenp = strdup ("");
212 if (!*tokenp)
213 goto out;
214 tokenp++;
215 i++;
216 }
217
218out:
219 free (copy);
220
221 if (i < count) {
222 cli_cmd_tokens_destroy (tokens);
223 tokens = NULL((void*)0);
224 }
225
226 return tokens;
227}
228
229
230char **
231cli_rl_get_matches (struct cli_state *state, struct cli_cmd_word *word,
232 const char *text)
233{
234 char **matches = NULL((void*)0);
235 char **matchesp = NULL((void*)0);
236 struct cli_cmd_word **next = NULL((void*)0);
237 int count = 0;
238 int len = 0;
239
240 len = strlen (text);
8
Null pointer passed as an argument to a 'nonnull' parameter
241
242 if (!word->nextwords)
243 return NULL((void*)0);
244
245 for (next = word->nextwords; *next; next++)
246 count++;
247
248 matches = calloc (count + 1, sizeof (*matches));
249 matchesp = matches;
250
251 for (next = word->nextwords; *next; next++) {
252 if ((*next)->match) {
253 continue;
254 }
255
256 if (strncmp ((*next)->word, text, len) == 0) {
257 *matchesp = strdup ((*next)->word);
258 matchesp++;
259 }
260 }
261
262 return matches;
263}
264
265
266int
267cli_rl_autocomplete_prepare (struct cli_state *state, const char *text)
268{
269 struct cli_cmd_word *word = NULL((void*)0);
270 struct cli_cmd_word *next = NULL((void*)0);
271 char **tokens = NULL((void*)0);
272 char **tokenp = NULL((void*)0);
273 char *token = NULL((void*)0);
274 char **matches = NULL((void*)0);
275
276 tokens = cli_rl_tokenize (text);
277 if (!tokens)
2
Taking false branch
278 return 0;
279
280 word = &state->tree.root;
281
282 for (tokenp = tokens; (token = *tokenp); tokenp++) {
3
Null pointer value stored to 'token'
4
Loop condition is false. Execution continues on line 294
283 if (!*(tokenp+1)) {
284 /* last word */
285 break;
286 }
287
288 next = cli_cmd_nextword (word, token);
289 word = next;
290 if (!word)
291 break;
292 }
293
294 if (!word)
5
Taking false branch
295 goto out;
296
297 matches = cli_rl_get_matches (state, word, token);
6
Passing null pointer value via 3rd parameter 'text'
7
Calling 'cli_rl_get_matches'
298
299 state->matches = matches;
300 state->matchesp = matches;
301
302out:
303 cli_cmd_tokens_destroy (tokens);
304 return 0;
305}
306
307
308int
309cli_rl_autocomplete_cleanup (struct cli_state *state)
310{
311 if (state->matches)
312 cli_cmd_tokens_destroy (state->matches);
313
314 state->matches = NULL((void*)0);
315 state->matchesp = NULL((void*)0);
316
317 return 0;
318}
319
320
321char **
322cli_rl_autocomplete (const char *text, int start, int end)
323{
324 struct cli_state *state = NULL((void*)0);
325 char **matches = NULL((void*)0);
326 char save = 0;
327
328 state = global_state;
329
330 /* hack to make the autocompletion code neater */
331 /* fake it as though the cursor is at the end of line */
332
333 save = rl_line_buffer[rl_point];
334 rl_line_buffer[rl_point] = 0;
335
336 cli_rl_autocomplete_prepare (state, rl_line_buffer);
1
Calling 'cli_rl_autocomplete_prepare'
337
338 matches = rl_completion_matches (text, cli_rl_autocomplete_entry);
339
340 cli_rl_autocomplete_cleanup (state);
341
342 rl_line_buffer[rl_point] = save;
343
344 return matches;
345}
346
347
348static char *
349complete_none (const char *txt, int times)
350{
351 return NULL((void*)0);
352}
353
354
355void *
356cli_rl_input (void *_data)
357{
358 struct cli_state *state = NULL((void*)0);
359 char *line = NULL((void*)0);
360
361 state = _data;
362
363 for (;;) {
364 line = readline (state->prompt);
365 if (!line)
366 exit(0); //break;
367
368 if (*line)
369 cli_rl_process_line (line);
370
371 free (line);
372 }
373
374 return NULL((void*)0);
375}
376
377
378int
379cli_rl_enable (struct cli_state *state)
380{
381 int ret = 0;
382
383 rl_pre_input_hook = NULL((void*)0);
384 rl_attempted_completion_function = cli_rl_autocomplete;
385 rl_completion_entry_function = complete_none;
386
387 if (!state->rl_async) {
388 ret = pthread_create (&state->input, NULL((void*)0),
389 cli_rl_input, state);
390 if (ret == 0)
391 state->rl_enabled = 1;
392 goto out;
393 }
394
395 ret = event_register (state->ctx->event_pool, 0, cli_rl_stdin, state,
396 1, 0);
397 if (ret == -1)
398 goto out;
399
400 state->rl_enabled = 1;
401 rl_callback_handler_install (state->prompt, cli_rl_process_line);
402
403out:
404 return state->rl_enabled;
405}
406
407#else /* HAVE_READLINE */
408
409int
410cli_rl_enable (struct cli_state *state)
411{
412 return 0;
413}
414
415#endif /* HAVE_READLINE */