blob: 4105e6aff92594fb9cfa557aa8349cea5a5d4a2b [file] [log] [blame]
gavinp@chromium.orgc1013302013-04-09 17:15:13 +00001/* gzlib.c -- zlib functions common to reading and writing gzip files
mark13dc2462017-02-14 22:15:29 -08002 * Copyright (C) 2004-2017 Mark Adler
gavinp@chromium.orgc1013302013-04-09 17:15:13 +00003 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include "gzguts.h"
7
mark13dc2462017-02-14 22:15:29 -08008#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
jiadong.zhu6c142162016-06-22 21:22:18 -07009# define LSEEK _lseeki64
10#else
11#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000012# define LSEEK lseek64
13#else
14# define LSEEK lseek
15#endif
jiadong.zhu6c142162016-06-22 21:22:18 -070016#endif
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000017
18/* Local functions */
19local void gz_reset OF((gz_statep));
jiadong.zhu6c142162016-06-22 21:22:18 -070020local gzFile gz_open OF((const void *, int, const char *));
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000021
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. */
33char 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 */
75local void gz_reset(state)
76 gz_statep state;
77{
jiadong.zhu6c142162016-06-22 21:22:18 -070078 state->x.have = 0; /* no output data available */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000079 if (state->mode == GZ_READ) { /* for reading ... */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000080 state->eof = 0; /* not at end of file */
jiadong.zhu6c142162016-06-22 21:22:18 -070081 state->past = 0; /* have not read past end yet */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000082 state->how = LOOK; /* look for gzip header */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000083 }
84 state->seek = 0; /* no seek request pending */
85 gz_error(state, Z_OK, NULL); /* clear error */
jiadong.zhu6c142162016-06-22 21:22:18 -070086 state->x.pos = 0; /* no uncompressed data yet */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000087 state->strm.avail_in = 0; /* no input data yet */
88}
89
90/* Open a gzip file either by name or file descriptor. */
91local gzFile gz_open(path, fd, mode)
jiadong.zhu6c142162016-06-22 21:22:18 -070092 const void *path;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +000093 int fd;
94 const char *mode;
95{
96 gz_statep state;
mark13dc2462017-02-14 22:15:29 -080097 z_size_t len;
jiadong.zhu6c142162016-06-22 21:22:18 -070098 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;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000109
110 /* allocate gzFile structure to return */
jiadong.zhu6c142162016-06-22 21:22:18 -0700111 state = (gz_statep)malloc(sizeof(gz_state));
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000112 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;
jiadong.zhu6c142162016-06-22 21:22:18 -0700122 state->direct = 0;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000123 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;
jiadong.zhu6c142162016-06-22 21:22:18 -0700144#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
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000154 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;
jiadong.zhu6c142162016-06-22 21:22:18 -0700165 break;
166 case 'T':
167 state->direct = 1;
168 break;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000169 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
jiadong.zhu6c142162016-06-22 21:22:18 -0700181 /* 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
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000190 /* save the path name for error messages */
mark13dc2462017-02-14 22:15:29 -0800191#ifdef WIDECHAR
jiadong.zhu6c142162016-06-22 21:22:18 -0700192 if (fd == -2) {
193 len = wcstombs(NULL, path, 0);
mark13dc2462017-02-14 22:15:29 -0800194 if (len == (z_size_t)-1)
jiadong.zhu6c142162016-06-22 21:22:18 -0700195 len = 0;
196 }
197 else
198#endif
199 len = strlen((const char *)path);
200 state->path = (char *)malloc(len + 1);
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000201 if (state->path == NULL) {
202 free(state);
203 return NULL;
204 }
mark13dc2462017-02-14 22:15:29 -0800205#ifdef WIDECHAR
jiadong.zhu6c142162016-06-22 21:22:18 -0700206 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)
mark13dc2462017-02-14 22:15:29 -0800214 (void)snprintf(state->path, len + 1, "%s", (const char *)path);
jiadong.zhu6c142162016-06-22 21:22:18 -0700215#else
216 strcpy(state->path, path);
217#endif
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000218
jiadong.zhu6c142162016-06-22 21:22:18 -0700219 /* compute the flags for open() */
220 oflag =
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000221#ifdef O_LARGEFILE
jiadong.zhu6c142162016-06-22 21:22:18 -0700222 O_LARGEFILE |
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000223#endif
224#ifdef O_BINARY
jiadong.zhu6c142162016-06-22 21:22:18 -0700225 O_BINARY |
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000226#endif
jiadong.zhu6c142162016-06-22 21:22:18 -0700227#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 : (
mark13dc2462017-02-14 22:15:29 -0800242#ifdef WIDECHAR
jiadong.zhu6c142162016-06-22 21:22:18 -0700243 fd == -2 ? _wopen(path, oflag, 0666) :
244#endif
245 open((const char *)path, oflag, 0666));
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000246 if (state->fd == -1) {
247 free(state->path);
248 free(state);
249 return NULL;
250 }
mark13dc2462017-02-14 22:15:29 -0800251 if (state->mode == GZ_APPEND) {
252 LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000253 state->mode = GZ_WRITE; /* simplify later checks */
mark13dc2462017-02-14 22:15:29 -0800254 }
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000255
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 -- */
270gzFile 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 -- */
278gzFile 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 -- */
286gzFile ZEXPORT gzdopen(fd, mode)
287 int fd;
288 const char *mode;
289{
290 char *path; /* identifier for error messages */
291 gzFile gz;
292
jiadong.zhu6c142162016-06-22 21:22:18 -0700293 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000294 return NULL;
jiadong.zhu6c142162016-06-22 21:22:18 -0700295#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
mark13dc2462017-02-14 22:15:29 -0800296 (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
jiadong.zhu6c142162016-06-22 21:22:18 -0700297#else
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000298 sprintf(path, "<fd:%d>", fd); /* for debugging */
jiadong.zhu6c142162016-06-22 21:22:18 -0700299#endif
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000300 gz = gz_open(path, fd, mode);
301 free(path);
302 return gz;
303}
304
305/* -- see zlib.h -- */
mark13dc2462017-02-14 22:15:29 -0800306#ifdef WIDECHAR
jiadong.zhu6c142162016-06-22 21:22:18 -0700307gzFile 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 -- */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000316int 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 */
mark13dc2462017-02-14 22:15:29 -0800334 if ((size << 1) < size)
335 return -1; /* need to be able to double it */
jiadong.zhu6c142162016-06-22 21:22:18 -0700336 if (size < 2)
337 size = 2; /* need two bytes to check magic header */
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000338 state->want = size;
339 return 0;
340}
341
342/* -- see zlib.h -- */
343int 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 */
jiadong.zhu6c142162016-06-22 21:22:18 -0700354 if (state->mode != GZ_READ ||
355 (state->err != Z_OK && state->err != Z_BUF_ERROR))
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000356 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 -- */
366z_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 */
jiadong.zhu6c142162016-06-22 21:22:18 -0700383 if (state->err != Z_OK && state->err != Z_BUF_ERROR)
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000384 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)
jiadong.zhu6c142162016-06-22 21:22:18 -0700392 offset -= state->x.pos;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000393 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 &&
jiadong.zhu6c142162016-06-22 21:22:18 -0700399 state->x.pos + offset >= 0) {
400 ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000401 if (ret == -1)
402 return -1;
jiadong.zhu6c142162016-06-22 21:22:18 -0700403 state->x.have = 0;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000404 state->eof = 0;
jiadong.zhu6c142162016-06-22 21:22:18 -0700405 state->past = 0;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000406 state->seek = 0;
407 gz_error(state, Z_OK, NULL);
408 state->strm.avail_in = 0;
jiadong.zhu6c142162016-06-22 21:22:18 -0700409 state->x.pos += offset;
410 return state->x.pos;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000411 }
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;
jiadong.zhu6c142162016-06-22 21:22:18 -0700417 offset += state->x.pos;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000418 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) {
jiadong.zhu6c142162016-06-22 21:22:18 -0700426 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;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000431 offset -= n;
432 }
433
434 /* request skip (if not zero) */
435 if (offset) {
436 state->seek = 1;
437 state->skip = offset;
438 }
jiadong.zhu6c142162016-06-22 21:22:18 -0700439 return state->x.pos + offset;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000440}
441
442/* -- see zlib.h -- */
443z_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 -- */
455z_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 */
jiadong.zhu6c142162016-06-22 21:22:18 -0700468 return state->x.pos + (state->seek ? state->skip : 0);
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000469}
470
471/* -- see zlib.h -- */
472z_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 -- */
482z_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 -- */
505z_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 -- */
515int 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 */
jiadong.zhu6c142162016-06-22 21:22:18 -0700528 return state->mode == GZ_READ ? state->past : 0;
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000529}
530
531/* -- see zlib.h -- */
532const 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;
jiadong.zhu6c142162016-06-22 21:22:18 -0700548 return state->err == Z_MEM_ERROR ? "out of memory" :
549 (state->msg == NULL ? "" : state->msg);
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000550}
551
552/* -- see zlib.h -- */
553void 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 */
jiadong.zhu6c142162016-06-22 21:22:18 -0700566 if (state->mode == GZ_READ) {
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000567 state->eof = 0;
jiadong.zhu6c142162016-06-22 21:22:18 -0700568 state->past = 0;
569 }
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000570 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. */
579void 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
jiadong.zhu6c142162016-06-22 21:22:18 -0700591 /* 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
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000595 /* set error code, and if no message, then done */
596 state->err = err;
597 if (msg == NULL)
598 return;
599
jiadong.zhu6c142162016-06-22 21:22:18 -0700600 /* for an out of memory error, return literal string when requested */
601 if (err == Z_MEM_ERROR)
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000602 return;
jmadillbf2aebe2016-06-20 06:58:52 -0700603
604 /* construct error message with path */
jiadong.zhu6c142162016-06-22 21:22:18 -0700605 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
606 NULL) {
jmadillbf2aebe2016-06-20 06:58:52 -0700607 state->err = Z_MEM_ERROR;
jmadillbf2aebe2016-06-20 06:58:52 -0700608 return;
609 }
jiadong.zhu6c142162016-06-22 21:22:18 -0700610#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
mark13dc2462017-02-14 22:15:29 -0800611 (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
612 "%s%s%s", state->path, ": ", msg);
jiadong.zhu6c142162016-06-22 21:22:18 -0700613#else
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000614 strcpy(state->msg, state->path);
615 strcat(state->msg, ": ");
616 strcat(state->msg, msg);
jiadong.zhu6c142162016-06-22 21:22:18 -0700617#endif
gavinp@chromium.orgc1013302013-04-09 17:15:13 +0000618}
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 */
625unsigned 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