This source file includes following definitions.
- _zip_ef_clone
- _zip_ef_delete_by_id
- _zip_ef_free
- _zip_ef_get_by_id
- _zip_ef_merge
- _zip_ef_new
- _zip_ef_parse
- _zip_ef_remove_internal
- _zip_ef_size
- _zip_ef_write
- _zip_read_local_ef
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 #include <stdlib.h>
35 #include <string.h>
36
37 #include "zipint.h"
38
39
40 zip_extra_field_t *
41 _zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error)
42 {
43 zip_extra_field_t *head, *prev, *def;
44
45 head = prev = NULL;
46
47 while (ef) {
48 if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) {
49 zip_error_set(error, ZIP_ER_MEMORY, 0);
50 _zip_ef_free(head);
51 return NULL;
52 }
53
54 if (head == NULL)
55 head = def;
56 if (prev)
57 prev->next = def;
58 prev = def;
59
60 ef = ef->next;
61 }
62
63 return head;
64 }
65
66
67 zip_extra_field_t *
68 _zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags)
69 {
70 zip_extra_field_t *head, *prev;
71 int i;
72
73 i = 0;
74 head = ef;
75 prev = NULL;
76 for (; ef; ef=(prev ? prev->next : head)) {
77 if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) {
78 if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) {
79 ef->flags &= ~(flags & ZIP_EF_BOTH);
80 if ((ef->flags & ZIP_EF_BOTH) == 0) {
81 if (prev)
82 prev->next = ef->next;
83 else
84 head = ef->next;
85 ef->next = NULL;
86 _zip_ef_free(ef);
87
88 if (id_idx == ZIP_EXTRA_FIELD_ALL)
89 continue;
90 }
91 }
92
93 i++;
94 if (i > id_idx)
95 break;
96 }
97 prev = ef;
98 }
99
100 return head;
101 }
102
103
104
105 void
106 _zip_ef_free(zip_extra_field_t *ef)
107 {
108 zip_extra_field_t *ef2;
109
110 while (ef) {
111 ef2 = ef->next;
112 free(ef->data);
113 free(ef);
114 ef = ef2;
115 }
116 }
117
118
119 const zip_uint8_t *
120 _zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error)
121 {
122 static const zip_uint8_t empty[1] = { '\0' };
123
124 int i;
125
126 i = 0;
127 for (; ef; ef=ef->next) {
128 if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) {
129 if (i < id_idx) {
130 i++;
131 continue;
132 }
133
134 if (lenp)
135 *lenp = ef->size;
136 if (ef->size > 0)
137 return ef->data;
138 else
139 return empty;
140 }
141 }
142
143 zip_error_set(error, ZIP_ER_NOENT, 0);
144 return NULL;
145 }
146
147
148 zip_extra_field_t *
149 _zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from)
150 {
151 zip_extra_field_t *ef2, *tt, *tail;
152 int duplicate;
153
154 if (to == NULL)
155 return from;
156
157 for (tail=to; tail->next; tail=tail->next)
158 ;
159
160 for (; from; from=ef2) {
161 ef2 = from->next;
162
163 duplicate = 0;
164 for (tt=to; tt; tt=tt->next) {
165 if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) {
166 tt->flags |= (from->flags & ZIP_EF_BOTH);
167 duplicate = 1;
168 break;
169 }
170 }
171
172 from->next = NULL;
173 if (duplicate)
174 _zip_ef_free(from);
175 else
176 tail = tail->next = from;
177 }
178
179 return to;
180 }
181
182
183 zip_extra_field_t *
184 _zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags)
185 {
186 zip_extra_field_t *ef;
187
188 if ((ef=(zip_extra_field_t *)malloc(sizeof(*ef))) == NULL)
189 return NULL;
190
191 ef->next = NULL;
192 ef->flags = flags;
193 ef->id = id;
194 ef->size = size;
195 if (size > 0) {
196 if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) {
197 free(ef);
198 return NULL;
199 }
200 }
201 else
202 ef->data = NULL;
203
204 return ef;
205 }
206
207
208 bool
209 _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error)
210 {
211 zip_buffer_t *buffer;
212 zip_extra_field_t *ef, *ef2, *ef_head;
213
214 if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) {
215 zip_error_set(error, ZIP_ER_MEMORY, 0);
216 return false;
217 }
218
219 ef_head = ef = NULL;
220
221 while (_zip_buffer_ok(buffer) && _zip_buffer_left(buffer) >= 4) {
222 zip_uint16_t fid, flen;
223 zip_uint8_t *ef_data;
224
225 fid = _zip_buffer_get_16(buffer);
226 flen = _zip_buffer_get_16(buffer);
227 ef_data = _zip_buffer_get(buffer, flen);
228
229 if (ef_data == NULL) {
230 zip_error_set(error, ZIP_ER_INCONS, 0);
231 _zip_buffer_free(buffer);
232 _zip_ef_free(ef_head);
233 return false;
234 }
235
236 if ((ef2=_zip_ef_new(fid, flen, ef_data, flags)) == NULL) {
237 zip_error_set(error, ZIP_ER_MEMORY, 0);
238 _zip_buffer_free(buffer);
239 _zip_ef_free(ef_head);
240 return false;
241 }
242
243 if (ef_head) {
244 ef->next = ef2;
245 ef = ef2;
246 }
247 else
248 ef_head = ef = ef2;
249 }
250
251 if (!_zip_buffer_eof(buffer)) {
252
253
254 size_t glen = _zip_buffer_left(buffer);
255 zip_uint8_t *garbage;
256 garbage = _zip_buffer_get(buffer, glen);
257 if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
258 zip_error_set(error, ZIP_ER_INCONS, 0);
259 _zip_buffer_free(buffer);
260 _zip_ef_free(ef_head);
261 return false;
262 }
263 }
264
265 _zip_buffer_free(buffer);
266
267 if (ef_head_p) {
268 *ef_head_p = ef_head;
269 }
270 else {
271 _zip_ef_free(ef_head);
272 }
273
274 return true;
275 }
276
277
278 zip_extra_field_t *
279 _zip_ef_remove_internal(zip_extra_field_t *ef)
280 {
281 zip_extra_field_t *ef_head;
282 zip_extra_field_t *prev, *next;
283
284 ef_head = ef;
285 prev = NULL;
286
287 while (ef) {
288 if (ZIP_EF_IS_INTERNAL(ef->id)) {
289 next = ef->next;
290 if (ef_head == ef)
291 ef_head = next;
292 ef->next = NULL;
293 _zip_ef_free(ef);
294 if (prev)
295 prev->next = next;
296 ef = next;
297 }
298 else {
299 prev = ef;
300 ef = ef->next;
301 }
302 }
303
304 return ef_head;
305 }
306
307
308 zip_uint16_t
309 _zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags)
310 {
311 zip_uint16_t size;
312
313 size = 0;
314 for (; ef; ef=ef->next) {
315 if (ef->flags & flags & ZIP_EF_BOTH)
316 size = (zip_uint16_t)(size+4+ef->size);
317 }
318
319 return size;
320 }
321
322
323 int
324 _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags)
325 {
326 zip_uint8_t b[4];
327 zip_buffer_t *buffer = _zip_buffer_new(b, sizeof(b));
328
329 if (buffer == NULL) {
330 return -1;
331 }
332
333 for (; ef; ef=ef->next) {
334 if (ef->flags & flags & ZIP_EF_BOTH) {
335 _zip_buffer_set_offset(buffer, 0);
336 _zip_buffer_put_16(buffer, ef->id);
337 _zip_buffer_put_16(buffer, ef->size);
338 if (!_zip_buffer_ok(buffer)) {
339 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
340 _zip_buffer_free(buffer);
341 return -1;
342 }
343 if (_zip_write(za, b, 4) < 0) {
344 _zip_buffer_free(buffer);
345 return -1;
346 }
347 if (ef->size > 0) {
348 if (_zip_write(za, ef->data, ef->size) < 0) {
349 _zip_buffer_free(buffer);
350 return -1;
351 }
352 }
353 }
354 }
355
356 _zip_buffer_free(buffer);
357 return 0;
358 }
359
360
361 int
362 _zip_read_local_ef(zip_t *za, zip_uint64_t idx)
363 {
364 zip_entry_t *e;
365 unsigned char b[4];
366 zip_buffer_t *buffer;
367 zip_uint16_t fname_len, ef_len;
368
369 if (idx >= za->nentry) {
370 zip_error_set(&za->error, ZIP_ER_INVAL, 0);
371 return -1;
372 }
373
374 e = za->entry+idx;
375
376 if (e->orig == NULL || e->orig->local_extra_fields_read)
377 return 0;
378
379 if (e->orig->offset + 26 > ZIP_INT64_MAX) {
380 zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG);
381 return -1;
382 }
383
384 if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
385 _zip_error_set_from_source(&za->error, za->src);
386 return -1;
387 }
388
389 if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) {
390 return -1;
391 }
392
393 fname_len = _zip_buffer_get_16(buffer);
394 ef_len = _zip_buffer_get_16(buffer);
395
396 if (!_zip_buffer_eof(buffer)) {
397 _zip_buffer_free(buffer);
398 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
399 return -1;
400 }
401
402 _zip_buffer_free(buffer);
403
404 if (ef_len > 0) {
405 zip_extra_field_t *ef;
406 zip_uint8_t *ef_raw;
407
408 if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) {
409 zip_error_set(&za->error, ZIP_ER_SEEK, errno);
410 return -1;
411 }
412
413 ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error);
414
415 if (ef_raw == NULL)
416 return -1;
417
418 if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) {
419 free(ef_raw);
420 return -1;
421 }
422 free(ef_raw);
423
424 if (ef) {
425 ef = _zip_ef_remove_internal(ef);
426 e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
427 }
428 }
429
430 e->orig->local_extra_fields_read = 1;
431
432 if (e->changes && e->changes->local_extra_fields_read == 0) {
433 e->changes->extra_fields = e->orig->extra_fields;
434 e->changes->local_extra_fields_read = 1;
435 }
436
437 return 0;
438 }