Rizin
unix-like reverse engineering framework and cli tools
zip_extra_field_api.c
Go to the documentation of this file.
1 /*
2  zip_extra_field_api.c -- public extra fields API functions
3  Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
4 
5  This file is part of libzip, a library to manipulate ZIP archives.
6  The authors can be contacted at <info@libzip.org>
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11  1. Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in
15  the documentation and/or other materials provided with the
16  distribution.
17  3. The names of the authors may not be used to endorse or promote
18  products derived from this software without specific prior
19  written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 
35 #include "zipint.h"
36 
37 
38 ZIP_EXTERN int
40  zip_dirent_t *de;
41 
42  if ((flags & ZIP_EF_BOTH) == 0) {
44  return -1;
45  }
46 
47  if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
49  return -1;
50  }
51 
52  if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
53  return -1;
54 
55  if (ZIP_IS_RDONLY(za)) {
57  return -1;
58  }
59 
61  return -1;
62 
63  de = za->entry[idx].changes;
64 
66  return 0;
67 }
68 
69 
70 ZIP_EXTERN int
72  zip_dirent_t *de;
73 
74  if ((flags & ZIP_EF_BOTH) == 0) {
76  return -1;
77  }
78 
79  if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
81  return -1;
82  }
83 
84  if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
85  return -1;
86 
87  if (ZIP_IS_RDONLY(za)) {
89  return -1;
90  }
91 
93  return -1;
94 
95  de = za->entry[idx].changes;
96 
97  de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
98  return 0;
99 }
100 
101 
102 ZIP_EXTERN const zip_uint8_t *
104  static const zip_uint8_t empty[1] = {'\0'};
105 
106  zip_dirent_t *de;
108  int i;
109 
110  if ((flags & ZIP_EF_BOTH) == 0) {
112  return NULL;
113  }
114 
115  if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
116  return NULL;
117 
118  if (flags & ZIP_FL_LOCAL)
119  if (_zip_read_local_ef(za, idx) < 0)
120  return NULL;
121 
122  i = 0;
123  for (ef = de->extra_fields; ef; ef = ef->next) {
124  if (ef->flags & flags & ZIP_EF_BOTH) {
125  if (i < ef_idx) {
126  i++;
127  continue;
128  }
129 
130  if (idp)
131  *idp = ef->id;
132  if (lenp)
133  *lenp = ef->size;
134  if (ef->size > 0)
135  return ef->data;
136  else
137  return empty;
138  }
139  }
140 
142  return NULL;
143 }
144 
145 
146 ZIP_EXTERN const zip_uint8_t *
148  zip_dirent_t *de;
149 
150  if ((flags & ZIP_EF_BOTH) == 0) {
152  return NULL;
153  }
154 
155  if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
156  return NULL;
157 
158  if (flags & ZIP_FL_LOCAL)
159  if (_zip_read_local_ef(za, idx) < 0)
160  return NULL;
161 
162  return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
163 }
164 
165 
168  zip_dirent_t *de;
170  zip_uint16_t n;
171 
172  if ((flags & ZIP_EF_BOTH) == 0) {
174  return -1;
175  }
176 
177  if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
178  return -1;
179 
180  if (flags & ZIP_FL_LOCAL)
181  if (_zip_read_local_ef(za, idx) < 0)
182  return -1;
183 
184  n = 0;
185  for (ef = de->extra_fields; ef; ef = ef->next)
186  if (ef->flags & flags & ZIP_EF_BOTH)
187  n++;
188 
189  return (zip_int16_t)n;
190 }
191 
192 
195  zip_dirent_t *de;
197  zip_uint16_t n;
198 
199  if ((flags & ZIP_EF_BOTH) == 0) {
201  return -1;
202  }
203 
204  if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
205  return -1;
206 
207  if (flags & ZIP_FL_LOCAL)
208  if (_zip_read_local_ef(za, idx) < 0)
209  return -1;
210 
211  n = 0;
212  for (ef = de->extra_fields; ef; ef = ef->next)
213  if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
214  n++;
215 
216  return (zip_int16_t)n;
217 }
218 
219 
220 ZIP_EXTERN int
222  zip_dirent_t *de;
223  zip_uint16_t ls, cs;
224  zip_extra_field_t *ef, *ef_prev, *ef_new;
225  int i, found, new_len;
226 
227  if ((flags & ZIP_EF_BOTH) == 0) {
229  return -1;
230  }
231 
232  if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
233  return -1;
234 
235  if (ZIP_IS_RDONLY(za)) {
237  return -1;
238  }
239 
240  if (ZIP_EF_IS_INTERNAL(ef_id)) {
242  return -1;
243  }
244 
246  return -1;
247 
248  de = za->entry[idx].changes;
249 
250  ef = de->extra_fields;
251  ef_prev = NULL;
252  i = 0;
253  found = 0;
254 
255  for (; ef; ef = ef->next) {
256  if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
257  if (i == ef_idx) {
258  found = 1;
259  break;
260  }
261  i++;
262  }
263  ef_prev = ef;
264  }
265 
266  if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
268  return -1;
269  }
270 
271  if (flags & ZIP_EF_LOCAL)
273  else
274  ls = 0;
275  if (flags & ZIP_EF_CENTRAL)
277  else
278  cs = 0;
279 
280  new_len = ls > cs ? ls : cs;
281  if (found)
282  new_len -= ef->size + 4;
283  new_len += len + 4;
284 
285  if (new_len > ZIP_UINT16_MAX) {
287  return -1;
288  }
289 
290  if ((ef_new = _zip_ef_new(ef_id, len, data, flags)) == NULL) {
292  return -1;
293  }
294 
295  if (found) {
296  if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
297  ef_new->next = ef->next;
298  ef->next = NULL;
299  _zip_ef_free(ef);
300  if (ef_prev)
301  ef_prev->next = ef_new;
302  else
303  de->extra_fields = ef_new;
304  }
305  else {
306  ef->flags &= ~(flags & ZIP_EF_BOTH);
307  ef_new->next = ef->next;
308  ef->next = ef_new;
309  }
310  }
311  else if (ef_prev) {
312  ef_new->next = ef_prev->next;
313  ef_prev->next = ef_new;
314  }
315  else
316  de->extra_fields = ef_new;
317 
318  return 0;
319 }
320 
321 
322 int
324  zip_entry_t *e;
325 
326  if (idx >= za->nentry) {
328  return -1;
329  }
330 
331  e = za->entry + idx;
332 
333  if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
334  return 0;
335 
336  if (e->orig) {
337  if (_zip_read_local_ef(za, idx) < 0)
338  return -1;
339  }
340 
341  if (e->changes == NULL) {
342  if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
344  return -1;
345  }
346  }
347 
348  if (e->orig && e->orig->extra_fields) {
349  if ((e->changes->extra_fields = _zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
350  return -1;
351  }
352  e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
353 
354  return 0;
355 }
size_t len
Definition: 6502dis.c:15
#define ef(frag,...)
#define e(frag)
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int)
Definition: zip_error.c:126
#define ZIP_EXTRA_FIELD_ALL
Definition: zip.h:99
#define ZIP_ER_MEMORY
Definition: zip.h:119
#define ZIP_ER_NOENT
Definition: zip.h:114
#define ZIP_FL_LOCAL
Definition: zip.h:85
#define ZIP_EXTERN
Definition: zip.h:54
#define ZIP_EXTRA_FIELD_NEW
Definition: zip.h:100
#define ZIP_ER_RDONLY
Definition: zip.h:130
#define ZIP_ER_INVAL
Definition: zip.h:123
zip_uint32_t zip_flags_t
Definition: zip.h:347
int n
Definition: mipsasm.c:19
int idx
Definition: setup.py:197
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
Definition: zipcmp.c:69
zip_uint16_t size
Definition: zipcmp.c:73
zip_uint16_t id
Definition: zipcmp.c:72
const zip_uint8_t * data
Definition: zipcmp.c:74
zip_uint16_t flags
Definition: zipcmp.c:71
zip_extra_field_t * extra_fields
Definition: zipint.h:342
Definition: zipint.h:408
zip_dirent_t * changes
Definition: zipint.h:410
zip_extra_field_t * next
Definition: zipint.h:368
Definition: zipint.h:278
zip_error_t error
Definition: zipint.h:281
zip_entry_t * entry
Definition: zipint.h:294
zip_uint64_t nentry
Definition: zipint.h:292
zip_dirent_t * _zip_dirent_clone(const zip_dirent_t *sde)
Definition: zip_dirent.c:215
zip_dirent_t * _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
Definition: zip_dirent.c:1064
zip_extra_field_t * _zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags)
zip_uint16_t _zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags)
int _zip_read_local_ef(zip_t *za, zip_uint64_t idx)
zip_extra_field_t * _zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error)
zip_extra_field_t * _zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags)
const zip_uint8_t * _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)
void _zip_ef_free(zip_extra_field_t *ef)
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
ZIP_EXTERN const zip_uint8_t * 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)
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags)
ZIP_EXTERN int 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)
ZIP_EXTERN int 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)
ZIP_EXTERN int zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags)
ZIP_EXTERN const zip_uint8_t * 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)
int _zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx)
int16_t zip_int16_t
Definition: zipconf.h:34
#define ZIP_UINT16_MAX
Definition: zipconf.h:47
uint64_t zip_uint64_t
Definition: zipconf.h:39
uint8_t zip_uint8_t
Definition: zipconf.h:33
uint16_t zip_uint16_t
Definition: zipconf.h:35
#define ZIP_IS_RDONLY(za)
Definition: zipint.h:479
#define ZIP_EF_BOTH
Definition: zipint.h:245
#define ZIP_EF_CENTRAL
Definition: zipint.h:244
#define ZIP_EF_LOCAL
Definition: zipint.h:243
#define ZIP_DIRENT_EXTRA_FIELD
Definition: zipint.h:319
#define ZIP_EF_IS_INTERNAL(id)
Definition: zipint.h:90
zip_t * za
Definition: ziptool.c:79