OLD | NEW |
1 /* gzlib.c -- zlib functions common to reading and writing gzip files | 1 /* gzlib.c -- zlib functions common to reading and writing gzip files |
2 * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler | 2 * Copyright (C) 2004-2017 Mark Adler |
3 * For conditions of distribution and use, see copyright notice in zlib.h | 3 * For conditions of distribution and use, see copyright notice in zlib.h |
4 */ | 4 */ |
5 | 5 |
6 #include "gzguts.h" | 6 #include "gzguts.h" |
7 | 7 |
8 #if defined(_WIN32) && !defined(__BORLANDC__) | 8 #if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) |
9 # define LSEEK _lseeki64 | 9 # define LSEEK _lseeki64 |
10 #else | 10 #else |
11 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 | 11 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 |
12 # define LSEEK lseek64 | 12 # define LSEEK lseek64 |
13 #else | 13 #else |
14 # define LSEEK lseek | 14 # define LSEEK lseek |
15 #endif | 15 #endif |
16 #endif | 16 #endif |
17 | 17 |
18 /* Local functions */ | 18 /* Local functions */ |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 state->strm.avail_in = 0; /* no input data yet */ | 87 state->strm.avail_in = 0; /* no input data yet */ |
88 } | 88 } |
89 | 89 |
90 /* Open a gzip file either by name or file descriptor. */ | 90 /* Open a gzip file either by name or file descriptor. */ |
91 local gzFile gz_open(path, fd, mode) | 91 local gzFile gz_open(path, fd, mode) |
92 const void *path; | 92 const void *path; |
93 int fd; | 93 int fd; |
94 const char *mode; | 94 const char *mode; |
95 { | 95 { |
96 gz_statep state; | 96 gz_statep state; |
97 size_t len; | 97 z_size_t len; |
98 int oflag; | 98 int oflag; |
99 #ifdef O_CLOEXEC | 99 #ifdef O_CLOEXEC |
100 int cloexec = 0; | 100 int cloexec = 0; |
101 #endif | 101 #endif |
102 #ifdef O_EXCL | 102 #ifdef O_EXCL |
103 int exclusive = 0; | 103 int exclusive = 0; |
104 #endif | 104 #endif |
105 | 105 |
106 /* check input */ | 106 /* check input */ |
107 if (path == NULL) | 107 if (path == NULL) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 /* can't force transparent read */ | 181 /* can't force transparent read */ |
182 if (state->mode == GZ_READ) { | 182 if (state->mode == GZ_READ) { |
183 if (state->direct) { | 183 if (state->direct) { |
184 free(state); | 184 free(state); |
185 return NULL; | 185 return NULL; |
186 } | 186 } |
187 state->direct = 1; /* for empty file */ | 187 state->direct = 1; /* for empty file */ |
188 } | 188 } |
189 | 189 |
190 /* save the path name for error messages */ | 190 /* save the path name for error messages */ |
191 #ifdef _WIN32 | 191 #ifdef WIDECHAR |
192 if (fd == -2) { | 192 if (fd == -2) { |
193 len = wcstombs(NULL, path, 0); | 193 len = wcstombs(NULL, path, 0); |
194 if (len == (size_t)-1) | 194 if (len == (z_size_t)-1) |
195 len = 0; | 195 len = 0; |
196 } | 196 } |
197 else | 197 else |
198 #endif | 198 #endif |
199 len = strlen((const char *)path); | 199 len = strlen((const char *)path); |
200 state->path = (char *)malloc(len + 1); | 200 state->path = (char *)malloc(len + 1); |
201 if (state->path == NULL) { | 201 if (state->path == NULL) { |
202 free(state); | 202 free(state); |
203 return NULL; | 203 return NULL; |
204 } | 204 } |
205 #ifdef _WIN32 | 205 #ifdef WIDECHAR |
206 if (fd == -2) | 206 if (fd == -2) |
207 if (len) | 207 if (len) |
208 wcstombs(state->path, path, len + 1); | 208 wcstombs(state->path, path, len + 1); |
209 else | 209 else |
210 *(state->path) = 0; | 210 *(state->path) = 0; |
211 else | 211 else |
212 #endif | 212 #endif |
213 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) | 213 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) |
214 snprintf(state->path, len + 1, "%s", (const char *)path); | 214 (void)snprintf(state->path, len + 1, "%s", (const char *)path); |
215 #else | 215 #else |
216 strcpy(state->path, path); | 216 strcpy(state->path, path); |
217 #endif | 217 #endif |
218 | 218 |
219 /* compute the flags for open() */ | 219 /* compute the flags for open() */ |
220 oflag = | 220 oflag = |
221 #ifdef O_LARGEFILE | 221 #ifdef O_LARGEFILE |
222 O_LARGEFILE | | 222 O_LARGEFILE | |
223 #endif | 223 #endif |
224 #ifdef O_BINARY | 224 #ifdef O_BINARY |
225 O_BINARY | | 225 O_BINARY | |
226 #endif | 226 #endif |
227 #ifdef O_CLOEXEC | 227 #ifdef O_CLOEXEC |
228 (cloexec ? O_CLOEXEC : 0) | | 228 (cloexec ? O_CLOEXEC : 0) | |
229 #endif | 229 #endif |
230 (state->mode == GZ_READ ? | 230 (state->mode == GZ_READ ? |
231 O_RDONLY : | 231 O_RDONLY : |
232 (O_WRONLY | O_CREAT | | 232 (O_WRONLY | O_CREAT | |
233 #ifdef O_EXCL | 233 #ifdef O_EXCL |
234 (exclusive ? O_EXCL : 0) | | 234 (exclusive ? O_EXCL : 0) | |
235 #endif | 235 #endif |
236 (state->mode == GZ_WRITE ? | 236 (state->mode == GZ_WRITE ? |
237 O_TRUNC : | 237 O_TRUNC : |
238 O_APPEND))); | 238 O_APPEND))); |
239 | 239 |
240 /* open the file with the appropriate flags (or just use fd) */ | 240 /* open the file with the appropriate flags (or just use fd) */ |
241 state->fd = fd > -1 ? fd : ( | 241 state->fd = fd > -1 ? fd : ( |
242 #ifdef _WIN32 | 242 #ifdef WIDECHAR |
243 fd == -2 ? _wopen(path, oflag, 0666) : | 243 fd == -2 ? _wopen(path, oflag, 0666) : |
244 #endif | 244 #endif |
245 open((const char *)path, oflag, 0666)); | 245 open((const char *)path, oflag, 0666)); |
246 if (state->fd == -1) { | 246 if (state->fd == -1) { |
247 free(state->path); | 247 free(state->path); |
248 free(state); | 248 free(state); |
249 return NULL; | 249 return NULL; |
250 } | 250 } |
251 if (state->mode == GZ_APPEND) | 251 if (state->mode == GZ_APPEND) { |
| 252 LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ |
252 state->mode = GZ_WRITE; /* simplify later checks */ | 253 state->mode = GZ_WRITE; /* simplify later checks */ |
| 254 } |
253 | 255 |
254 /* save the current position for rewinding (only if reading) */ | 256 /* save the current position for rewinding (only if reading) */ |
255 if (state->mode == GZ_READ) { | 257 if (state->mode == GZ_READ) { |
256 state->start = LSEEK(state->fd, 0, SEEK_CUR); | 258 state->start = LSEEK(state->fd, 0, SEEK_CUR); |
257 if (state->start == -1) state->start = 0; | 259 if (state->start == -1) state->start = 0; |
258 } | 260 } |
259 | 261 |
260 /* initialize stream */ | 262 /* initialize stream */ |
261 gz_reset(state); | 263 gz_reset(state); |
262 | 264 |
(...skipping 21 matching lines...) Expand all Loading... |
284 gzFile ZEXPORT gzdopen(fd, mode) | 286 gzFile ZEXPORT gzdopen(fd, mode) |
285 int fd; | 287 int fd; |
286 const char *mode; | 288 const char *mode; |
287 { | 289 { |
288 char *path; /* identifier for error messages */ | 290 char *path; /* identifier for error messages */ |
289 gzFile gz; | 291 gzFile gz; |
290 | 292 |
291 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) | 293 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) |
292 return NULL; | 294 return NULL; |
293 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) | 295 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) |
294 snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */ | 296 (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); |
295 #else | 297 #else |
296 sprintf(path, "<fd:%d>", fd); /* for debugging */ | 298 sprintf(path, "<fd:%d>", fd); /* for debugging */ |
297 #endif | 299 #endif |
298 gz = gz_open(path, fd, mode); | 300 gz = gz_open(path, fd, mode); |
299 free(path); | 301 free(path); |
300 return gz; | 302 return gz; |
301 } | 303 } |
302 | 304 |
303 /* -- see zlib.h -- */ | 305 /* -- see zlib.h -- */ |
304 #ifdef _WIN32 | 306 #ifdef WIDECHAR |
305 gzFile ZEXPORT gzopen_w(path, mode) | 307 gzFile ZEXPORT gzopen_w(path, mode) |
306 const wchar_t *path; | 308 const wchar_t *path; |
307 const char *mode; | 309 const char *mode; |
308 { | 310 { |
309 return gz_open(path, -2, mode); | 311 return gz_open(path, -2, mode); |
310 } | 312 } |
311 #endif | 313 #endif |
312 | 314 |
313 /* -- see zlib.h -- */ | 315 /* -- see zlib.h -- */ |
314 int ZEXPORT gzbuffer(file, size) | 316 int ZEXPORT gzbuffer(file, size) |
315 gzFile file; | 317 gzFile file; |
316 unsigned size; | 318 unsigned size; |
317 { | 319 { |
318 gz_statep state; | 320 gz_statep state; |
319 | 321 |
320 /* get internal structure and check integrity */ | 322 /* get internal structure and check integrity */ |
321 if (file == NULL) | 323 if (file == NULL) |
322 return -1; | 324 return -1; |
323 state = (gz_statep)file; | 325 state = (gz_statep)file; |
324 if (state->mode != GZ_READ && state->mode != GZ_WRITE) | 326 if (state->mode != GZ_READ && state->mode != GZ_WRITE) |
325 return -1; | 327 return -1; |
326 | 328 |
327 /* make sure we haven't already allocated memory */ | 329 /* make sure we haven't already allocated memory */ |
328 if (state->size != 0) | 330 if (state->size != 0) |
329 return -1; | 331 return -1; |
330 | 332 |
331 /* check and set requested size */ | 333 /* check and set requested size */ |
| 334 if ((size << 1) < size) |
| 335 return -1; /* need to be able to double it */ |
332 if (size < 2) | 336 if (size < 2) |
333 size = 2; /* need two bytes to check magic header */ | 337 size = 2; /* need two bytes to check magic header */ |
334 state->want = size; | 338 state->want = size; |
335 return 0; | 339 return 0; |
336 } | 340 } |
337 | 341 |
338 /* -- see zlib.h -- */ | 342 /* -- see zlib.h -- */ |
339 int ZEXPORT gzrewind(file) | 343 int ZEXPORT gzrewind(file) |
340 gzFile file; | 344 gzFile file; |
341 { | 345 { |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 if (err == Z_MEM_ERROR) | 601 if (err == Z_MEM_ERROR) |
598 return; | 602 return; |
599 | 603 |
600 /* construct error message with path */ | 604 /* construct error message with path */ |
601 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == | 605 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == |
602 NULL) { | 606 NULL) { |
603 state->err = Z_MEM_ERROR; | 607 state->err = Z_MEM_ERROR; |
604 return; | 608 return; |
605 } | 609 } |
606 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) | 610 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) |
607 snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, | 611 (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, |
608 "%s%s%s", state->path, ": ", msg); | 612 "%s%s%s", state->path, ": ", msg); |
609 #else | 613 #else |
610 strcpy(state->msg, state->path); | 614 strcpy(state->msg, state->path); |
611 strcat(state->msg, ": "); | 615 strcat(state->msg, ": "); |
612 strcat(state->msg, msg); | 616 strcat(state->msg, msg); |
613 #endif | 617 #endif |
614 return; | |
615 } | 618 } |
616 | 619 |
617 #ifndef INT_MAX | 620 #ifndef INT_MAX |
618 /* portably return maximum value for an int (when limits.h presumed not | 621 /* portably return maximum value for an int (when limits.h presumed not |
619 available) -- we need to do this to cover cases where 2's complement not | 622 available) -- we need to do this to cover cases where 2's complement not |
620 used, since C standard permits 1's complement and sign-bit representations, | 623 used, since C standard permits 1's complement and sign-bit representations, |
621 otherwise we could just use ((unsigned)-1) >> 1 */ | 624 otherwise we could just use ((unsigned)-1) >> 1 */ |
622 unsigned ZLIB_INTERNAL gz_intmax() | 625 unsigned ZLIB_INTERNAL gz_intmax() |
623 { | 626 { |
624 unsigned p, q; | 627 unsigned p, q; |
625 | 628 |
626 p = 1; | 629 p = 1; |
627 do { | 630 do { |
628 q = p; | 631 q = p; |
629 p <<= 1; | 632 p <<= 1; |
630 p++; | 633 p++; |
631 } while (p > q); | 634 } while (p > q); |
632 return q >> 1; | 635 return q >> 1; |
633 } | 636 } |
634 #endif | 637 #endif |
OLD | NEW |