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