Bug Summary

File:save.c
Location:line 297, column 14
Description:Branch condition evaluates to a garbage value

Annotated Source Code

1/******************************************************************************
2
3Copyright 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Author: Ralph Mor, X Consortium
26******************************************************************************/
27
28#include "smproxy.h"
29#ifdef HAVE_MKSTEMP1
30#include <unistd.h>
31#endif
32
33
34static ProxyFileEntry *proxyFileHead = NULL((void*)0);
35
36static int write_byte ( FILE *file, unsigned char b );
37static int write_short ( FILE *file, unsigned short s );
38static int write_counted_string ( FILE *file, char *string );
39static int read_byte ( FILE *file, unsigned char *bp );
40static int read_short ( FILE *file, unsigned short *shortp );
41static int read_counted_string ( FILE *file, char **stringp );
42
43#ifndef HAVE_ASPRINTF1
44# include <stdarg.h>
45
46/* sprintf variant found in newer libc's which allocates string to print to */
47_X_HIDDEN__attribute__((visibility("hidden"))) int _X_ATTRIBUTE_PRINTF(2,3)__attribute__((__format__(__printf__,2,3)))
48asprintf(char ** ret, const char *format, ...)
49{
50 char buf[256];
51 int len;
52 va_list ap;
53
54 va_start(ap, format);
55 len = vsnprintf(buf, sizeof(buf), format, ap)__builtin___vsnprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1 ? 1 : 0), format, ap)
;
56 va_end(ap);
57
58 if (len < 0)
59 return -1;
60
61 if (len < sizeof(buf))
62 {
63 *ret = strdup(buf);
64 }
65 else
66 {
67 *ret = malloc(len + 1); /* snprintf doesn't count trailing '\0' */
68 if (*ret != NULL((void*)0))
69 {
70 va_start(ap, format);
71 len = vsnprintf(*ret, len + 1, format, ap)__builtin___vsnprintf_chk (*ret, len + 1, 0, __builtin_object_size
(*ret, 2 > 1 ? 1 : 0), format, ap)
;
72 va_end(ap);
73 if (len < 0) {
74 free(*ret);
75 *ret = NULL((void*)0);
76 }
77 }
78 }
79
80 if (*ret == NULL((void*)0))
81 return -1;
82
83 return len;
84}
85#endif
86
87
88
89static int
90write_byte (FILE *file, unsigned char b)
91{
92 if (fwrite ((char *) &b, 1, 1, file) != 1)
93 return 0;
94 return 1;
95}
96
97
98static int
99write_short (FILE *file, unsigned short s)
100{
101 unsigned char file_short[2];
102
103 file_short[0] = (s & (unsigned)0xff00) >> 8;
104 file_short[1] = s & 0xff;
105 if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
106 return 0;
107 return 1;
108}
109
110
111static int
112write_counted_string(FILE *file, char *string)
113{
114 if (string)
115 {
116 unsigned char count = strlen (string);
117
118 if (write_byte (file, count) == 0)
119 return 0;
120 if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
121 return 0;
122 }
123 else
124 {
125 if (write_byte (file, 0) == 0)
126 return 0;
127 }
128
129 return 1;
130}
131
132
133
134static int
135read_byte(FILE *file, unsigned char *bp)
136{
137 if (fread ((char *) bp, 1, 1, file) != 1)
138 return 0;
139 return 1;
140}
141
142
143static int
144read_short(FILE *file, unsigned short *shortp)
145{
146 unsigned char file_short[2];
147
148 if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
149 return 0;
150 *shortp = file_short[0] * 256 + file_short[1];
151 return 1;
152}
153
154
155static int
156read_counted_string(FILE *file, char **stringp)
157{
158 unsigned char len;
159 char *data;
160
161 if (read_byte (file, &len) == 0)
162 return 0;
163 if (len == 0) {
164 data = NULL((void*)0);
165 } else {
166 data = (char *) malloc ((unsigned) len + 1);
167 if (!data)
168 return 0;
169 if (fread (data, (int) sizeof (char), (int) len, file) != len) {
170 free (data);
171 return 0;
172 }
173 data[len] = '\0';
174 }
175 *stringp = data;
176 return 1;
177}
178
179
180
181/*
182 * An entry in the .smproxy file looks like this:
183 *
184 * FIELD BYTES
185 * ----- ----
186 * client ID len 1
187 * client ID LIST of bytes
188 * WM_CLASS "res name" length 1
189 * WM_CLASS "res name" LIST of bytes
190 * WM_CLASS "res class" length 1
191 * WM_CLASS "res class" LIST of bytes
192 * WM_NAME length 1
193 * WM_NAME LIST of bytes
194 * WM_COMMAND arg count 1
195 * For each arg in WM_COMMAND
196 * arg length 1
197 * arg LIST of bytes
198 */
199
200int
201WriteProxyFileEntry(FILE *proxyFile, WinInfo *theWindow)
202{
203 int i;
204
205 if (!write_counted_string (proxyFile, theWindow->client_id))
206 return 0;
207 if (!write_counted_string (proxyFile, theWindow->class.res_name))
208 return 0;
209 if (!write_counted_string (proxyFile, theWindow->class.res_class))
210 return 0;
211 if (!write_counted_string (proxyFile, theWindow->wm_name))
212 return 0;
213
214 if (!theWindow->wm_command || theWindow->wm_command_count == 0)
215 {
216 if (!write_byte (proxyFile, 0))
217 return 0;
218 }
219 else
220 {
221 if (!write_byte (proxyFile, (char) theWindow->wm_command_count))
222 return 0;
223 for (i = 0; i < theWindow->wm_command_count; i++)
224 if (!write_counted_string (proxyFile, theWindow->wm_command[i]))
225 return 0;
226 }
227
228 return 1;
229}
230
231
232int
233ReadProxyFileEntry(FILE *proxyFile, ProxyFileEntry **pentry)
234{
235 ProxyFileEntry *entry;
236 unsigned char byte;
237 int i;
238
239 *pentry = entry = (ProxyFileEntry *) malloc (
240 sizeof (ProxyFileEntry));
241 if (!*pentry)
7
Taking false branch
242 return 0;
243
244 entry->tag = 0;
245 entry->client_id = NULL((void*)0);
246 entry->class.res_name = NULL((void*)0);
247 entry->class.res_class = NULL((void*)0);
248 entry->wm_name = NULL((void*)0);
249 entry->wm_command = NULL((void*)0);
250 entry->wm_command_count = 0;
251
252 if (!read_counted_string (proxyFile, &entry->client_id))
8
Taking false branch
253 goto give_up;
254 if (!read_counted_string (proxyFile, &entry->class.res_name))
9
Taking false branch
255 goto give_up;
256 if (!read_counted_string (proxyFile, &entry->class.res_class))
10
Taking false branch
257 goto give_up;
258 if (!read_counted_string (proxyFile, &entry->wm_name))
11
Taking false branch
259 goto give_up;
260
261 if (!read_byte (proxyFile, &byte))
12
Taking false branch
262 goto give_up;
263 entry->wm_command_count = byte;
264
265 if (entry->wm_command_count == 0)
13
Taking false branch
266 entry->wm_command = NULL((void*)0);
267 else
268 {
269 entry->wm_command = (char **) malloc (entry->wm_command_count *
270 sizeof (char *));
271
272 if (!entry->wm_command)
14
Taking false branch
273 goto give_up;
274
275 for (i = 0; i < entry->wm_command_count; i++)
15
Loop condition is true. Entering loop body
276 if (!read_counted_string (proxyFile, &entry->wm_command[i]))
16
Taking true branch
277 goto give_up;
17
Control jumps to line 284
278 }
279
280 return 1;
281
282give_up:
283
284 if (entry->client_id)
18
Taking true branch
285 free (entry->client_id);
286 if (entry->class.res_name)
19
Taking false branch
287 free (entry->class.res_name);
288 if (entry->class.res_class)
20
Taking false branch
289 free (entry->class.res_class);
290 if (entry->wm_name)
21
Taking false branch
291 free (entry->wm_name);
292 if (entry->wm_command)
22
Taking true branch
293 {
294 if (entry->wm_command_count)
23
Taking true branch
295 {
296 for (i = 0; i < entry->wm_command_count; i++)
24
Loop condition is true. Entering loop body
297 if (entry->wm_command[i])
25
Branch condition evaluates to a garbage value
298 free (entry->wm_command[i]);
299 }
300 free ((char *) entry->wm_command);
301 }
302
303 free ((char *) entry);
304 *pentry = NULL((void*)0);
305
306 return 0;
307}
308
309
310void
311ReadProxyFile(char *filename)
312{
313 FILE *proxyFile;
314 ProxyFileEntry *entry;
315 int done = 0;
316 unsigned short version;
317
318 proxyFile = fopen (filename, "rb");
319 if (!proxyFile)
1
Assuming 'proxyFile' is non-null
2
Taking false branch
320 return;
321
322 if (!read_short (proxyFile, &version) ||
4
Taking false branch
323 version > SAVEFILE_VERSION1)
3
Assuming 'version' is <= 1
324 {
325 done = 1;
326 }
327
328 while (!done)
5
Loop condition is true. Entering loop body
329 {
330 if (ReadProxyFileEntry (proxyFile, &entry))
6
Calling 'ReadProxyFileEntry'
331 {
332 entry->next = proxyFileHead;
333 proxyFileHead = entry;
334 }
335 else
336 done = 1;
337 }
338
339 fclose (proxyFile);
340}
341
342
343
344static char *
345unique_filename(const char *path, const char *prefix, int *pFd)
346{
347 char *tempFile = NULL((void*)0);
348 int tempFd = 0;
349
350#if defined(HAVE_MKSTEMP1) || defined(HAVE_MKTEMP1)
351 if (asprintf (&tempFile, "%s/%sXXXXXX", path, prefix) == -1)
352 return NULL((void*)0);
353#endif
354
355#ifdef HAVE_MKSTEMP1
356 tempFd = mkstemp(tempFile);
357#else
358
359# ifdef HAVE_MKTEMP1
360 if (mktemp(tempFile) == NULL((void*)0))
361 tempFd = -1;
362# else /* fallback to tempnam */
363 tempFile = tempnam (path, prefix);
364# endif /* HAVE_MKTEMP */
365
366 if (tempFd != -1 && tempFile != NULL((void*)0))
367 tempFd = open(tempFile, O_RDWR | O_CREAT | O_EXCL, 0600);
368#endif
369
370 if (tempFd == -1) {
371 free(tempFile);
372 return (NULL((void*)0));
373 }
374
375 *pFd = tempFd;
376 return tempFile;
377
378}
379
380
381
382char *
383WriteProxyFile(void)
384{
385 FILE *proxyFile = NULL((void*)0);
386 char *filename = NULL((void*)0);
387 int fd = -1;
388 const char *path;
389 WinInfo *winptr;
390 Boolint success = False0;
391
392 path = getenv ("SM_SAVE_DIR");
393 if (!path)
394 {
395 path = getenv ("HOME");
396 if (!path)
397 path = ".";
398 }
399
400 if ((filename = unique_filename (path, ".prx", &fd)) == NULL((void*)0))
401 goto bad;
402
403 if (!(proxyFile = fdopen(fd, "wb")))
404 goto bad;
405
406 if (!write_short (proxyFile, SAVEFILE_VERSION1))
407 goto bad;
408
409 success = True1;
410 winptr = win_head;
411
412 while (winptr && success)
413 {
414 if (winptr->client_id)
415 if (!WriteProxyFileEntry (proxyFile, winptr))
416 {
417 success = False0;
418 break;
419 }
420
421 winptr = winptr->next;
422 }
423
424 bad:
425
426 if (proxyFile)
427 fclose (proxyFile);
428 else if (fd != -1)
429 close (fd);
430
431 if (success)
432 return (filename);
433 else
434 {
435 if (filename)
436 free (filename);
437 return (NULL((void*)0));
438 }
439}
440
441
442
443char *
444LookupClientID(WinInfo *theWindow)
445{
446 ProxyFileEntry *ptr;
447 int found = 0;
448
449 ptr = proxyFileHead;
450 while (ptr && !found)
451 {
452 if (!ptr->tag &&
453 strcmp (theWindow->class.res_name, ptr->class.res_name) == 0 &&
454 strcmp (theWindow->class.res_class, ptr->class.res_class) == 0 &&
455 strcmp (theWindow->wm_name, ptr->wm_name) == 0)
456 {
457 int i;
458
459 if (theWindow->wm_command_count == ptr->wm_command_count)
460 {
461 for (i = 0; i < theWindow->wm_command_count; i++)
462 if (strcmp (theWindow->wm_command[i],
463 ptr->wm_command[i]) != 0)
464 break;
465
466 if (i == theWindow->wm_command_count)
467 found = 1;
468 }
469 }
470
471 if (!found)
472 ptr = ptr->next;
473 }
474
475 if (found)
476 {
477 ptr->tag = 1;
478 return (ptr->client_id);
479 }
480 else
481 return NULL((void*)0);
482}