Bug Summary

File:saveutil.c
Location:line 157, column 18
Description:Access to field 'name' results in a dereference of a null pointer (loaded from variable 'prop')

Annotated Source Code

1/* $Xorg: saveutil.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */
2/******************************************************************************
3
4Copyright 1993, 1998 The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25******************************************************************************/
26/* $XFree86: xc/programs/xsm/saveutil.c,v 1.5 2001/01/17 23:46:31 dawes Exp $ */
27
28#include "xsm.h"
29#include "log.h"
30#include "saveutil.h"
31#include "info.h"
32
33static char session_save_file[PATH_MAX1024];
34
35
36void
37set_session_save_file_name(const char *session_name)
38{
39 const char *p;
40
41 p = getenv ("SM_SAVE_DIR");
42 if (!p)
43 {
44 p = getenv ("HOME");
45 if (!p)
46 p = ".";
47 }
48
49 snprintf (session_save_file, sizeof(session_save_file),__builtin___snprintf_chk (session_save_file, sizeof(session_save_file
), 0, __builtin_object_size (session_save_file, 2 > 1 ? 1 :
0), "%s/.XSM-%s", p, session_name)
50 "%s/.XSM-%s", p, session_name)__builtin___snprintf_chk (session_save_file, sizeof(session_save_file
), 0, __builtin_object_size (session_save_file, 2 > 1 ? 1 :
0), "%s/.XSM-%s", p, session_name)
;
51}
52
53
54
55int
56ReadSave(const char *session_name, char **sm_id)
57{
58 char *buf;
59 int buflen;
60 char *p;
61 PendingClient *c = NULL((void*)0);
62 Prop *prop = NULL((void*)0);
63 PropValue *val;
64 FILE *f;
65 int state, i;
66 int version_number;
67
68 f = fopen(session_save_file, "r");
69 if(!f) {
1
Assuming 'f' is non-null
2
Taking false branch
70 if (verbose)
71 printf("No session save file.\n");
72 *sm_id = NULL((void*)0);
73 return 0;
74 }
75 fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1);
76 if (verbose)
3
Assuming 'verbose' is 0
4
Taking false branch
77 printf("Reading session save file...\n");
78
79 buf = NULL((void*)0);
80 buflen = 0;
81
82 /* Read version # */
83 getnextline(&buf, &buflen, f);
84 if((p = strchr(buf, '\n'))) *p = '\0';
5
Assuming 'p' is null
6
Taking false branch
85 version_number = atoi (buf);
86 if (version_number > SAVEFILE_VERSION3)
7
Assuming 'version_number' is <= 3
8
Taking false branch
87 {
88 if (verbose)
89 printf("Unsupported version number of session save file.\n");
90 *sm_id = NULL((void*)0);
91 if (buf)
92 free (buf);
93 return 0;
94 }
95
96 /* Read SM's id */
97 getnextline(&buf, &buflen, f);
98 if((p = strchr(buf, '\n'))) *p = '\0';
9
Assuming 'p' is null
10
Taking false branch
99 *sm_id = XtNewString(buf)((buf) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(buf) + 1), buf, __builtin_object_size (XtMalloc((unsigned
)strlen(buf) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
100
101 /* Read number of clients running in the last session */
102 if (version_number >= 2)
11
Assuming 'version_number' is < 2
12
Taking false branch
103 {
104 getnextline(&buf, &buflen, f);
105 if((p = strchr(buf, '\n'))) *p = '\0';
106 num_clients_in_last_session = atoi (buf);
107 }
108
109 state = 0;
110 while(getnextline(&buf, &buflen, f)) {
13
Loop condition is true. Entering loop body
19
Loop condition is true. Entering loop body
32
Loop condition is true. Entering loop body
41
Loop condition is true. Entering loop body
111 if((p = strchr(buf, '\n'))) *p = '\0';
14
Assuming 'p' is null
15
Taking false branch
20
Assuming 'p' is null
21
Taking false branch
33
Assuming 'p' is null
34
Taking false branch
42
Assuming 'p' is null
43
Taking false branch
112 for(p = buf; *p && isspace(*p); p++) /* LOOP */;
22
Loop condition is false. Execution continues on line 113
35
Loop condition is false. Execution continues on line 113
44
Loop condition is false. Execution continues on line 113
113 if(*p == '#') continue;
16
Taking false branch
23
Taking false branch
36
Taking false branch
45
Taking false branch
114
115 if(!*p)
17
Taking true branch
24
Taking false branch
37
Taking false branch
46
Taking false branch
116 {
117 if (version_number >= 3 &&
118 ListCount (PendingList) == num_clients_in_last_session)
119 {
120 state = 5;
121 break;
122 }
123 else
124 {
125 state = 0;
126 continue;
18
Execution continues on line 110
127 }
128 }
129
130 if(!isspace(buf[0])) {
25
Taking true branch
38
Taking true branch
47
Taking true branch
131 switch(state) {
26
Control jumps to 'case 0:' at line 132
39
Control jumps to 'case 1:' at line 147
48
Control jumps to 'case 2:' at line 152
132 case 0:
133 c = (PendingClient *)XtMalloc(sizeof *c);
134 if(!c) nomem();
27
Assuming 'c' is non-null
28
Taking false branch
135
136 c->clientId = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned
)strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
137 c->clientHostname = NULL((void*)0); /* set in next state */
138
139 c->props = ListInit();
140 if(!c->props) nomem();
29
Taking false branch
141
142 if(!ListAddLast(PendingList, (char *)c)) nomem();
30
Taking false branch
143
144 state = 1;
145 break;
31
Execution continues on line 110
146
147 case 1:
148 c->clientHostname = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned
)strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
149 state = 2;
150 break;
40
Execution continues on line 110
151
152 case 2:
153 case 4:
154 prop = (Prop *)XtMalloc(sizeof *prop);
49
Value assigned to 'prop'
155 if(!prop) nomem();
50
Assuming 'prop' is null
51
Taking true branch
156
157 prop->name = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned
)strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
52
Access to field 'name' results in a dereference of a null pointer (loaded from variable 'prop')
158 prop->values = ListInit();
159 if(!prop->values) nomem();
160
161 prop->type = NULL((void*)0);
162
163 if(!ListAddLast(c->props, (char *)prop)) nomem();
164
165 state = 3;
166 break;
167
168 case 3:
169 prop->type = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned
)strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
170 state = 4;
171 break;
172
173 default:
174 fprintf(stderr__stderrp, "state %d\n", state);
175 fprintf(stderr__stderrp,
176 "Corrupt save file line ignored:\n%s\n", buf);
177 continue;
178 }
179 } else {
180 if (state != 4) {
181 fprintf(stderr__stderrp, "Corrupt save file line ignored:\n%s\n", buf);
182 continue;
183 }
184 val = (PropValue *)XtMalloc(sizeof *val);
185 if(!val) nomem();
186
187 if (strcmp (prop->type, SmCARD8"CARD8") == 0)
188 {
189 val->length = 1;
190 val->value = (XtPointer) XtMalloc (1);
191 *((char *)(val->value)) = atoi (p);
192 }
193 else
194 {
195 val->length = strlen(p);
196 val->value = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned
)strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned
)strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
197 }
198
199 if(!ListAddLast(prop->values, (char *)val)) nomem();
200 }
201 }
202
203 /* Read commands for non-session aware clients */
204
205 if (state == 5)
206 {
207 String strbuf;
208 int bufsize = 0;
209
210 getnextline(&buf, &buflen, f);
211 if((p = strchr(buf, '\n'))) *p = '\0';
212 non_session_aware_count = atoi (buf);
213
214 if (non_session_aware_count > 0)
215 {
216 non_session_aware_clients = (char **) malloc (
217 non_session_aware_count * sizeof (char *));
218
219 for (i = 0; i < non_session_aware_count; i++)
220 {
221 getnextline(&buf, &buflen, f);
222 if((p = strchr(buf, '\n'))) *p = '\0';
223 non_session_aware_clients[i] = (char *) malloc (
224 strlen (buf) + 2);
225 strcpy (non_session_aware_clients[i], buf)__builtin___strcpy_chk (non_session_aware_clients[i], buf, __builtin_object_size
(non_session_aware_clients[i], 2 > 1 ? 1 : 0))
;
226 bufsize += (strlen (buf) + 1);
227 }
228
229 strbuf = (String) malloc (bufsize + 1);
230 strbuf[0] = '\0';
231
232 for (i = 0; i < non_session_aware_count; i++)
233 {
234 strcat (strbuf, non_session_aware_clients[i])__builtin___strcat_chk (strbuf, non_session_aware_clients[i],
__builtin_object_size (strbuf, 2 > 1 ? 1 : 0))
;
235 strcat (strbuf, "\n")__builtin___strcat_chk (strbuf, "\n", __builtin_object_size (
strbuf, 2 > 1 ? 1 : 0))
;
236 }
237
238 XtVaSetValues (manualRestartCommands,
239 XtNstring((char*)&XtStrings[733]), strbuf,
240 NULL((void*)0));
241
242 free ((char *) strbuf);
243 }
244 }
245
246 fclose(f);
247
248 if (buf)
249 free (buf);
250
251 return 1;
252}
253
254
255
256static void
257SaveClient(FILE *f, ClientRec *client)
258{
259 List *pl;
260
261 fprintf (f, "%s\n", client->clientId);
262 fprintf (f, "%s\n", client->clientHostname);
263
264 for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
265 {
266 Prop *pprop = (Prop *) pl->thing;
267 List *pj, *vl;
268 PropValue *pval;
269
270 fprintf (f, "%s\n", pprop->name);
271 fprintf (f, "%s\n", pprop->type);
272
273 if (strcmp (pprop->type, SmCARD8"CARD8") == 0)
274 {
275 char *card8;
276 int value;
277
278 vl = ListFirst (pprop->values);
279 pval = (PropValue *) vl->thing;
280
281 card8 = pval->value;
282 value = *card8;
283 fprintf(f, "\t%d\n", value);
284 }
285 else
286 {
287 for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj))
288 {
289 pval = (PropValue *) pj->thing;
290 fprintf (f, "\t%s\n", (char *)pval->value);
291 }
292 }
293 }
294
295 fprintf (f, "\n");
296}
297
298
299
300void
301WriteSave(const char *sm_id)
302{
303 ClientRec *client;
304 FILE *f;
305 List *cl;
306 String commands;
307 char *p, *c;
308 int count;
309
310 f = fopen (session_save_file, "w");
311
312 if (!f)
313 {
314 char msg[256];
315
316 snprintf (msg, sizeof(msg), "%s: Error creating session save file %s",__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size
(msg, 2 > 1 ? 1 : 0), "%s: Error creating session save file %s"
, Argv[0], session_save_file)
317 Argv[0], session_save_file)__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size
(msg, 2 > 1 ? 1 : 0), "%s: Error creating session save file %s"
, Argv[0], session_save_file)
;
318 add_log_text (msg);
319 perror (msg);
320 }
321 else
322 {
323 fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1);
324 fprintf (f, "%d\n", SAVEFILE_VERSION3);
325 fprintf (f, "%s\n", sm_id);
326
327 count = 0;
328 for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
329 {
330 client = (ClientRec *) cl->thing;
331
332 if (client->restartHint != SmRestartNever3)
333 count++;
334 }
335 count += ListCount (RestartAnywayList);
336
337 fprintf (f, "%d\n", count);
338 if (count == 0)
339 fprintf (f, "\n");
340
341 for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
342 {
343 client = (ClientRec *) cl->thing;
344
345 if (client->restartHint == SmRestartNever3)
346 continue;
347
348 SaveClient (f, client);
349 }
350
351 for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl))
352 {
353 client = (ClientRec *) cl->thing;
354
355 SaveClient (f, client);
356 }
357
358
359 /* Save the non-session aware clients */
360
361 XtVaGetValues (manualRestartCommands,
362 XtNstring((char*)&XtStrings[733]), &commands,
363 NULL((void*)0));
364
365 p = c = commands;
366 count = 0;
367
368 while (*p)
369 {
370 if (*p == '\n')
371 {
372 if (p != c)
373 count++;
374 c = p + 1;
375 }
376 p++;
377 }
378 if (p != c)
379 count++;
380
381 fprintf (f, "%d\n", count);
382
383 p = c = commands;
384
385 while (*p)
386 {
387 if (*p == '\n')
388 {
389 if (p != c)
390 {
391 *p = '\0';
392 fprintf (f, "%s\n", c);
393 *p = '\n';
394 }
395 c = p + 1;
396 }
397 p++;
398 }
399
400 if (p != c)
401 fprintf (f, "%s\n", c);
402
403 fclose (f);
404 }
405}
406
407
408
409Statusint
410DeleteSession(const char *session_name)
411{
412 char *buf;
413 int buflen;
414 char *p;
415 const char *dir;
416 FILE *f;
417 int state;
418 int foundDiscard;
419 char filename[256];
420 int version_number;
421
422 dir = getenv ("SM_SAVE_DIR");
423 if (!dir)
424 {
425 dir = getenv ("HOME");
426 if (!dir)
427 dir = ".";
428 }
429
430 snprintf (filename, sizeof(filename), "%s/.XSM-%s", dir, session_name)__builtin___snprintf_chk (filename, sizeof(filename), 0, __builtin_object_size
(filename, 2 > 1 ? 1 : 0), "%s/.XSM-%s", dir, session_name
)
;
431
432 f = fopen(filename, "r");
433 if(!f) {
434 return (0);
435 }
436 fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1);
437
438 buf = NULL((void*)0);
439 buflen = 0;
440
441 /* Read version # */
442 getnextline(&buf, &buflen, f);
443 if((p = strchr(buf, '\n'))) *p = '\0';
444 version_number = atoi (buf);
445 if (version_number > SAVEFILE_VERSION3)
446 {
447 if (verbose)
448 printf("Can't delete session save file - incompatible version.\n");
449 if (buf)
450 free (buf);
451 return (0);
452 }
453
454 /* Skip SM's id */
455 getnextline(&buf, &buflen, f);
456
457 /* Skip number of clients running in the last session */
458 if (version_number >= 2)
459 getnextline(&buf, &buflen, f);
460
461 state = 0;
462 foundDiscard = 0;
463 while(getnextline(&buf, &buflen, f)) {
464 if((p = strchr(buf, '\n'))) *p = '\0';
465 for(p = buf; *p && isspace(*p); p++) /* LOOP */;
466 if(*p == '#') continue;
467
468 if(!*p) {
469 state = 0;
470 foundDiscard = 0;
471 continue;
472 }
473
474 if(!isspace(buf[0])) {
475 switch(state) {
476 case 0:
477 state = 1;
478 break;
479
480 case 1:
481 state = 2;
482 break;
483
484 case 2:
485 case 4:
486 if (strcmp (p, SmDiscardCommand"DiscardCommand") == 0)
487 foundDiscard = 1;
488 state = 3;
489 break;
490
491 case 3:
492 state = 4;
493 break;
494
495 default:
496 continue;
497 }
498 } else {
499 if (state != 4) {
500 continue;
501 }
502 if (foundDiscard)
503 {
504 execute_system_command (p); /* Discard Command */
505 foundDiscard = 0;
506 }
507 }
508 }
509
510 fclose(f);
511
512 if (buf)
513 free (buf);
514
515 return ((remove (filename) == -1) ? 0 : 1);
516}
517
518
519
520Boolint
521getnextline(char **pbuf, int *plen, FILE *f)
522{
523 int c;
524 int i;
525
526 i = 0;
527 while(1) {
528 if(i+2 > *plen) {
529 if(*plen) *plen *= 2;
530 else *plen = BUFSIZ1024;
531 if(*pbuf) *pbuf = (char *) realloc(*pbuf, *plen + 1);
532 else *pbuf = (char *) malloc(*plen + 1);
533 }
534 c = getc(f);
535 if(c == EOF(-1)) break;
536 (*pbuf)[i++] = c;
537 if(c == '\n') break;
538 }
539 (*pbuf)[i] = '\0';
540 return i;
541}