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