This source file includes following definitions.
- _zip_source_zip_new
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <stdlib.h>
36
37 #include "zipint.h"
38
39
40 zip_source_t *
41 _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password)
42 {
43 zip_compression_implementation comp_impl;
44 zip_encryption_implementation enc_impl;
45 zip_source_t *src, *s2;
46 zip_uint64_t offset;
47 struct zip_stat st;
48
49 if (za == NULL)
50 return NULL;
51
52 if (srcza == NULL || srcidx >= srcza->nentry) {
53 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
54 return NULL;
55 }
56
57 if ((flags & ZIP_FL_UNCHANGED) == 0
58 && (ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx) || srcza->entry[srcidx].deleted)) {
59 zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
60 return NULL;
61 }
62
63 if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) {
64 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
65 return NULL;
66 }
67
68 if (flags & ZIP_FL_ENCRYPTED)
69 flags |= ZIP_FL_COMPRESSED;
70
71 if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) {
72 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
73 return NULL;
74 }
75
76
77 if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) {
78 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
79 return NULL;
80 }
81
82 enc_impl = NULL;
83 if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) {
84 if (password == NULL) {
85 zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
86 return NULL;
87 }
88 if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method)) == NULL) {
89 zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
90 return NULL;
91 }
92 }
93
94 comp_impl = NULL;
95 if ((flags & ZIP_FL_COMPRESSED) == 0) {
96 if (st.comp_method != ZIP_CM_STORE) {
97 if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
98 zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
99 return NULL;
100 }
101 }
102 }
103
104 if ((offset=_zip_file_get_offset(srcza, srcidx, &za->error)) == 0)
105 return NULL;
106
107 if (st.comp_size == 0) {
108 return zip_source_buffer(za, NULL, 0, 0);
109 }
110
111 if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) {
112 struct zip_stat st2;
113
114 st2.size = len ? len : st.size-start;
115 st2.comp_size = st2.size;
116 st2.comp_method = ZIP_CM_STORE;
117 st2.mtime = st.mtime;
118 st2.valid = ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_MTIME;
119
120 if ((src = _zip_source_window_new(srcza->src, offset+start, st2.size, &st2, &za->error)) == NULL) {
121 return NULL;
122 }
123 }
124 else {
125 if ((src = _zip_source_window_new(srcza->src, offset, st.comp_size, &st, &za->error)) == NULL) {
126 return NULL;
127 }
128 }
129
130 if (_zip_source_set_source_archive(src, srcza) < 0) {
131 zip_source_free(src);
132 return NULL;
133 }
134
135
136
137 if (enc_impl) {
138 s2 = enc_impl(za, src, st.encryption_method, 0, password);
139 zip_source_free(src);
140 if (s2 == NULL) {
141 return NULL;
142 }
143 src = s2;
144 }
145 if (comp_impl) {
146 s2 = comp_impl(za, src, st.comp_method, 0);
147 zip_source_free(src);
148 if (s2 == NULL) {
149 return NULL;
150 }
151 src = s2;
152 }
153 if (((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) && (len == 0 || len == st.comp_size)) {
154
155 s2 = zip_source_crc(za, src, 1);
156 zip_source_free(src);
157 if (s2 == NULL) {
158 return NULL;
159 }
160 src = s2;
161 }
162
163 if (start+len > 0 && (comp_impl || enc_impl)) {
164 s2 = zip_source_window(za, src, start, len ? len : st.size-start);
165 zip_source_free(src);
166 if (s2 == NULL) {
167 return NULL;
168 }
169 src = s2;
170 }
171
172 return src;
173 }