Rizin
unix-like reverse engineering framework and cli tools
zip_source_window.c
Go to the documentation of this file.
1 /*
2  zip_source_window.c -- return part of lower source
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 <stdlib.h>
36 #include <string.h>
37 
38 #include "zipint.h"
39 
40 struct window {
41  zip_uint64_t start; /* where in file we start reading */
42  zip_uint64_t end; /* where in file we stop reading */
43  bool end_valid; /* whether end is set, otherwise read until EOF */
44 
45  /* if not NULL, read file data for this file */
48 
49  zip_uint64_t offset; /* offset in src for next read */
50 
55  bool needs_seek;
56 };
57 
59 
60 
63  return _zip_source_window_new(src, start, len, NULL, 0, NULL, 0, error);
64 }
65 
66 
69  struct window *ctx;
70 
71  if (src == NULL || length < -1 || (source_archive == NULL && source_index != 0)) {
73  return NULL;
74  }
75 
76  if (length >= 0) {
77  if (start + (zip_uint64_t)length < start) {
79  return NULL;
80  }
81  }
82 
83  if ((ctx = (struct window *)malloc(sizeof(*ctx))) == NULL) {
85  return NULL;
86  }
87 
88  ctx->start = start;
89  if (length == -1) {
90  ctx->end_valid = false;
91  }
92  else {
93  ctx->end = start + (zip_uint64_t)length;
94  ctx->end_valid = true;
95  }
96  zip_stat_init(&ctx->stat);
97  if (attributes != NULL) {
98  memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
99  }
100  else {
101  zip_file_attributes_init(&ctx->attributes);
102  }
103  ctx->source_archive = source_archive;
104  ctx->source_index = source_index;
107  ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
108 
109  if (st) {
110  if (_zip_stat_merge(&ctx->stat, st, error) < 0) {
111  free(ctx);
112  return NULL;
113  }
114  }
115 
117 }
118 
119 
120 int
122  src->source_archive = za;
123  return _zip_register_source(za, src);
124 }
125 
126 
127 /* called by zip_discard to avoid operating on file from closed archive */
128 void
130  src->source_closed = 1;
131 
132  if (zip_error_code_zip(&src->error) == ZIP_ER_OK) {
133  zip_error_set(&src->error, ZIP_ER_ZIPCLOSED, 0);
134  }
135 }
136 
137 
138 static zip_int64_t
140  struct window *ctx;
141  zip_int64_t ret;
142  zip_uint64_t n, i;
143 
144  ctx = (struct window *)_ctx;
145 
146  switch (cmd) {
147  case ZIP_SOURCE_CLOSE:
148  return 0;
149 
150  case ZIP_SOURCE_ERROR:
151  return zip_error_to_data(&ctx->error, data, len);
152 
153  case ZIP_SOURCE_FREE:
154  free(ctx);
155  return 0;
156 
157  case ZIP_SOURCE_OPEN:
158  if (ctx->source_archive) {
160 
161  if ((offset = _zip_file_get_offset(ctx->source_archive, ctx->source_index, &ctx->error)) == 0) {
162  return -1;
163  }
164  if (ctx->end + offset < ctx->end) {
165  /* zip archive data claims end of data past zip64 limits */
167  return -1;
168  }
169  ctx->start += offset;
170  ctx->end += offset;
171  ctx->source_archive = NULL;
172  }
173 
174  if (!ctx->needs_seek) {
176 
177  if (!byte_array_init(b, BUFSIZE)) {
179  return -1;
180  }
181 
182  for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) {
183  i = (ctx->start - n > BUFSIZE ? BUFSIZE : ctx->start - n);
184  if ((ret = zip_source_read(src, b, i)) < 0) {
187  return -1;
188  }
189  if (ret == 0) {
192  return -1;
193  }
194  }
195 
197  }
198 
199  ctx->offset = ctx->start;
200  return 0;
201 
202  case ZIP_SOURCE_READ:
203  if (ctx->end_valid && len > ctx->end - ctx->offset) {
204  len = ctx->end - ctx->offset;
205  }
206 
207  if (len == 0) {
208  return 0;
209  }
210 
211  if (ctx->needs_seek) {
212  if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) {
214  return -1;
215  }
216  }
217 
218  if ((ret = zip_source_read(src, data, len)) < 0) {
220  return -1;
221  }
222 
223  ctx->offset += (zip_uint64_t)ret;
224 
225  if (ret == 0) {
226  if (ctx->end_valid && ctx->offset < ctx->end) {
228  return -1;
229  }
230  }
231  return ret;
232 
233  case ZIP_SOURCE_SEEK: {
234  zip_int64_t new_offset;
235 
236  if (!ctx->end_valid) {
238 
239  if (args == NULL) {
240  return -1;
241  }
242  if (args->whence == SEEK_END) {
243  if (zip_source_seek(src, args->offset, args->whence) < 0) {
245  return -1;
246  }
247  new_offset = zip_source_tell(src);
248  if (new_offset < 0) {
250  return -1;
251  }
252  if ((zip_uint64_t)new_offset < ctx->start) {
254  (void)zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET);
255  return -1;
256  }
257  ctx->offset = (zip_uint64_t)new_offset;
258  return 0;
259  }
260  }
261 
262  new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error);
263 
264  if (new_offset < 0) {
265  return -1;
266  }
267 
268  ctx->offset = (zip_uint64_t)new_offset + ctx->start;
269  return 0;
270  }
271 
272  case ZIP_SOURCE_STAT: {
273  zip_stat_t *st;
274 
275  st = (zip_stat_t *)data;
276 
277  if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) {
278  return -1;
279  }
280  return 0;
281  }
282 
284  if (len < sizeof(ctx->attributes)) {
286  return -1;
287  }
288 
289  memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
290  return sizeof(ctx->attributes);
291 
292  case ZIP_SOURCE_SUPPORTS:
293  return ctx->supports;
294 
295  case ZIP_SOURCE_TELL:
296  return (zip_int64_t)(ctx->offset - ctx->start);
297 
298  default:
300  return -1;
301  }
302 }
303 
304 
305 void
307  unsigned int i;
308 
309  for (i = 0; i < za->nopen_source; i++) {
310  if (za->open_source[i] == src) {
312  za->nopen_source--;
313  break;
314  }
315  }
316 }
317 
318 
319 int
321  zip_source_t **open_source;
322 
323  if (za->nopen_source + 1 >= za->nopen_source_alloc) {
324  unsigned int n;
325  n = za->nopen_source_alloc + 10;
326  open_source = (zip_source_t **)realloc(za->open_source, n * sizeof(zip_source_t *));
327  if (open_source == NULL) {
329  return -1;
330  }
332  za->open_source = open_source;
333  }
334 
336 
337  return 0;
338 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf uLong offset
Definition: ioapi.h:144
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int)
Definition: zip_error.c:126
#define ZIP_SOURCE_SUPPORTS_SEEKABLE
Definition: zip.h:256
ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull)
#define ZIP_ER_MEMORY
Definition: zip.h:119
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t)
ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *_Nonnull, zip_uint64_t, zip_error_t *_Nullable)
ZIP_EXTERN int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int)
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull)
ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull)
Definition: zip_stat_init.c:40
ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull)
Definition: zip_error.c:59
#define ZIP_EXTERN
Definition: zip.h:54
#define ZIP_ER_ZIPCLOSED
Definition: zip.h:113
enum zip_source_cmd zip_source_cmd_t
Definition: zip.h:241
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd)
Definition: zip.h:243
@ ZIP_SOURCE_CLOSE
Definition: zip.h:222
@ ZIP_SOURCE_READ
Definition: zip.h:221
@ ZIP_SOURCE_GET_FILE_ATTRIBUTES
Definition: zip.h:239
@ ZIP_SOURCE_FREE
Definition: zip.h:225
@ ZIP_SOURCE_SEEK
Definition: zip.h:226
@ ZIP_SOURCE_SUPPORTS
Definition: zip.h:234
@ ZIP_SOURCE_STAT
Definition: zip.h:223
@ ZIP_SOURCE_TELL
Definition: zip.h:227
@ ZIP_SOURCE_OPEN
Definition: zip.h:220
@ ZIP_SOURCE_ERROR
Definition: zip.h:224
#define ZIP_ER_OK
Definition: zip.h:105
#define ZIP_ER_INVAL
Definition: zip.h:123
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t,...)
ZIP_EXTERN int zip_error_code_zip(const zip_error_t *_Nonnull)
Definition: zip_error.c:46
#define ZIP_ER_OPNOTSUPP
Definition: zip.h:133
#define ZIP_ER_EOF
Definition: zip.h:122
#define ZIP_ER_INCONS
Definition: zip.h:126
ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, zip_uint64_t)
Definition: zip_error.c:141
#define ZIP_SOURCE_GET_ARGS(type, data, len, error)
Definition: zip.h:279
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
#define BUFSIZE
#define b(i)
Definition: sha256.c:42
zip_error_t * error
zip_stat_t stat
bool end_valid
zip_uint64_t end
zip_uint64_t start
zip_uint64_t offset
zip_t * source_archive
zip_int64_t supports
zip_error_t error
bool needs_seek
zip_uint64_t source_index
zip_file_attributes_t attributes
Definition: zip.h:284
Definition: zip.h:300
Definition: zipint.h:278
zip_source_t ** open_source
Definition: zipint.h:298
zip_error_t error
Definition: zipint.h:281
unsigned int nopen_source
Definition: zipint.h:296
unsigned int nopen_source_alloc
Definition: zipint.h:297
void error(const char *msg)
Definition: untgz.c:593
#define SEEK_SET
Definition: zip.c:88
#define SEEK_END
Definition: zip.c:84
void _zip_error_set_from_source(zip_error_t *err, zip_source_t *src)
Definition: zip_error.c:135
zip_uint64_t _zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error)
zip_source_t * zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error)
zip_int64_t zip_source_supports(zip_source_t *src)
static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t)
ZIP_EXTERN zip_source_t * zip_source_window_create(zip_source_t *src, zip_uint64_t start, zip_int64_t len, zip_error_t *error)
int _zip_source_set_source_archive(zip_source_t *src, zip_t *za)
void _zip_source_invalidate(zip_source_t *src)
zip_source_t * _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error)
void _zip_deregister_source(zip_t *za, zip_source_t *src)
int _zip_register_source(zip_t *za, zip_source_t *src)
int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error)
Definition: zip_stat_init.c:54
uint64_t zip_uint64_t
Definition: zipconf.h:39
int64_t zip_int64_t
Definition: zipconf.h:38
#define MAKE_DETAIL_WITH_INDEX(error, index)
Definition: zipint.h:207
#define byte_array_fini(buf)
Definition: zipint.h:440
#define byte_array_init(buf, size)
Definition: zipint.h:439
#define DEFINE_BYTE_ARRAY(buf, size)
Definition: zipint.h:438
#define ZIP_ER_DETAIL_CDIR_ENTRY_INVALID
Definition: zipint.h:217
zip_t * za
Definition: ziptool.c:79