This source file includes following definitions.
- zip_file_extra_field_delete
- zip_file_extra_field_delete_by_id
- zip_file_extra_field_get
- zip_file_extra_field_get_by_id
- zip_file_extra_fields_count
- zip_file_extra_fields_count_by_id
- zip_file_extra_field_set
- _zip_file_extra_field_prepare_for_change
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 "zipint.h"
36
37
38 ZIP_EXTERN int
39 zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags)
40 {
41 zip_dirent_t *de;
42
43 if ((flags & ZIP_EF_BOTH) == 0) {
44 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
45 return -1;
46 }
47
48 if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
49 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
50 return -1;
51 }
52
53 if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
54 return -1;
55
56 if (ZIP_IS_RDONLY(za)) {
57 zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
58 return -1;
59 }
60
61 if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
62 return -1;
63
64 de = za->entry[idx].changes;
65
66 de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
67 return 0;
68 }
69
70
71 ZIP_EXTERN int
72 zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags)
73 {
74 zip_dirent_t *de;
75
76 if ((flags & ZIP_EF_BOTH) == 0) {
77 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
78 return -1;
79 }
80
81 if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
82 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
83 return -1;
84 }
85
86 if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
87 return -1;
88
89 if (ZIP_IS_RDONLY(za)) {
90 zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
91 return -1;
92 }
93
94 if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
95 return -1;
96
97 de = za->entry[idx].changes;
98
99 de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
100 return 0;
101 }
102
103
104 ZIP_EXTERN const zip_uint8_t *
105 zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags)
106 {
107 static const zip_uint8_t empty[1] = { '\0' };
108
109 zip_dirent_t *de;
110 zip_extra_field_t *ef;
111 int i;
112
113 if ((flags & ZIP_EF_BOTH) == 0) {
114 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
115 return NULL;
116 }
117
118 if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
119 return NULL;
120
121 if (flags & ZIP_FL_LOCAL)
122 if (_zip_read_local_ef(za, idx) < 0)
123 return NULL;
124
125 i = 0;
126 for (ef=de->extra_fields; ef; ef=ef->next) {
127 if (ef->flags & flags & ZIP_EF_BOTH) {
128 if (i < ef_idx) {
129 i++;
130 continue;
131 }
132
133 if (idp)
134 *idp = ef->id;
135 if (lenp)
136 *lenp = ef->size;
137 if (ef->size > 0)
138 return ef->data;
139 else
140 return empty;
141 }
142 }
143
144 zip_error_set(&za->error, ZIP_ER_NOENT, 0);
145 return NULL;
146
147 }
148
149
150 ZIP_EXTERN const zip_uint8_t *
151 zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags)
152 {
153 zip_dirent_t *de;
154
155 if ((flags & ZIP_EF_BOTH) == 0) {
156 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
157 return NULL;
158 }
159
160 if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
161 return NULL;
162
163 if (flags & ZIP_FL_LOCAL)
164 if (_zip_read_local_ef(za, idx) < 0)
165 return NULL;
166
167 return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
168 }
169
170
171 ZIP_EXTERN zip_int16_t
172 zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
173 {
174 zip_dirent_t *de;
175 zip_extra_field_t *ef;
176 zip_uint16_t n;
177
178 if ((flags & ZIP_EF_BOTH) == 0) {
179 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
180 return -1;
181 }
182
183 if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
184 return -1;
185
186 if (flags & ZIP_FL_LOCAL)
187 if (_zip_read_local_ef(za, idx) < 0)
188 return -1;
189
190 n = 0;
191 for (ef=de->extra_fields; ef; ef=ef->next)
192 if (ef->flags & flags & ZIP_EF_BOTH)
193 n++;
194
195 return (zip_int16_t)n;
196 }
197
198
199 ZIP_EXTERN zip_int16_t
200 zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags)
201 {
202 zip_dirent_t *de;
203 zip_extra_field_t *ef;
204 zip_uint16_t n;
205
206 if ((flags & ZIP_EF_BOTH) == 0) {
207 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
208 return -1;
209 }
210
211 if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
212 return -1;
213
214 if (flags & ZIP_FL_LOCAL)
215 if (_zip_read_local_ef(za, idx) < 0)
216 return -1;
217
218 n = 0;
219 for (ef=de->extra_fields; ef; ef=ef->next)
220 if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
221 n++;
222
223 return (zip_int16_t)n;
224 }
225
226
227 ZIP_EXTERN int
228 zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags)
229 {
230 zip_dirent_t *de;
231 zip_uint16_t ls, cs;
232 zip_extra_field_t *ef, *ef_prev, *ef_new;
233 int i, found, new_len;
234
235 if ((flags & ZIP_EF_BOTH) == 0) {
236 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
237 return -1;
238 }
239
240 if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
241 return -1;
242
243 if (ZIP_IS_RDONLY(za)) {
244 zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
245 return -1;
246 }
247
248 if (ZIP_EF_IS_INTERNAL(ef_id)) {
249 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
250 return -1;
251 }
252
253 if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
254 return -1;
255
256 de = za->entry[idx].changes;
257
258 ef = de->extra_fields;
259 ef_prev = NULL;
260 i = 0;
261 found = 0;
262
263 for (; ef; ef=ef->next) {
264 if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
265 if (i == ef_idx) {
266 found = 1;
267 break;
268 }
269 i++;
270 }
271 ef_prev = ef;
272 }
273
274 if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
275 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
276 return -1;
277 }
278
279 if (flags & ZIP_EF_LOCAL)
280 ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
281 else
282 ls = 0;
283 if (flags & ZIP_EF_CENTRAL)
284 cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
285 else
286 cs = 0;
287
288 new_len = ls > cs ? ls : cs;
289 if (found)
290 new_len -= ef->size + 4;
291 new_len += len + 4;
292
293 if (new_len > ZIP_UINT16_MAX) {
294 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
295 return -1;
296 }
297
298 if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) {
299 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
300 return -1;
301 }
302
303 if (found) {
304 if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
305 ef_new->next = ef->next;
306 ef->next = NULL;
307 _zip_ef_free(ef);
308 if (ef_prev)
309 ef_prev->next = ef_new;
310 else
311 de->extra_fields = ef_new;
312 }
313 else {
314 ef->flags &= ~(flags & ZIP_EF_BOTH);
315 ef_new->next = ef->next;
316 ef->next = ef_new;
317 }
318 }
319 else if (ef_prev) {
320 ef_new->next = ef_prev->next;
321 ef_prev->next = ef_new;
322 }
323 else
324 de->extra_fields = ef_new;
325
326 return 0;
327 }
328
329
330
331 int
332 _zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx)
333 {
334 zip_entry_t *e;
335
336 if (idx >= za->nentry) {
337 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
338 return -1;
339 }
340
341 e = za->entry+idx;
342
343 if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
344 return 0;
345
346 if (e->orig) {
347 if (_zip_read_local_ef(za, idx) < 0)
348 return -1;
349 }
350
351 if (e->changes == NULL) {
352 if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
353 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
354 return -1;
355 }
356 }
357
358 if (e->orig && e->orig->extra_fields) {
359 if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
360 return -1;
361 }
362 e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
363
364 return 0;
365 }
366