diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2020-03-09 11:34:21 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2020-03-10 10:33:01 +0100 |
commit | da370af54b419132d5f1e990f79b06ad8ebe66c0 (patch) | |
tree | 29749bc61bb0f74eb9601c98bb2431dd26c233a7 /src/Common/libzip/zip_source_filep.c | |
parent | 7d110798d2ec1dae02310939c1bd6b036b90f6bf (diff) | |
download | VeraCrypt-da370af54b419132d5f1e990f79b06ad8ebe66c0.tar.gz VeraCrypt-da370af54b419132d5f1e990f79b06ad8ebe66c0.zip |
Windows: Update libzip to 1.6.1
Diffstat (limited to 'src/Common/libzip/zip_source_filep.c')
-rw-r--r-- | src/Common/libzip/zip_source_filep.c | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/src/Common/libzip/zip_source_filep.c b/src/Common/libzip/zip_source_filep.c index cb3d1511..30e5991c 100644 --- a/src/Common/libzip/zip_source_filep.c +++ b/src/Common/libzip/zip_source_filep.c @@ -30,8 +30,9 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> @@ -53,30 +54,8 @@ #include <sys/ioctl.h> #define CAN_CLONE #endif -#ifdef _WIN32 -/* WIN32 needs <fcntl.h> for _O_BINARY */ -#include <fcntl.h> -#endif - -/* Windows sys/types.h does not provide these */ -#ifndef S_ISREG -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) -#endif -#if defined(S_IXUSR) && defined(S_IRWXG) && defined(S_IRWXO) -#define _SAFE_MASK (S_IXUSR | S_IRWXG | S_IRWXO) -#elif defined(_S_IWRITE) -#define _SAFE_MASK (_S_IWRITE) -#else -#error do not know safe values for umask, please report this -#endif - -#ifdef _MSC_VER -/* MSVC doesn't have mode_t */ -typedef int mode_t; -#endif - struct read_file { zip_error_t error; /* last error information */ zip_int64_t supports; @@ -98,8 +77,9 @@ static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_sour static int create_temp_output(struct read_file *ctx); #ifdef CAN_CLONE static zip_int64_t create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset); #endif +static FILE *_zip_fopen(const char *name, bool writeable); static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error); static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error); @@ -224,8 +204,9 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int } } } + ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); #ifdef CAN_CLONE if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) { ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING); } @@ -244,25 +225,31 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int static int create_temp_output(struct read_file *ctx) { char *temp; int tfd; - mode_t mask; + int mode; FILE *tfp; + struct stat st; if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); return -1; } + + if (stat(ctx->fname, &st) == 0) { + mode = st.st_mode; + } + else { + mode = -1; + } + sprintf(temp, "%s.XXXXXX", ctx->fname); - mask = umask(_SAFE_MASK); - if ((tfd = mkstemp(temp)) == -1) { + if ((tfd = _zip_mkstempm(temp, mode)) == -1) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - umask(mask); free(temp); return -1; } - umask(mask); if ((tfp = fdopen(tfd, "r+b")) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); close(tfd); @@ -270,16 +257,8 @@ create_temp_output(struct read_file *ctx) { free(temp); return -1; } -#ifdef _WIN32 - /* - According to Pierre Joye, Windows in some environments per - default creates text files, so force binary mode. - */ - _setmode(_fileno(tfp), _O_BINARY); -#endif - ctx->fout = tfp; ctx->tmpname = temp; return 0; @@ -315,9 +294,9 @@ zip_int64_t static create_temp_output_cloning(struct read_file *ctx, zip_uint64_ zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); free(temp); return -1; } - if ((tfp = fopen(temp, "r+b")) == NULL) { + if ((tfp = _zip_fopen(temp, true)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); (void)remove(temp); free(temp); return -1; @@ -395,14 +374,21 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { ctx = (struct read_file *)state; buf = (char *)data; switch (cmd) { + case ZIP_SOURCE_ACCEPT_EMPTY: + return 0; + case ZIP_SOURCE_BEGIN_WRITE: +#ifdef _WIN32 + return -1; +#else if (ctx->fname == NULL) { zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); return -1; } return create_temp_output(ctx); +#endif #ifdef CAN_CLONE case ZIP_SOURCE_BEGIN_WRITE_CLONING: if (ctx->fname == NULL) { @@ -411,42 +397,30 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { } return create_temp_output_cloning(ctx, len); #endif - case ZIP_SOURCE_COMMIT_WRITE: { - mode_t mode; - struct stat st; + case ZIP_SOURCE_CLOSE: + if (ctx->fname) { + fclose(ctx->f); + ctx->f = NULL; + } + return 0; + case ZIP_SOURCE_COMMIT_WRITE: { if (fclose(ctx->fout) < 0) { ctx->fout = NULL; zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); } ctx->fout = NULL; - if (stat(ctx->fname, &st) == 0) { - mode = st.st_mode; - } else { - mode_t mask = umask(022); - umask(mask); - mode = 0666 & ~mask; - } if (rename(ctx->tmpname, ctx->fname) < 0) { zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); return -1; } - /* not much we can do if chmod fails except make the whole commit fail */ - (void)chmod(ctx->fname, mode); free(ctx->tmpname); ctx->tmpname = NULL; return 0; } - case ZIP_SOURCE_CLOSE: - if (ctx->fname) { - fclose(ctx->f); - ctx->f = NULL; - } - return 0; - case ZIP_SOURCE_ERROR: return zip_error_to_data(&ctx->error, data, len); case ZIP_SOURCE_FREE: @@ -458,9 +432,9 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { return 0; case ZIP_SOURCE_OPEN: if (ctx->fname) { - if ((ctx->f = fopen(ctx->fname, "rb")) == NULL) { + if ((ctx->f = _zip_fopen(ctx->fname, false)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); return -1; } } @@ -655,4 +629,35 @@ _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error) { return -1; } return 0; } + + +/* + * fopen replacement that sets the close-on-exec flag + * some implementations support an fopen 'e' flag for that, + * but e.g. macOS doesn't. + */ +static FILE * +_zip_fopen(const char *name, bool writeable) +{ + int fd; + int flags; + FILE *fp; + + flags = O_CLOEXEC; + if (writeable) { + flags |= O_RDWR; + } + else { + flags |= O_RDONLY; + } + + /* mode argument needed on Windows */ + if ((fd = open(name, flags, 0666)) < 0) { + return NULL; + } + if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) { + return NULL; + } + return fp; +} |