Line | Count | Source |
1 | | /* uncompr.c -- decompress a memory buffer |
2 | | * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler. |
3 | | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | | */ |
5 | | |
6 | | #include "zbuild.h" |
7 | | #include "zutil.h" |
8 | | |
9 | | /* =========================================================================== |
10 | | Decompresses the source buffer into the destination buffer. *sourceLen is |
11 | | the byte length of the source buffer. Upon entry, *destLen is the total size |
12 | | of the destination buffer, which must be large enough to hold the entire |
13 | | uncompressed data. (The size of the uncompressed data must have been saved |
14 | | previously by the compressor and transmitted to the decompressor by some |
15 | | mechanism outside the scope of this compression library.) Upon exit, |
16 | | *destLen is the size of the decompressed data and *sourceLen is the number |
17 | | of source bytes consumed. Upon return, source + *sourceLen points to the |
18 | | first unused input byte. |
19 | | |
20 | | uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough |
21 | | memory, Z_BUF_ERROR if there was not enough room in the output buffer, or |
22 | | Z_DATA_ERROR if the input data was corrupted, including if the input data is |
23 | | an incomplete zlib stream. |
24 | | */ |
25 | | #ifdef ZLIB_COMPAT |
26 | | int Z_EXPORT PREFIX(uncompress2_z)(unsigned char *dest, z_size_t *destLen, const unsigned char *source, |
27 | | z_size_t *sourceLen) { |
28 | | #else |
29 | | z_int32_t Z_EXPORT PREFIX(uncompress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, |
30 | 30.1k | z_uintmax_t *sourceLen) { |
31 | 30.1k | #endif |
32 | 30.1k | PREFIX3(stream) stream; |
33 | 30.1k | int err; |
34 | 30.1k | const unsigned int max = (unsigned int)-1; |
35 | 30.1k | z_size_t len, left; |
36 | 30.1k | unsigned char buf[1]; /* for detection of incomplete stream when *destLen == 0 */ |
37 | | |
38 | 30.1k | if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) || |
39 | 30.1k | destLen == NULL || (*destLen > 0 && dest == NULL)) |
40 | 0 | return Z_STREAM_ERROR; |
41 | | |
42 | 30.1k | len = *sourceLen; |
43 | 30.1k | if (*destLen) { |
44 | 30.1k | left = *destLen; |
45 | 30.1k | *destLen = 0; |
46 | 30.1k | } else { |
47 | 0 | left = 1; |
48 | 0 | dest = buf; |
49 | 0 | } |
50 | | |
51 | 30.1k | stream.next_in = (z_const unsigned char *)source; |
52 | 30.1k | stream.avail_in = 0; |
53 | 30.1k | stream.zalloc = NULL; |
54 | 30.1k | stream.zfree = NULL; |
55 | 30.1k | stream.opaque = NULL; |
56 | | |
57 | 30.1k | err = PREFIX(inflateInit)(&stream); |
58 | 30.1k | if (err != Z_OK) return err; |
59 | | |
60 | 30.1k | stream.next_out = dest; |
61 | 30.1k | stream.avail_out = 0; |
62 | | |
63 | 31.5k | do { |
64 | 31.5k | if (stream.avail_out == 0) { |
65 | 30.4k | stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; |
66 | 30.4k | left -= stream.avail_out; |
67 | 30.4k | } |
68 | 31.5k | if (stream.avail_in == 0) { |
69 | 31.1k | stream.avail_in = len > (unsigned long)max ? max : (unsigned int)len; |
70 | 31.1k | len -= stream.avail_in; |
71 | 31.1k | } |
72 | 31.5k | err = PREFIX(inflate)(&stream, Z_NO_FLUSH); |
73 | 31.5k | } while (err == Z_OK); |
74 | | |
75 | 30.1k | *sourceLen -= len + stream.avail_in; |
76 | 30.1k | if (dest != buf) |
77 | 30.1k | *destLen = (z_size_t)stream.total_out; |
78 | 0 | else if (stream.total_out && err == Z_BUF_ERROR) |
79 | 0 | left = 1; |
80 | | |
81 | 30.1k | PREFIX(inflateEnd)(&stream); |
82 | 30.1k | return err == Z_STREAM_END ? Z_OK : |
83 | 30.1k | err == Z_NEED_DICT ? Z_DATA_ERROR : |
84 | 6.02k | err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : |
85 | 6.02k | err; |
86 | 30.1k | } |
87 | | |
88 | 30.1k | z_int32_t Z_EXPORT PREFIX(uncompress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { |
89 | 30.1k | return PREFIX(uncompress2)(dest, destLen, source, &sourceLen); |
90 | 30.1k | } |
91 | | |
92 | | #ifdef ZLIB_COMPAT |
93 | | int Z_EXPORT PREFIX(uncompress2)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, |
94 | | unsigned long *sourceLen) { |
95 | | z_size_t got = destLen ? *destLen : 0, used = sourceLen ? *sourceLen : 0; |
96 | | int ret = PREFIX(uncompress2_z)(dest, &got, source, &used); |
97 | | if (sourceLen) |
98 | | *sourceLen = (unsigned long)used; |
99 | | if (destLen) |
100 | | *destLen = (unsigned long)got; |
101 | | return ret; |
102 | | } |
103 | | |
104 | | z_int32_t Z_EXPORT PREFIX(uncompress_z)(unsigned char *dest, z_size_t *destLen, const unsigned char *source, |
105 | | z_size_t sourceLen) { |
106 | | return PREFIX(uncompress2_z)(dest, destLen, source, &sourceLen); |
107 | | } |
108 | | #endif |