new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / external / zlib-1.2.11 / gzlib.c
1 /* gzlib.c -- zlib functions common to reading and writing gzip files
2  * Copyright (C) 2004-2017 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5
6 #include "gzguts.h"
7
8 #if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
9 #  define LSEEK _lseeki64
10 #else
11 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
12 #  define LSEEK lseek64
13 #else
14 #  define LSEEK lseek
15 #endif
16 #endif
17
18 /* Local functions */
19 local void gz_reset OF((gz_statep));
20 local gzFile gz_open OF((const void *, int, const char *));
21
22 #if defined UNDER_CE
23
24 /* Map the Windows error number in ERROR to a locale-dependent error message
25    string and return a pointer to it.  Typically, the values for ERROR come
26    from GetLastError.
27
28    The string pointed to shall not be modified by the application, but may be
29    overwritten by a subsequent call to gz_strwinerror
30
31    The gz_strwinerror function does not change the current setting of
32    GetLastError. */
33 char ZLIB_INTERNAL *gz_strwinerror (error)
34      DWORD error;
35 {
36     static char buf[1024];
37
38     wchar_t *msgbuf;
39     DWORD lasterr = GetLastError();
40     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
41         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
42         NULL,
43         error,
44         0, /* Default language */
45         (LPVOID)&msgbuf,
46         0,
47         NULL);
48     if (chars != 0) {
49         /* If there is an \r\n appended, zap it.  */
50         if (chars >= 2
51             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
52             chars -= 2;
53             msgbuf[chars] = 0;
54         }
55
56         if (chars > sizeof (buf) - 1) {
57             chars = sizeof (buf) - 1;
58             msgbuf[chars] = 0;
59         }
60
61         wcstombs(buf, msgbuf, chars + 1);
62         LocalFree(msgbuf);
63     }
64     else {
65         sprintf(buf, "unknown win32 error (%ld)", error);
66     }
67
68     SetLastError(lasterr);
69     return buf;
70 }
71
72 #endif /* UNDER_CE */
73
74 /* Reset gzip file state */
75 local void gz_reset(state)
76     gz_statep state;
77 {
78     state->x.have = 0;              /* no output data available */
79     if (state->mode == GZ_READ) {   /* for reading ... */
80         state->eof = 0;             /* not at end of file */
81         state->past = 0;            /* have not read past end yet */
82         state->how = LOOK;          /* look for gzip header */
83     }
84     state->seek = 0;                /* no seek request pending */
85     gz_error(state, Z_OK, NULL);    /* clear error */
86     state->x.pos = 0;               /* no uncompressed data yet */
87     state->strm.avail_in = 0;       /* no input data yet */
88 }
89
90 /* Open a gzip file either by name or file descriptor. */
91 local gzFile gz_open(path, fd, mode)
92     const void *path;
93     int fd;
94     const char *mode;
95 {
96     gz_statep state;
97     z_size_t len;
98     int oflag;
99 #ifdef O_CLOEXEC
100     int cloexec = 0;
101 #endif
102 #ifdef O_EXCL
103     int exclusive = 0;
104 #endif
105
106     /* check input */
107     if (path == NULL)
108         return NULL;
109
110     /* allocate gzFile structure to return */
111     state = (gz_statep)malloc(sizeof(gz_state));
112     if (state == NULL)
113         return NULL;
114     state->size = 0;            /* no buffers allocated yet */
115     state->want = GZBUFSIZE;    /* requested buffer size */
116     state->msg = NULL;          /* no error message yet */
117
118     /* interpret mode */
119     state->mode = GZ_NONE;
120     state->level = Z_DEFAULT_COMPRESSION;
121     state->strategy = Z_DEFAULT_STRATEGY;
122     state->direct = 0;
123     while (*mode) {
124         if (*mode >= '0' && *mode <= '9')
125             state->level = *mode - '0';
126         else
127             switch (*mode) {
128             case 'r':
129                 state->mode = GZ_READ;
130                 break;
131 #ifndef NO_GZCOMPRESS
132             case 'w':
133                 state->mode = GZ_WRITE;
134                 break;
135             case 'a':
136                 state->mode = GZ_APPEND;
137                 break;
138 #endif
139             case '+':       /* can't read and write at the same time */
140                 free(state);
141                 return NULL;
142             case 'b':       /* ignore -- will request binary anyway */
143                 break;
144 #ifdef O_CLOEXEC
145             case 'e':
146                 cloexec = 1;
147                 break;
148 #endif
149 #ifdef O_EXCL
150             case 'x':
151                 exclusive = 1;
152                 break;
153 #endif
154             case 'f':
155                 state->strategy = Z_FILTERED;
156                 break;
157             case 'h':
158                 state->strategy = Z_HUFFMAN_ONLY;
159                 break;
160             case 'R':
161                 state->strategy = Z_RLE;
162                 break;
163             case 'F':
164                 state->strategy = Z_FIXED;
165                 break;
166             case 'T':
167                 state->direct = 1;
168                 break;
169             default:        /* could consider as an error, but just ignore */
170                 ;
171             }
172         mode++;
173     }
174
175     /* must provide an "r", "w", or "a" */
176     if (state->mode == GZ_NONE) {
177         free(state);
178         return NULL;
179     }
180
181     /* can't force transparent read */
182     if (state->mode == GZ_READ) {
183         if (state->direct) {
184             free(state);
185             return NULL;
186         }
187         state->direct = 1;      /* for empty file */
188     }
189
190     /* save the path name for error messages */
191 #ifdef WIDECHAR
192     if (fd == -2) {
193         len = wcstombs(NULL, path, 0);
194         if (len == (z_size_t)-1)
195             len = 0;
196     }
197     else
198 #endif
199         len = strlen((const char *)path);
200     state->path = (char *)malloc(len + 1);
201     if (state->path == NULL) {
202         free(state);
203         return NULL;
204     }
205 #ifdef WIDECHAR
206     if (fd == -2)
207         if (len)
208             wcstombs(state->path, path, len + 1);
209         else
210             *(state->path) = 0;
211     else
212 #endif
213 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
214         (void)snprintf(state->path, len + 1, "%s", (const char *)path);
215 #else
216         strcpy(state->path, path);
217 #endif
218
219     /* compute the flags for open() */
220     oflag =
221 #ifdef O_LARGEFILE
222         O_LARGEFILE |
223 #endif
224 #ifdef O_BINARY
225         O_BINARY |
226 #endif
227 #ifdef O_CLOEXEC
228         (cloexec ? O_CLOEXEC : 0) |
229 #endif
230         (state->mode == GZ_READ ?
231          O_RDONLY :
232          (O_WRONLY | O_CREAT |
233 #ifdef O_EXCL
234           (exclusive ? O_EXCL : 0) |
235 #endif
236           (state->mode == GZ_WRITE ?
237            O_TRUNC :
238            O_APPEND)));
239
240     /* open the file with the appropriate flags (or just use fd) */
241     state->fd = fd > -1 ? fd : (
242 #ifdef WIDECHAR
243         fd == -2 ? _wopen(path, oflag, 0666) :
244 #endif
245         open((const char *)path, oflag, 0666));
246     if (state->fd == -1) {
247         free(state->path);
248         free(state);
249         return NULL;
250     }
251     if (state->mode == GZ_APPEND) {
252         LSEEK(state->fd, 0, SEEK_END);  /* so gzoffset() is correct */
253         state->mode = GZ_WRITE;         /* simplify later checks */
254     }
255
256     /* save the current position for rewinding (only if reading) */
257     if (state->mode == GZ_READ) {
258         state->start = LSEEK(state->fd, 0, SEEK_CUR);
259         if (state->start == -1) state->start = 0;
260     }
261
262     /* initialize stream */
263     gz_reset(state);
264
265     /* return stream */
266     return (gzFile)state;
267 }
268
269 /* -- see zlib.h -- */
270 gzFile ZEXPORT gzopen(path, mode)
271     const char *path;
272     const char *mode;
273 {
274     return gz_open(path, -1, mode);
275 }
276
277 /* -- see zlib.h -- */
278 gzFile ZEXPORT gzopen64(path, mode)
279     const char *path;
280     const char *mode;
281 {
282     return gz_open(path, -1, mode);
283 }
284
285 /* -- see zlib.h -- */
286 gzFile ZEXPORT gzdopen(fd, mode)
287     int fd;
288     const char *mode;
289 {
290     char *path;         /* identifier for error messages */
291     gzFile gz;
292
293     if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
294         return NULL;
295 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
296     (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
297 #else
298     sprintf(path, "<fd:%d>", fd);   /* for debugging */
299 #endif
300     gz = gz_open(path, fd, mode);
301     free(path);
302     return gz;
303 }
304
305 /* -- see zlib.h -- */
306 #ifdef WIDECHAR
307 gzFile ZEXPORT gzopen_w(path, mode)
308     const wchar_t *path;
309     const char *mode;
310 {
311     return gz_open(path, -2, mode);
312 }
313 #endif
314
315 /* -- see zlib.h -- */
316 int ZEXPORT gzbuffer(file, size)
317     gzFile file;
318     unsigned size;
319 {
320     gz_statep state;
321
322     /* get internal structure and check integrity */
323     if (file == NULL)
324         return -1;
325     state = (gz_statep)file;
326     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
327         return -1;
328
329     /* make sure we haven't already allocated memory */
330     if (state->size != 0)
331         return -1;
332
333     /* check and set requested size */
334     if ((size << 1) < size)
335         return -1;              /* need to be able to double it */
336     if (size < 2)
337         size = 2;               /* need two bytes to check magic header */
338     state->want = size;
339     return 0;
340 }
341
342 /* -- see zlib.h -- */
343 int ZEXPORT gzrewind(file)
344     gzFile file;
345 {
346     gz_statep state;
347
348     /* get internal structure */
349     if (file == NULL)
350         return -1;
351     state = (gz_statep)file;
352
353     /* check that we're reading and that there's no error */
354     if (state->mode != GZ_READ ||
355             (state->err != Z_OK && state->err != Z_BUF_ERROR))
356         return -1;
357
358     /* back up and start over */
359     if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
360         return -1;
361     gz_reset(state);
362     return 0;
363 }
364
365 /* -- see zlib.h -- */
366 z_off64_t ZEXPORT gzseek64(file, offset, whence)
367     gzFile file;
368     z_off64_t offset;
369     int whence;
370 {
371     unsigned n;
372     z_off64_t ret;
373     gz_statep state;
374
375     /* get internal structure and check integrity */
376     if (file == NULL)
377         return -1;
378     state = (gz_statep)file;
379     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
380         return -1;
381
382     /* check that there's no error */
383     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
384         return -1;
385
386     /* can only seek from start or relative to current position */
387     if (whence != SEEK_SET && whence != SEEK_CUR)
388         return -1;
389
390     /* normalize offset to a SEEK_CUR specification */
391     if (whence == SEEK_SET)
392         offset -= state->x.pos;
393     else if (state->seek)
394         offset += state->skip;
395     state->seek = 0;
396
397     /* if within raw area while reading, just go there */
398     if (state->mode == GZ_READ && state->how == COPY &&
399             state->x.pos + offset >= 0) {
400         ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
401         if (ret == -1)
402             return -1;
403         state->x.have = 0;
404         state->eof = 0;
405         state->past = 0;
406         state->seek = 0;
407         gz_error(state, Z_OK, NULL);
408         state->strm.avail_in = 0;
409         state->x.pos += offset;
410         return state->x.pos;
411     }
412
413     /* calculate skip amount, rewinding if needed for back seek when reading */
414     if (offset < 0) {
415         if (state->mode != GZ_READ)         /* writing -- can't go backwards */
416             return -1;
417         offset += state->x.pos;
418         if (offset < 0)                     /* before start of file! */
419             return -1;
420         if (gzrewind(file) == -1)           /* rewind, then skip to offset */
421             return -1;
422     }
423
424     /* if reading, skip what's in output buffer (one less gzgetc() check) */
425     if (state->mode == GZ_READ) {
426         n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
427             (unsigned)offset : state->x.have;
428         state->x.have -= n;
429         state->x.next += n;
430         state->x.pos += n;
431         offset -= n;
432     }
433
434     /* request skip (if not zero) */
435     if (offset) {
436         state->seek = 1;
437         state->skip = offset;
438     }
439     return state->x.pos + offset;
440 }
441
442 /* -- see zlib.h -- */
443 z_off_t ZEXPORT gzseek(file, offset, whence)
444     gzFile file;
445     z_off_t offset;
446     int whence;
447 {
448     z_off64_t ret;
449
450     ret = gzseek64(file, (z_off64_t)offset, whence);
451     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
452 }
453
454 /* -- see zlib.h -- */
455 z_off64_t ZEXPORT gztell64(file)
456     gzFile file;
457 {
458     gz_statep state;
459
460     /* get internal structure and check integrity */
461     if (file == NULL)
462         return -1;
463     state = (gz_statep)file;
464     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
465         return -1;
466
467     /* return position */
468     return state->x.pos + (state->seek ? state->skip : 0);
469 }
470
471 /* -- see zlib.h -- */
472 z_off_t ZEXPORT gztell(file)
473     gzFile file;
474 {
475     z_off64_t ret;
476
477     ret = gztell64(file);
478     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
479 }
480
481 /* -- see zlib.h -- */
482 z_off64_t ZEXPORT gzoffset64(file)
483     gzFile file;
484 {
485     z_off64_t offset;
486     gz_statep state;
487
488     /* get internal structure and check integrity */
489     if (file == NULL)
490         return -1;
491     state = (gz_statep)file;
492     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
493         return -1;
494
495     /* compute and return effective offset in file */
496     offset = LSEEK(state->fd, 0, SEEK_CUR);
497     if (offset == -1)
498         return -1;
499     if (state->mode == GZ_READ)             /* reading */
500         offset -= state->strm.avail_in;     /* don't count buffered input */
501     return offset;
502 }
503
504 /* -- see zlib.h -- */
505 z_off_t ZEXPORT gzoffset(file)
506     gzFile file;
507 {
508     z_off64_t ret;
509
510     ret = gzoffset64(file);
511     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
512 }
513
514 /* -- see zlib.h -- */
515 int ZEXPORT gzeof(file)
516     gzFile file;
517 {
518     gz_statep state;
519
520     /* get internal structure and check integrity */
521     if (file == NULL)
522         return 0;
523     state = (gz_statep)file;
524     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
525         return 0;
526
527     /* return end-of-file state */
528     return state->mode == GZ_READ ? state->past : 0;
529 }
530
531 /* -- see zlib.h -- */
532 const char * ZEXPORT gzerror(file, errnum)
533     gzFile file;
534     int *errnum;
535 {
536     gz_statep state;
537
538     /* get internal structure and check integrity */
539     if (file == NULL)
540         return NULL;
541     state = (gz_statep)file;
542     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
543         return NULL;
544
545     /* return error information */
546     if (errnum != NULL)
547         *errnum = state->err;
548     return state->err == Z_MEM_ERROR ? "out of memory" :
549                                        (state->msg == NULL ? "" : state->msg);
550 }
551
552 /* -- see zlib.h -- */
553 void ZEXPORT gzclearerr(file)
554     gzFile file;
555 {
556     gz_statep state;
557
558     /* get internal structure and check integrity */
559     if (file == NULL)
560         return;
561     state = (gz_statep)file;
562     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
563         return;
564
565     /* clear error and end-of-file */
566     if (state->mode == GZ_READ) {
567         state->eof = 0;
568         state->past = 0;
569     }
570     gz_error(state, Z_OK, NULL);
571 }
572
573 /* Create an error message in allocated memory and set state->err and
574    state->msg accordingly.  Free any previous error message already there.  Do
575    not try to free or allocate space if the error is Z_MEM_ERROR (out of
576    memory).  Simply save the error message as a static string.  If there is an
577    allocation failure constructing the error message, then convert the error to
578    out of memory. */
579 void ZLIB_INTERNAL gz_error(state, err, msg)
580     gz_statep state;
581     int err;
582     const char *msg;
583 {
584     /* free previously allocated message and clear */
585     if (state->msg != NULL) {
586         if (state->err != Z_MEM_ERROR)
587             free(state->msg);
588         state->msg = NULL;
589     }
590
591     /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
592     if (err != Z_OK && err != Z_BUF_ERROR)
593         state->x.have = 0;
594
595     /* set error code, and if no message, then done */
596     state->err = err;
597     if (msg == NULL)
598         return;
599
600     /* for an out of memory error, return literal string when requested */
601     if (err == Z_MEM_ERROR)
602         return;
603
604     /* construct error message with path */
605     if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
606             NULL) {
607         state->err = Z_MEM_ERROR;
608         return;
609     }
610 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
611     (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
612                    "%s%s%s", state->path, ": ", msg);
613 #else
614     strcpy(state->msg, state->path);
615     strcat(state->msg, ": ");
616     strcat(state->msg, msg);
617 #endif
618 }
619
620 #ifndef INT_MAX
621 /* portably return maximum value for an int (when limits.h presumed not
622    available) -- we need to do this to cover cases where 2's complement not
623    used, since C standard permits 1's complement and sign-bit representations,
624    otherwise we could just use ((unsigned)-1) >> 1 */
625 unsigned ZLIB_INTERNAL gz_intmax()
626 {
627     unsigned p, q;
628
629     p = 1;
630     do {
631         q = p;
632         p <<= 1;
633         p++;
634     } while (p > q);
635     return q >> 1;
636 }
637 #endif