Rizin
unix-like reverse engineering framework and cli tools
zip_source_file_stdio.c
Go to the documentation of this file.
1 /*
2  zip_source_file_stdio.c -- read-only stdio file source implementation
3  Copyright (C) 2020 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 #include "zipint.h"
35 
36 #include "zip_source_file.h"
37 #include "zip_source_file_stdio.h"
38 
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <sys/stat.h>
43 
44 #ifdef _WIN32
45 #ifndef S_IWUSR
46 #define S_IWUSR _S_IWRITE
47 #endif
48 #endif
49 
50 /* clang-format off */
53  NULL,
54  NULL,
55  NULL,
56  NULL,
58  NULL,
59  NULL,
62  NULL,
64  NULL
65 };
66 /* clang-format on */
67 
68 
71  if (za == NULL) {
72  return NULL;
73  }
74 
76 }
77 
78 
81  if (file == NULL || length < -1) {
83  return NULL;
84  }
85 
87 }
88 
89 
90 void
92  fclose((FILE *)ctx->f);
93 }
94 
95 
98  size_t i;
99  if (len > SIZE_MAX) {
100  len = SIZE_MAX;
101  }
102 
103  if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) {
104  if (ferror((FILE *)ctx->f)) {
105  zip_error_set(&ctx->error, ZIP_ER_READ, errno);
106  return -1;
107  }
108  }
109 
110  return (zip_int64_t)i;
111 }
112 
113 
114 bool
116 #if ZIP_FSEEK_MAX > ZIP_INT64_MAX
119  return false;
120  }
121 #endif
122 
123  if (fseeko((FILE *)f, (off_t)offset, whence) < 0) {
124  zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
125  return false;
126  }
127  return true;
128 }
129 
130 
131 bool
133  struct stat sb;
134 
135  int ret;
136 
137  if (ctx->fname) {
138  ret = stat(ctx->fname, &sb);
139  }
140  else {
141  ret = fstat(fileno((FILE *)ctx->f), &sb);
142  }
143 
144  if (ret < 0) {
145  if (errno == ENOENT) {
146  st->exists = false;
147  return true;
148  }
149  zip_error_set(&ctx->error, ZIP_ER_READ, errno);
150  return false;
151  }
152 
153  st->size = (zip_uint64_t)sb.st_size;
154  st->mtime = sb.st_mtime;
155 
156  st->regular_file = S_ISREG(sb.st_mode);
157  st->exists = true;
158 
159  /* We're using UNIX file API, even on Windows; thus, we supply external file attributes with Unix values. */
160  /* TODO: This could be improved on Windows by providing Windows-specific file attributes */
162  ctx->attributes.host_system = ZIP_OPSYS_UNIX;
163  ctx->attributes.external_file_attributes = (((zip_uint32_t)sb.st_mode) << 16) | ((sb.st_mode & S_IWUSR) ? 0 : 1);
164 
165  return true;
166 }
167 
168 
171  off_t offset = ftello((FILE *)f);
172 
173  if (offset < 0) {
174  zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
175  }
176 
177  return offset;
178 }
179 
180 
181 /*
182  * fopen replacement that sets the close-on-exec flag
183  * some implementations support an fopen 'e' flag for that,
184  * but e.g. macOS doesn't.
185  */
186 FILE *
187 _zip_fopen_close_on_exec(const char *name, bool writeable) {
188  int fd;
189  int flags;
190  FILE *fp;
191 
192  flags = O_CLOEXEC;
193  if (writeable) {
194  flags |= O_RDWR;
195  }
196  else {
197  flags |= O_RDONLY;
198  }
199 
200  /* mode argument needed on Windows */
201  if ((fd = open(name, flags, 0666)) < 0) {
202  return NULL;
203  }
204  if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) {
205  return NULL;
206  }
207  return fp;
208 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
static SblHeader sb
Definition: bin_mbn.c:26
#define ZIP_FSEEK_MIN
Definition: compat.h:155
#define fseeko(s, o, w)
Definition: compat.h:121
#define ZIP_FSEEK_MAX
Definition: compat.h:154
#define EOVERFLOW
Definition: compat.h:75
#define ftello(s)
Definition: compat.h:125
#define S_ISREG(mode)
Definition: compat.h:191
#define O_CLOEXEC
Definition: compat.h:80
#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 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 fstat
Definition: sflib.h:107
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
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
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
#define ZIP_OPSYS_UNIX
Definition: zip.h:198
#define ZIP_FILE_ATTRIBUTES_HOST_SYSTEM
Definition: zip.h:329
#define ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES
Definition: zip.h:332
#define ZIP_EXTERN
Definition: zip.h:54
#define ZIP_ER_INVAL
Definition: zip.h:123
#define ZIP_ER_READ
Definition: zip.h:110
static stat
Definition: sflib.h:131
string FILE
Definition: benchmark.py:21
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define ENOENT
Definition: sftypes.h:112
#define O_RDONLY
Definition: sftypes.h:486
int off_t
Definition: sftypes.h:41
#define O_RDWR
Definition: sftypes.h:488
#define f(i)
Definition: sha256.c:46
#define SIZE_MAX
zip_error_t * error
Definition: gzappend.c:170
Definition: z80asm.h:102
Definition: sftypes.h:80
Definition: zip.h:284
Definition: zipint.h:278
zip_error_t error
Definition: zipint.h:281
void error(const char *msg)
Definition: untgz.c:593
static const z80_opcode fd[]
Definition: z80_tab.h:997
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)
void _zip_stdio_op_close(zip_source_file_context_t *ctx)
ZIP_EXTERN zip_source_t * zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len)
ZIP_EXTERN zip_source_t * zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
zip_int64_t _zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len)
zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f)
bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st)
FILE * _zip_fopen_close_on_exec(const char *name, bool writeable)
bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence)
static zip_source_file_operations_t ops_stdio_read
uint64_t zip_uint64_t
Definition: zipconf.h:39
uint32_t zip_uint32_t
Definition: zipconf.h:37
int64_t zip_int64_t
Definition: zipconf.h:38
zip_t * za
Definition: ziptool.c:79