Rizin
unix-like reverse engineering framework and cli tools
zip_source_file_common.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
#include "zip_source_file.h"

Go to the source code of this file.

Functions

static zip_int64_t read_file (void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
 
static void zip_source_file_stat_init (zip_source_file_stat_t *st)
 
zip_source_tzip_source_file_common_new (const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error)
 

Function Documentation

◆ read_file()

static zip_int64_t read_file ( void *  state,
void *  data,
zip_uint64_t  len,
zip_source_cmd_t  cmd 
)
static

Definition at line 204 of file zip_source_file_common.c.

204  {
206  char *buf;
207 
209  buf = (char *)data;
210 
211  switch (cmd) {
213  return 0;
214 
216  /* write support should not be set if fname is NULL */
217  if (ctx->fname == NULL) {
219  return -1;
220  }
221  return ctx->ops->create_temp_output(ctx);
222 
224  /* write support should not be set if fname is NULL */
225  if (ctx->fname == NULL) {
227  return -1;
228  }
229  return ctx->ops->create_temp_output_cloning(ctx, len);
230 
231  case ZIP_SOURCE_CLOSE:
232  if (ctx->fname) {
233  ctx->ops->close(ctx);
234  ctx->f = NULL;
235  }
236  return 0;
237 
239  zip_int64_t ret = ctx->ops->commit_write(ctx);
240  ctx->fout = NULL;
241  if (ret == 0) {
242  free(ctx->tmpname);
243  ctx->tmpname = NULL;
244  }
245  return ret;
246  }
247 
248  case ZIP_SOURCE_ERROR:
249  return zip_error_to_data(&ctx->error, data, len);
250 
251  case ZIP_SOURCE_FREE:
252  free(ctx->fname);
253  free(ctx->tmpname);
254  if (ctx->f) {
255  ctx->ops->close(ctx);
256  }
257  free(ctx);
258  return 0;
259 
261  if (len < sizeof(ctx->attributes)) {
263  return -1;
264  }
265  memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
266  return sizeof(ctx->attributes);
267 
268  case ZIP_SOURCE_OPEN:
269  if (ctx->fname) {
270  if (ctx->ops->open(ctx) == false) {
271  return -1;
272  }
273  }
274 
275  if (ctx->start > 0) { // TODO: rewind on re-open
276  if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) {
277  /* TODO: skip by reading */
278  return -1;
279  }
280  }
281  ctx->offset = 0;
282  return 0;
283 
284  case ZIP_SOURCE_READ: {
285  zip_int64_t i;
286  zip_uint64_t n;
287 
288  if (ctx->len > 0) {
289  n = ZIP_MIN(ctx->len - ctx->offset, len);
290  }
291  else {
292  n = len;
293  }
294 
295  if ((i = ctx->ops->read(ctx, buf, n)) < 0) {
296  zip_error_set(&ctx->error, ZIP_ER_READ, errno);
297  return -1;
298  }
299  ctx->offset += (zip_uint64_t)i;
300 
301  return i;
302  }
303 
304  case ZIP_SOURCE_REMOVE:
305  return ctx->ops->remove(ctx);
306 
308  ctx->ops->rollback_write(ctx);
309  ctx->fout = NULL;
310  free(ctx->tmpname);
311  ctx->tmpname = NULL;
312  return 0;
313 
314  case ZIP_SOURCE_SEEK: {
315  zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset, ctx->len, data, len, &ctx->error);
316 
317  if (new_offset < 0) {
318  return -1;
319  }
320 
321  /* The actual offset inside the file must be representable as zip_int64_t. */
322  if (new_offset > ZIP_INT64_MAX - (zip_int64_t)ctx->start) {
324  return -1;
325  }
326 
327  ctx->offset = (zip_uint64_t)new_offset;
328 
329  if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)(ctx->offset + ctx->start), SEEK_SET) == false) {
330  return -1;
331  }
332  return 0;
333  }
334 
335  case ZIP_SOURCE_SEEK_WRITE: {
337 
339  if (args == NULL) {
340  return -1;
341  }
342 
343  if (ctx->ops->seek(ctx, ctx->fout, args->offset, args->whence) == false) {
344  return -1;
345  }
346  return 0;
347  }
348 
349  case ZIP_SOURCE_STAT: {
350  if (len < sizeof(ctx->st))
351  return -1;
352 
353  if (zip_error_code_zip(&ctx->stat_error) != 0) {
354  zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error));
355  return -1;
356  }
357 
358  memcpy(data, &ctx->st, sizeof(ctx->st));
359  return sizeof(ctx->st);
360  }
361 
362  case ZIP_SOURCE_SUPPORTS:
363  return ctx->supports;
364 
365  case ZIP_SOURCE_TELL:
366  return (zip_int64_t)ctx->offset;
367 
369  return ctx->ops->tell(ctx, ctx->fout);
370 
371  case ZIP_SOURCE_WRITE:
372  return ctx->ops->write(ctx, data, len);
373 
374  default:
376  return -1;
377  }
378 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define EOVERFLOW
Definition: compat.h:75
#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 cmd
Definition: sflib.h:79
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define ZIP_ER_INTERNAL
Definition: zip.h:125
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int)
Definition: zip_error.c:126
#define ZIP_ER_SEEK
Definition: zip.h:109
ZIP_EXTERN int zip_error_code_system(const zip_error_t *_Nonnull)
Definition: zip_error.c:40
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_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_ACCEPT_EMPTY
Definition: zip.h:238
@ ZIP_SOURCE_BEGIN_WRITE_CLONING
Definition: zip.h:237
@ ZIP_SOURCE_SEEK
Definition: zip.h:226
@ ZIP_SOURCE_SEEK_WRITE
Definition: zip.h:232
@ 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_REMOVE
Definition: zip.h:235
@ ZIP_SOURCE_ROLLBACK_WRITE
Definition: zip.h:230
@ ZIP_SOURCE_TELL_WRITE
Definition: zip.h:233
@ ZIP_SOURCE_BEGIN_WRITE
Definition: zip.h:228
@ ZIP_SOURCE_WRITE
Definition: zip.h:231
@ ZIP_SOURCE_ERROR
Definition: zip.h:224
@ ZIP_SOURCE_COMMIT_WRITE
Definition: zip.h:229
#define ZIP_ER_INVAL
Definition: zip.h:123
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
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_ER_READ
Definition: zip.h:110
#define ZIP_SOURCE_GET_ARGS(type, data, len, error)
Definition: zip.h:279
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
zip_error_t * error
Definition: dis.h:43
#define SEEK_SET
Definition: zip.c:88
uint64_t zip_uint64_t
Definition: zipconf.h:39
#define ZIP_INT64_MAX
Definition: zipconf.h:54
int64_t zip_int64_t
Definition: zipconf.h:38
#define ZIP_MIN(a, b)
Definition: zipint.h:473

References args, cmd, EOVERFLOW, ctx::error, free(), i, len, memcpy(), n, NULL, SEEK_SET, ZIP_ER_INTERNAL, ZIP_ER_INVAL, ZIP_ER_OPNOTSUPP, ZIP_ER_READ, ZIP_ER_SEEK, zip_error_code_system(), zip_error_code_zip(), zip_error_set(), zip_error_to_data(), ZIP_INT64_MAX, ZIP_MIN, ZIP_SOURCE_ACCEPT_EMPTY, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_CLOSE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_ARGS, ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK, zip_source_seek_compute_offset(), ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_STAT, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_TELL_WRITE, and ZIP_SOURCE_WRITE.

Referenced by zip_source_file_common_new().

◆ zip_source_file_common_new()

zip_source_t* zip_source_file_common_new ( const char *  fname,
void *  file,
zip_uint64_t  start,
zip_int64_t  len,
const zip_stat_t st,
zip_source_file_operations_t ops,
void *  ops_userdata,
zip_error_t error 
)

Definition at line 53 of file zip_source_file_common.c.

53  {
55  zip_source_t *zs;
57 
58  if (ops == NULL) {
60  return NULL;
61  }
62 
63  if (ops->close == NULL || ops->read == NULL || ops->seek == NULL || ops->stat == NULL) {
65  return NULL;
66  }
67 
68  if (ops->write != NULL && (ops->commit_write == NULL || ops->create_temp_output == NULL || ops->remove == NULL || ops->rollback_write == NULL || ops->tell == NULL)) {
70  return NULL;
71  }
72 
73  if (fname != NULL) {
74  if (ops->open == NULL || ops->string_duplicate == NULL) {
76  return NULL;
77  }
78  }
79  else if (file == NULL) {
81  return NULL;
82  }
83 
84  if (len < 0) {
85  len = 0;
86  }
87 
90  return NULL;
91  }
92 
95  return NULL;
96  }
97 
98  ctx->ops = ops;
99  ctx->ops_userdata = ops_userdata;
100  ctx->fname = NULL;
101  if (fname) {
102  if ((ctx->fname = ops->string_duplicate(ctx, fname)) == NULL) {
104  free(ctx);
105  return NULL;
106  }
107  }
108  ctx->f = file;
109  ctx->start = start;
110  ctx->len = (zip_uint64_t)len;
111  if (st) {
112  memcpy(&ctx->st, st, sizeof(ctx->st));
113  ctx->st.name = NULL;
114  ctx->st.valid &= ~ZIP_STAT_NAME;
115  }
116  else {
117  zip_stat_init(&ctx->st);
118  }
119 
120  if (ctx->len > 0) {
121  ctx->st.size = ctx->len;
122  ctx->st.valid |= ZIP_STAT_SIZE;
123  }
124 
125  zip_error_init(&ctx->stat_error);
126 
127  ctx->tmpname = NULL;
128  ctx->fout = NULL;
129 
131  zip_file_attributes_init(&ctx->attributes);
132 
134 
136  if (!ops->stat(ctx, &sb)) {
138  free(ctx->fname);
139  free(ctx);
140  return NULL;
141  }
142 
143  if (!sb.exists) {
144  if (ctx->fname && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) {
145  ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
146  /* zip_open_from_source checks for this to detect non-existing files */
147  zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
148  }
149  else {
150  zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
151  free(ctx->fname);
152  free(ctx);
153  return NULL;
154  }
155  }
156  else {
157  if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
158  ctx->st.mtime = sb.mtime;
159  ctx->st.valid |= ZIP_STAT_MTIME;
160  }
161  if (sb.regular_file) {
162  ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
163 
164  if (ctx->start + ctx->len > sb.size) {
166  free(ctx->fname);
167  free(ctx);
168  return NULL;
169  }
170 
171  if (ctx->len == 0) {
172  ctx->len = sb.size - ctx->start;
173  ctx->st.size = ctx->len;
174  ctx->st.valid |= ZIP_STAT_SIZE;
175 
176  /* when using a partial file, don't allow writing */
177  if (ctx->fname && start == 0 && ops->write != NULL) {
178  ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
179  }
180  }
181  }
182 
184  }
185 
187  if (ops->create_temp_output_cloning != NULL) {
190  }
191  }
192 
194  free(ctx->fname);
195  free(ctx);
196  return NULL;
197  }
198 
199  return zs;
200 }
static struct @29 ops[]
static SblHeader sb
Definition: bin_mbn.c:26
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
#define ZIP_STAT_NAME
Definition: zip.h:290
#define ZIP_SOURCE_SUPPORTS_SEEKABLE
Definition: zip.h:256
#define ZIP_SOURCE_SUPPORTS_READABLE
Definition: zip.h:249
ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull)
#define ZIP_SOURCE_SUPPORTS_WRITABLE
Definition: zip.h:261
#define ZIP_ER_MEMORY
Definition: zip.h:119
#define ZIP_STAT_SIZE
Definition: zip.h:292
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_SOURCE_MAKE_COMMAND_BITMASK(cmd)
Definition: zip.h:243
ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable)
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t,...)
#define ZIP_STAT_MTIME
Definition: zip.h:294
void * malloc(size_t size)
Definition: malloc.c:123
#define ENOENT
Definition: sftypes.h:112
Definition: gzappend.c:170
void error(const char *msg)
Definition: untgz.c:593
static int file
Definition: z80asm.c:58
void _zip_error_copy(zip_error_t *dst, const zip_error_t *src)
Definition: zip_error.c:102
static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
static void zip_source_file_stat_init(zip_source_file_stat_t *st)

References _zip_error_copy(), ENOENT, ctx::error, error(), file, create_tags_rz::fname, free(), len, malloc(), memcpy(), NULL, ops, read_file(), sb, start, ZIP_ER_INTERNAL, ZIP_ER_INVAL, ZIP_ER_MEMORY, ZIP_ER_READ, zip_error_init(), zip_error_set(), zip_file_attributes_init(), ZIP_INT64_MAX, ZIP_SOURCE_ACCEPT_EMPTY, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, zip_source_file_stat_init(), zip_source_function_create(), ZIP_SOURCE_GET_FILE_ATTRIBUTES, zip_source_make_command_bitmap(), ZIP_SOURCE_MAKE_COMMAND_BITMASK, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_SUPPORTS_READABLE, ZIP_SOURCE_SUPPORTS_SEEKABLE, ZIP_SOURCE_SUPPORTS_WRITABLE, ZIP_SOURCE_TELL, zip_stat_init(), ZIP_STAT_MTIME, ZIP_STAT_NAME, and ZIP_STAT_SIZE.

Referenced by zip_source_file_create(), zip_source_filep_create(), zip_source_win32a_create(), zip_source_win32handle_create(), and zip_source_win32w_create().

◆ zip_source_file_stat_init()

static void zip_source_file_stat_init ( zip_source_file_stat_t st)
static

Definition at line 45 of file zip_source_file_common.c.

45  {
46  st->size = 0;
47  st->mtime = time(NULL);
48  st->exists = false;
49  st->regular_file = false;
50 }
static static fork const void static count static fd const char const char static newpath char char char static envp time
Definition: sflib.h:42

References zip_source_file_stat::exists, zip_source_file_stat::mtime, NULL, zip_source_file_stat::regular_file, zip_source_file_stat::size, and time.

Referenced by zip_source_file_common_new().