Bug Summary

File:/home/joel/rtems-4.11-work/build/rtems/c/src/../../cpukit/zlib/gzlib.c
Location:line 176, column 9
Description:Allocated memory never released. Potential memory leak

Annotated Source Code

1/* gzlib.c -- zlib functions common to reading and writing gzip files
2 * Copyright (C) 2004, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include "gzguts.h"
7
8#ifdef _LARGEFILE64_SOURCE
9# define LSEEKlseek lseek64
10#else
11# define LSEEKlseek lseek
12#endif
13
14/* Local functions */
15localstatic void gz_reset OF((gz_statep))(gz_statep);
16localstatic gzFilez_gzFile gz_open OF((const char *, int, const char *))(const char *, int, const char *);
17
18#if defined UNDER_CE && defined NO_ERRNO_H
19
20/* Map the Windows error number in ERROR to a locale-dependent error message
21 string and return a pointer to it. Typically, the values for ERROR come
22 from GetLastError.
23
24 The string pointed to shall not be modified by the application, but may be
25 overwritten by a subsequent call to gz_strwinerror
26
27 The gz_strwinerror function does not change the current setting of
28 GetLastError. */
29char ZEXPORT *gz_strwinerrorz_gz_strwinerror (error)
30 DWORD error;
31{
32 static char buf[1024];
33
34 wchar_t *msgbuf;
35 DWORD lasterr = GetLastError();
36 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
37 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
38 NULL((void*)0),
39 error,
40 0, /* Default language */
41 (LPVOID)&msgbuf,
42 0,
43 NULL((void*)0));
44 if (chars != 0) {
45 /* If there is an \r\n appended, zap it. */
46 if (chars >= 2
47 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
48 chars -= 2;
49 msgbuf[chars] = 0;
50 }
51
52 if (chars > sizeof (buf) - 1) {
53 chars = sizeof (buf) - 1;
54 msgbuf[chars] = 0;
55 }
56
57 wcstombs(buf, msgbuf, chars + 1);
58 LocalFree(msgbuf);
59 }
60 else {
61 sprintf(buf, "unknown win32 error (%ld)", error);
62 }
63
64 SetLastError(lasterr);
65 return buf;
66}
67
68#endif /* UNDER_CE && NO_ERRNO_H */
69
70/* Reset gzip file state */
71localstatic void gz_reset(state)
72 gz_statep state;
73{
74 if (state->mode == GZ_READ7247) { /* for reading ... */
75 state->have = 0; /* no output data available */
76 state->eof = 0; /* not at end of file */
77 state->how = LOOK0; /* look for gzip header */
78 state->direct = 1; /* default for empty file */
79 }
80 state->seek = 0; /* no seek request pending */
81 gz_errorz_gz_error(state, Z_OK0, NULL((void*)0)); /* clear error */
82 state->pos = 0; /* no uncompressed data yet */
83 state->strm.avail_in = 0; /* no input data yet */
84}
85
86/* Open a gzip file either by name or file descriptor. */
87localstatic gzFilez_gzFile gz_open(path, fd, mode)
88 const char *path;
89 int fd;
90 const char *mode;
91{
92 gz_statep state;
93
94 /* allocate gzFile structure to return */
95 state = malloc(sizeof(gz_state));
96 if (state == NULL((void*)0))
1
Taking false branch
97 return NULL((void*)0);
98 state->size = 0; /* no buffers allocated yet */
99 state->want = GZBUFSIZE8192; /* requested buffer size */
100 state->msg = NULL((void*)0); /* no error message yet */
101
102 /* interpret mode */
103 state->mode = GZ_NONE0;
104 state->level = Z_DEFAULT_COMPRESSION(-1);
105 state->strategy = Z_DEFAULT_STRATEGY0;
106 while (*mode) {
2
Loop condition is true. Entering loop body
6
Loop condition is false. Execution continues on line 145
107 if (*mode >= '0' && *mode <= '9')
3
Taking false branch
108 state->level = *mode - '0';
109 else
110 switch (*mode) {
4
Control jumps to 'case 114:' at line 111
111 case 'r':
112 state->mode = GZ_READ7247;
113 break;
5
Execution continues on line 141
114#ifndef NO_GZCOMPRESS
115 case 'w':
116 state->mode = GZ_WRITE31153;
117 break;
118 case 'a':
119 state->mode = GZ_APPEND1;
120 break;
121#endif
122 case '+': /* can't read and write at the same time */
123 free(state);
124 return NULL((void*)0);
125 case 'b': /* ignore -- will request binary anyway */
126 break;
127 case 'f':
128 state->strategy = Z_FILTERED1;
129 break;
130 case 'h':
131 state->strategy = Z_HUFFMAN_ONLY2;
132 break;
133 case 'R':
134 state->strategy = Z_RLE3;
135 break;
136 case 'F':
137 state->strategy = Z_FIXED4;
138 default: /* could consider as an error, but just ignore */
139 ;
140 }
141 mode++;
142 }
143
144 /* must provide an "r", "w", or "a" */
145 if (state->mode == GZ_NONE0) {
7
Taking false branch
146 free(state);
147 return NULL((void*)0);
148 }
149
150 /* save the path name for error messages */
151 state->path = malloc(strlen(path) + 1);
152 if (state->path == NULL((void*)0)) {
8
Taking false branch
153 free(state);
154 return NULL((void*)0);
155 }
156 strcpy(state->path, path);
157
158 /* open the file with the appropriate mode (or just use fd) */
159 state->fd = fd != -1 ? fd :
9
'?' condition is false
160 open(path,
161#ifdef O_LARGEFILE
162 O_LARGEFILE |
163#endif
164#ifdef O_BINARY
165 O_BINARY |
166#endif
167 (state->mode == GZ_READ7247 ?
10
'?' condition is true
168 O_RDONLY00 :
169 (O_WRONLY01 | O_CREAT0100 | (
170 state->mode == GZ_WRITE31153 ?
171 O_TRUNC01000 :
172 O_APPEND02000))),
173 0666);
174 if (state->fd == -1) {
11
Taking true branch
175 free(state);
176 return NULL((void*)0);
12
Allocated memory never released. Potential memory leak
177 }
178 if (state->mode == GZ_APPEND1)
179 state->mode = GZ_WRITE31153; /* simplify later checks */
180
181 /* save the current position for rewinding (only if reading) */
182 if (state->mode == GZ_READ7247) {
183 state->start = LSEEKlseek(state->fd, 0, SEEK_CUR1);
184 if (state->start == -1) state->start = 0;
185 }
186
187 /* initialize stream */
188 gz_reset(state);
189
190 /* return stream */
191 return (gzFilez_gzFile)state;
192}
193
194/* -- see zlib.h -- */
195gzFilez_gzFile ZEXPORT gzopenz_gzopen(path, mode)
196 const char *path;
197 const char *mode;
198{
199 return gz_open(path, -1, mode);
200}
201
202#if (defined(_LARGEFILE64_SOURCE)||(_FILE_OFFSET_BITS == 64))
203/* -- see zlib.h -- */
204gzFilez_gzFile ZEXPORT gzopen64z_gzopen64(path, mode)
205 const char *path;
206 const char *mode;
207{
208 return gz_open(path, -1, mode);
209}
210#endif /* (defined(_LARGEFILE64_SOURCE)||(_FILE_OFFSET_BITS == 64)) */
211
212/* -- see zlib.h -- */
213gzFilez_gzFile ZEXPORT gzdopenz_gzdopen(fd, mode)
214 int fd;
215 const char *mode;
216{
217 char *path; /* identifier for error messages */
218 gzFilez_gzFile gz;
219
220 if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL((void*)0))
221 return NULL((void*)0);
222 sprintf(path, "<fd:%d>", fd);
223 gz = gz_open(path, fd, mode);
224 free(path);
225 return gz;
226}
227
228/* -- see zlib.h -- */
229int ZEXPORT gzbufferz_gzbuffer(file, size)
230 gzFilez_gzFile file;
231 unsigned size;
232{
233 gz_statep state;
234
235 /* get internal structure and check integrity */
236 if (file == NULL((void*)0))
237 return -1;
238 state = (gz_statep)file;
239 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
240 return -1;
241
242 /* make sure we haven't already allocated memory */
243 if (state->size != 0)
244 return -1;
245
246 /* check and set requested size */
247 if (size == 0)
248 return -1;
249 state->want = size;
250 return 0;
251}
252
253/* -- see zlib.h -- */
254int ZEXPORT gzrewindz_gzrewind(file)
255 gzFilez_gzFile file;
256{
257 gz_statep state;
258
259 /* get internal structure */
260 if (file == NULL((void*)0))
261 return -1;
262 state = (gz_statep)file;
263
264 /* check that we're reading and that there's no error */
265 if (state->mode != GZ_READ7247 || state->err != Z_OK0)
266 return -1;
267
268 /* back up and start over */
269 if (LSEEKlseek(state->fd, state->start, SEEK_SET0) == -1)
270 return -1;
271 gz_reset(state);
272 return 0;
273}
274
275/* -- see zlib.h -- */
276z_off64_toff_t ZEXPORT gzseek64z_gzseek64(file, offset, whence)
277 gzFilez_gzFile file;
278 z_off64_toff_t offset;
279 int whence;
280{
281 unsigned n;
282 z_off64_toff_t ret;
283 gz_statep state;
284
285 /* get internal structure and check integrity */
286 if (file == NULL((void*)0))
287 return -1;
288 state = (gz_statep)file;
289 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
290 return -1;
291
292 /* check that there's no error */
293 if (state->err != Z_OK0)
294 return -1;
295
296 /* can only seek from start or relative to current position */
297 if (whence != SEEK_SET0 && whence != SEEK_CUR1)
298 return -1;
299
300 /* normalize offset to a SEEK_CUR specification */
301 if (whence == SEEK_SET0)
302 offset -= state->pos;
303 else if (state->seek)
304 offset += state->skip;
305 state->seek = 0;
306
307 /* if within raw area while reading, just go there */
308 if (state->mode == GZ_READ7247 && state->how == COPY1 &&
309 state->pos + offset >= state->raw) {
310 ret = LSEEKlseek(state->fd, offset, SEEK_CUR1);
311 if (ret == -1)
312 return -1;
313 state->have = 0;
314 state->eof = 0;
315 state->seek = 0;
316 gz_errorz_gz_error(state, Z_OK0, NULL((void*)0));
317 state->strm.avail_in = 0;
318 state->pos += offset;
319 return state->pos;
320 }
321
322 /* calculate skip amount, rewinding if needed for back seek when reading */
323 if (offset < 0) {
324 if (state->mode != GZ_READ7247) /* writing -- can't go backwards */
325 return -1;
326 offset += state->pos;
327 if (offset < 0) /* before start of file! */
328 return -1;
329 if (gzrewindz_gzrewind(file) == -1) /* rewind, then skip to offset */
330 return -1;
331 }
332
333 /* if reading, skip what's in output buffer (one less gzgetc() check) */
334 if (state->mode == GZ_READ7247) {
335 n = GT_OFF(state->have)(sizeof(int) == sizeof(off_t) && (state->have) >
2147483647)
|| (z_off64_toff_t)state->have > offset ?
336 (unsigned)offset : state->have;
337 state->have -= n;
338 state->next += n;
339 state->pos += n;
340 offset -= n;
341 }
342
343 /* request skip (if not zero) */
344 if (offset) {
345 state->seek = 1;
346 state->skip = offset;
347 }
348 return state->pos + offset;
349}
350
351/* -- see zlib.h -- */
352z_off_toff_t ZEXPORT gzseekz_gzseek(file, offset, whence)
353 gzFilez_gzFile file;
354 z_off_toff_t offset;
355 int whence;
356{
357 z_off64_toff_t ret;
358
359 ret = gzseek64z_gzseek64(file, (z_off64_toff_t)offset, whence);
360 return ret == (z_off_toff_t)ret ? (z_off_toff_t)ret : -1;
361}
362
363/* -- see zlib.h -- */
364z_off64_toff_t ZEXPORT gztell64z_gztell64(file)
365 gzFilez_gzFile file;
366{
367 gz_statep state;
368
369 /* get internal structure and check integrity */
370 if (file == NULL((void*)0))
371 return -1;
372 state = (gz_statep)file;
373 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
374 return -1;
375
376 /* return position */
377 return state->pos + (state->seek ? state->skip : 0);
378}
379
380/* -- see zlib.h -- */
381z_off_toff_t ZEXPORT gztellz_gztell(file)
382 gzFilez_gzFile file;
383{
384 z_off64_toff_t ret;
385
386 ret = gztell64z_gztell64(file);
387 return ret == (z_off_toff_t)ret ? (z_off_toff_t)ret : -1;
388}
389
390/* -- see zlib.h -- */
391
392z_off64_toff_t ZEXPORT gzoffset64z_gzoffset64(file)
393 gzFilez_gzFile file;
394{
395 z_off64_toff_t offset;
396 gz_statep state;
397
398 /* get internal structure and check integrity */
399 if (file == NULL((void*)0))
400 return -1;
401 state = (gz_statep)file;
402 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
403 return -1;
404
405 /* compute and return effective offset in file */
406 offset = LSEEKlseek(state->fd, 0, SEEK_CUR1);
407 if (offset == -1)
408 return -1;
409 if (state->mode == GZ_READ7247) /* reading */
410 offset -= state->strm.avail_in; /* don't count buffered input */
411 return offset;
412}
413
414/* -- see zlib.h -- */
415z_off_toff_t ZEXPORT gzoffsetz_gzoffset(file)
416 gzFilez_gzFile file;
417{
418 z_off64_toff_t ret;
419
420 ret = gzoffset64z_gzoffset64(file);
421 return ret == (z_off_toff_t)ret ? (z_off_toff_t)ret : -1;
422}
423
424/* -- see zlib.h -- */
425int ZEXPORT gzeofz_gzeof(file)
426 gzFilez_gzFile file;
427{
428 gz_statep state;
429
430 /* get internal structure and check integrity */
431 if (file == NULL((void*)0))
432 return 0;
433 state = (gz_statep)file;
434 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
435 return 0;
436
437 /* return end-of-file state */
438 return state->mode == GZ_READ7247 ? (state->eof && state->have == 0) : 0;
439}
440
441/* -- see zlib.h -- */
442const char * ZEXPORT gzerrorz_gzerror(file, errnum)
443 gzFilez_gzFile file;
444 int *errnum;
445{
446 gz_statep state;
447
448 /* get internal structure and check integrity */
449 if (file == NULL((void*)0))
450 return NULL((void*)0);
451 state = (gz_statep)file;
452 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
453 return NULL((void*)0);
454
455 /* return error information */
456 if (errnum != NULL((void*)0))
457 *errnum = state->err;
458 return state->msg == NULL((void*)0) ? "" : state->msg;
459}
460
461/* -- see zlib.h -- */
462void ZEXPORT gzclearerrz_gzclearerr(file)
463 gzFilez_gzFile file;
464{
465 gz_statep state;
466
467 /* get internal structure and check integrity */
468 if (file == NULL((void*)0))
469 return;
470 state = (gz_statep)file;
471 if (state->mode != GZ_READ7247 && state->mode != GZ_WRITE31153)
472 return;
473
474 /* clear error and end-of-file */
475 if (state->mode == GZ_READ7247)
476 state->eof = 0;
477 gz_errorz_gz_error(state, Z_OK0, NULL((void*)0));
478}
479
480/* Create an error message in allocated memory and set state->err and
481 state->msg accordingly. Free any previous error message already there. Do
482 not try to free or allocate space if the error is Z_MEM_ERROR (out of
483 memory). Simply save the error message as a static string. If there is an
484 allocation failure constructing the error message, then convert the error to
485 out of memory. */
486void ZEXPORT gz_errorz_gz_error(state, err, msg)
487 gz_statep state;
488 int err;
489 const char *msg;
490{
491 /* free previously allocated message and clear */
492 if (state->msg != NULL((void*)0)) {
493 if (state->err != Z_MEM_ERROR(-4))
494 free(state->msg);
495 state->msg = NULL((void*)0);
496 }
497
498 /* set error code, and if no message, then done */
499 state->err = err;
500 if (msg == NULL((void*)0))
501 return;
502
503 /* for an out of memory error, save as static string */
504 if (err == Z_MEM_ERROR(-4)) {
505 state->msg = (char *)msg;
506 return;
507 }
508
509 /* construct error message with path */
510 if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL((void*)0)) {
511 state->err = Z_MEM_ERROR(-4);
512 state->msg = (char *)"out of memory";
513 return;
514 }
515 strcpy(state->msg, state->path);
516 strcat(state->msg, ": ");
517 strcat(state->msg, msg);
518 return;
519}
520
521#ifndef INT_MAX2147483647
522/* portably return maximum value for an int (when limits.h presumed not
523 available) -- we need to do this to cover cases where 2's complement not
524 used, since C standard permits 1's complement and sign-bit representations,
525 otherwise we could just use ((unsigned)-1) >> 1 */
526unsigned ZEXPORT gz_intmaxz_gz_intmax()
527{
528 unsigned p, q;
529
530 p = 1;
531 do {
532 q = p;
533 p <<= 1;
534 p++;
535 } while (p > q);
536 return q >> 1;
537}
538#endif