From 652d39c330b58964a8d985a1cedf60ed6d1ecfa1 Mon Sep 17 00:00:00 2001 From: Greg Beaver Date: Mon, 31 Dec 2007 22:42:40 +0000 Subject: [PATCH] add zip-based phar support. not quite working is webPhar(), not sure why yet --- ext/phar/config.m4 | 33 +- ext/phar/config.w32 | 18 + ext/phar/lib/mkstemp.c | 136 ++++ ext/phar/lib/unistd.h | 3 + ext/phar/lib/zip.h | 210 ++++++ ext/phar/lib/zip_add.c | 51 ++ ext/phar/lib/zip_add_dir.c | 83 +++ ext/phar/lib/zip_close.c | 558 +++++++++++++++ ext/phar/lib/zip_delete.c | 61 ++ ext/phar/lib/zip_dirent.c | 531 +++++++++++++++ ext/phar/lib/zip_entry_free.c | 55 ++ ext/phar/lib/zip_entry_new.c | 81 +++ ext/phar/lib/zip_err_str.c | 72 ++ ext/phar/lib/zip_error.c | 104 +++ ext/phar/lib/zip_error_clear.c | 47 ++ ext/phar/lib/zip_error_get.c | 47 ++ ext/phar/lib/zip_error_get_sys_type.c | 50 ++ ext/phar/lib/zip_error_strerror.c | 93 +++ ext/phar/lib/zip_error_to_str.c | 73 ++ ext/phar/lib/zip_fclose.c | 76 +++ ext/phar/lib/zip_file_error_clear.c | 47 ++ ext/phar/lib/zip_file_error_get.c | 47 ++ ext/phar/lib/zip_file_get_offset.c | 80 +++ ext/phar/lib/zip_file_strerror.c | 47 ++ ext/phar/lib/zip_fopen.c | 52 ++ ext/phar/lib/zip_fopen_index.c | 219 ++++++ ext/phar/lib/zip_fread.c | 125 ++++ ext/phar/lib/zip_free.c | 86 +++ ext/phar/lib/zip_get_archive_comment.c | 58 ++ ext/phar/lib/zip_get_file_comment.c | 61 ++ ext/phar/lib/zip_get_name.c | 74 ++ ext/phar/lib/zip_get_num_files.c | 50 ++ ext/phar/lib/zip_memdup.c | 58 ++ ext/phar/lib/zip_name_locate.c | 91 +++ ext/phar/lib/zip_new.c | 71 ++ ext/phar/lib/zip_open.c | 468 +++++++++++++ ext/phar/lib/zip_rename.c | 52 ++ ext/phar/lib/zip_replace.c | 82 +++ ext/phar/lib/zip_set_archive_comment.c | 68 ++ ext/phar/lib/zip_set_file_comment.c | 69 ++ ext/phar/lib/zip_set_name.c | 77 +++ ext/phar/lib/zip_source_buffer.c | 160 +++++ ext/phar/lib/zip_source_file.c | 75 +++ ext/phar/lib/zip_source_filep.c | 176 +++++ ext/phar/lib/zip_source_free.c | 54 ++ ext/phar/lib/zip_source_function.c | 62 ++ ext/phar/lib/zip_source_zip.c | 189 ++++++ ext/phar/lib/zip_stat.c | 52 ++ ext/phar/lib/zip_stat_index.c | 93 +++ ext/phar/lib/zip_stat_init.c | 53 ++ ext/phar/lib/zip_strerror.c | 47 ++ ext/phar/lib/zip_unchange.c | 84 +++ ext/phar/lib/zip_unchange_all.c | 56 ++ ext/phar/lib/zip_unchange_archive.c | 52 ++ ext/phar/lib/zip_unchange_data.c | 53 ++ ext/phar/lib/zip_win32.h | 29 + ext/phar/lib/zipint.h | 226 +++++++ ext/phar/phar.c | 898 +++++++++++++++++++++++-- ext/phar/phar_internal.h | 20 +- ext/phar/phar_object.c | 100 ++- ext/phar/tests/001.phpt | 2 +- 61 files changed, 6780 insertions(+), 65 deletions(-) create mode 100644 ext/phar/lib/mkstemp.c create mode 100644 ext/phar/lib/unistd.h create mode 100644 ext/phar/lib/zip.h create mode 100644 ext/phar/lib/zip_add.c create mode 100644 ext/phar/lib/zip_add_dir.c create mode 100644 ext/phar/lib/zip_close.c create mode 100644 ext/phar/lib/zip_delete.c create mode 100644 ext/phar/lib/zip_dirent.c create mode 100644 ext/phar/lib/zip_entry_free.c create mode 100644 ext/phar/lib/zip_entry_new.c create mode 100644 ext/phar/lib/zip_err_str.c create mode 100644 ext/phar/lib/zip_error.c create mode 100644 ext/phar/lib/zip_error_clear.c create mode 100644 ext/phar/lib/zip_error_get.c create mode 100644 ext/phar/lib/zip_error_get_sys_type.c create mode 100644 ext/phar/lib/zip_error_strerror.c create mode 100644 ext/phar/lib/zip_error_to_str.c create mode 100644 ext/phar/lib/zip_fclose.c create mode 100644 ext/phar/lib/zip_file_error_clear.c create mode 100644 ext/phar/lib/zip_file_error_get.c create mode 100644 ext/phar/lib/zip_file_get_offset.c create mode 100644 ext/phar/lib/zip_file_strerror.c create mode 100644 ext/phar/lib/zip_fopen.c create mode 100644 ext/phar/lib/zip_fopen_index.c create mode 100644 ext/phar/lib/zip_fread.c create mode 100644 ext/phar/lib/zip_free.c create mode 100644 ext/phar/lib/zip_get_archive_comment.c create mode 100644 ext/phar/lib/zip_get_file_comment.c create mode 100644 ext/phar/lib/zip_get_name.c create mode 100644 ext/phar/lib/zip_get_num_files.c create mode 100644 ext/phar/lib/zip_memdup.c create mode 100644 ext/phar/lib/zip_name_locate.c create mode 100644 ext/phar/lib/zip_new.c create mode 100644 ext/phar/lib/zip_open.c create mode 100644 ext/phar/lib/zip_rename.c create mode 100644 ext/phar/lib/zip_replace.c create mode 100644 ext/phar/lib/zip_set_archive_comment.c create mode 100644 ext/phar/lib/zip_set_file_comment.c create mode 100644 ext/phar/lib/zip_set_name.c create mode 100644 ext/phar/lib/zip_source_buffer.c create mode 100644 ext/phar/lib/zip_source_file.c create mode 100644 ext/phar/lib/zip_source_filep.c create mode 100644 ext/phar/lib/zip_source_free.c create mode 100644 ext/phar/lib/zip_source_function.c create mode 100644 ext/phar/lib/zip_source_zip.c create mode 100644 ext/phar/lib/zip_stat.c create mode 100644 ext/phar/lib/zip_stat_index.c create mode 100644 ext/phar/lib/zip_stat_init.c create mode 100644 ext/phar/lib/zip_strerror.c create mode 100644 ext/phar/lib/zip_unchange.c create mode 100644 ext/phar/lib/zip_unchange_all.c create mode 100644 ext/phar/lib/zip_unchange_archive.c create mode 100644 ext/phar/lib/zip_unchange_data.c create mode 100644 ext/phar/lib/zip_win32.h create mode 100644 ext/phar/lib/zipint.h diff --git a/ext/phar/config.m4 b/ext/phar/config.m4 index 5597388efb..5de8145b07 100644 --- a/ext/phar/config.m4 +++ b/ext/phar/config.m4 @@ -2,10 +2,39 @@ dnl $Id$ dnl config.m4 for extension phar PHP_ARG_ENABLE(phar, for phar support/phar zlib support, -[ --enable-phar Enable phar support, use --with-zlib-dir if zlib detection fails]) +[ --enable-phar Enable phar support]) + +PHP_ARG_WITH(phar-zip, for zip-based phar support, +[ --without-phar-zip PHAR: Disable zip-based phar archive support], no, no) if test "$PHP_PHAR" != "no"; then - PHP_NEW_EXTENSION(phar, phar.c phar_object.c phar_path_check.c, $ext_shared) + AC_MSG_CHECKING([for zip-based phar support]) + if test "$PHP_PHAR_ZIP" != "yes"; then + AC_MSG_RESULT([yes]) + PHP_PHAR_SOURCES="$PHP_PHAR_SOURCES lib/zip_add.c lib/zip_error.c lib/zip_fclose.c \ + lib/zip_fread.c lib/zip_open.c lib/zip_source_filep.c \ + lib/zip_strerror.c lib/zip_close.c lib/zip_error_get.c \ + lib/zip_file_error_get.c lib/zip_free.c lib/zip_rename.c \ + lib/zip_source_free.c lib/zip_unchange_all.c lib/zip_delete.c \ + lib/zip_error_get_sys_type.c lib/zip_file_get_offset.c \ + lib/zip_get_name.c lib/zip_replace.c lib/zip_source_function.c \ + lib/zip_unchange.c lib/zip_dirent.c lib/zip_error_strerror.c \ + lib/zip_file_strerror.c lib/zip_get_num_files.c \ + lib/zip_set_name.c lib/zip_source_zip.c lib/zip_unchange_data.c \ + lib/zip_entry_free.c lib/zip_error_to_str.c lib/zip_fopen.c \ + lib/zip_name_locate.c lib/zip_source_buffer.c lib/zip_stat.c \ + lib/zip_entry_new.c lib/zip_err_str.c lib/zip_fopen_index.c \ + lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c lib/zip_get_archive_comment.c \ + lib/zip_get_file_comment.c lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \ + lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \ + lib/zip_error_clear.c lib/zip_file_error_clear.c" + AC_DEFINE(HAVE_PHAR_ZIP,1,[ ]) + else + AC_MSG_RESULT([no]) + fi + PHP_NEW_EXTENSION(phar, phar.c phar_object.c phar_path_check.c $PHP_PHAR_SOURCES, $ext_shared) + PHP_ADD_BUILD_DIR($ext_builddir/lib, 1) + PHP_SUBST(PHAR_SHARED_LIBADD) PHP_ADD_EXTENSION_DEP(phar, zlib, true) PHP_ADD_EXTENSION_DEP(phar, bz2, true) PHP_ADD_EXTENSION_DEP(phar, spl, true) diff --git a/ext/phar/config.w32 b/ext/phar/config.w32 index 8046b06d01..edf067a21b 100644 --- a/ext/phar/config.w32 +++ b/ext/phar/config.w32 @@ -5,6 +5,24 @@ ARG_ENABLE("phar", "enable phar support", "no"); if (PHP_PHAR != "no") { EXTENSION("phar", "phar.c phar_object.c phar_path_check.c"); + ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_error.c zip_fclose.c \ + zip_fread.c zip_open.c zip_source_filep.c \ + zip_strerror.c zip_close.c zip_error_get.c \ + zip_file_error_get.c zip_free.c zip_rename.c \ + zip_source_free.c zip_unchange_all.c zip_delete.c \ + zip_error_get_sys_type.c zip_file_get_offset.c \ + zip_get_name.c zip_replace.c zip_source_function.c \ + zip_unchange.c zip_dirent.c zip_error_strerror.c \ + zip_file_strerror.c zip_get_num_files.c \ + zip_set_name.c zip_source_zip.c zip_unchange_data.c \ + zip_entry_free.c zip_error_to_str.c zip_fopen.c \ + zip_name_locate.c zip_source_buffer.c zip_stat.c \ + zip_entry_new.c zip_err_str.c zip_fopen_index.c \ + zip_new.c zip_source_file.c zip_stat_index.c \ + zip_get_archive_comment.c zip_get_file_comment.c \ + zip_set_archive_comment.c zip_set_file_comment.c \ + zip_unchange_archive.c zip_memdup.c zip_stat_init.c \ + zip_add_dir.c zip_file_error_clear.c zip_error_clear.c", "phar"); ADD_EXTENSION_DEP('phar', 'zlib', true); ADD_EXTENSION_DEP('phar', 'bz2', true); ADD_EXTENSION_DEP('phar', 'spl', true); diff --git a/ext/phar/lib/mkstemp.c b/ext/phar/lib/mkstemp.c new file mode 100644 index 0000000000..3ac587eafe --- /dev/null +++ b/ext/phar/lib/mkstemp.c @@ -0,0 +1,136 @@ +/* $NiH: mkstemp.c,v 1.3 2006/04/23 14:51:45 wiz Exp $ */ + +/* Adapted from NetBSB libc by Dieter Baron */ + +/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +int +_zip_mkstemp(char *path) +{ + int fd; + char *start, *trv; + struct stat sbuf; + pid_t pid; + + /* To guarantee multiple calls generate unique names even if + the file is not created. 676 different possibilities with 7 + or more X's, 26 with 6 or less. */ + static char xtra[2] = "aa"; + int xcnt = 0; + + pid = getpid(); + + /* Move to end of path and count trailing X's. */ + for (trv = path; *trv; ++trv) + if (*trv == 'X') + xcnt++; + else + xcnt = 0; + + /* Use at least one from xtra. Use 2 if more than 6 X's. */ + if (*(trv - 1) == 'X') + *--trv = xtra[0]; + if (xcnt > 6 && *(trv - 1) == 'X') + *--trv = xtra[1]; + + /* Set remaining X's to pid digits with 0's to the left. */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* update xtra for next call. */ + if (xtra[0] != 'z') + xtra[0]++; + else { + xtra[0] = 'a'; + if (xtra[1] != 'z') + xtra[1]++; + else + xtra[1] = 'a'; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return (0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0) + return (1); + if (errno != EEXIST) + return (0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit((unsigned char)*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +} diff --git a/ext/phar/lib/unistd.h b/ext/phar/lib/unistd.h new file mode 100644 index 0000000000..2ef435c012 --- /dev/null +++ b/ext/phar/lib/unistd.h @@ -0,0 +1,3 @@ +#ifndef _MSC_VER +#include +#endif diff --git a/ext/phar/lib/zip.h b/ext/phar/lib/zip.h new file mode 100644 index 0000000000..de115d38ae --- /dev/null +++ b/ext/phar/lib/zip.h @@ -0,0 +1,210 @@ +#ifndef _HAD_ZIP_H +#define _HAD_ZIP_H + +/* + $NiH: zip.h,v 1.57 2006/04/24 14:04:19 dillo Exp $ + + zip.h -- exported declarations. + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include "zip_win32.h" + +/* flags for zip_open */ + +#define ZIP_CREATE 1 +#define ZIP_EXCL 2 +#define ZIP_CHECKCONS 4 +#define ZIP_OVERWRITE 8 + + +/* flags for zip_name_locate, zip_fopen, zip_stat, ... */ + +#define ZIP_FL_NOCASE 1 /* ignore case on name lookup */ +#define ZIP_FL_NODIR 2 /* ignore directory component */ +#define ZIP_FL_COMPRESSED 4 /* read compressed data */ +#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ + +/* libzip error codes */ + +#define ZIP_ER_OK 0 /* N No error */ +#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */ +#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */ +#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */ +#define ZIP_ER_SEEK 4 /* S Seek error */ +#define ZIP_ER_READ 5 /* S Read error */ +#define ZIP_ER_WRITE 6 /* S Write error */ +#define ZIP_ER_CRC 7 /* N CRC error */ +#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */ +#define ZIP_ER_NOENT 9 /* N No such file */ +#define ZIP_ER_EXISTS 10 /* N File already exists */ +#define ZIP_ER_OPEN 11 /* S Can't open file */ +#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */ +#define ZIP_ER_ZLIB 13 /* Z Zlib error */ +#define ZIP_ER_MEMORY 14 /* N Malloc failure */ +#define ZIP_ER_CHANGED 15 /* N Entry has been changed */ +#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */ +#define ZIP_ER_EOF 17 /* N Premature EOF */ +#define ZIP_ER_INVAL 18 /* N Invalid argument */ +#define ZIP_ER_NOZIP 19 /* N Not a zip archive */ +#define ZIP_ER_INTERNAL 20 /* N Internal error */ +#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ +#define ZIP_ER_REMOVE 22 /* S Can't remove file */ +#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ + + +/* type of system error value */ + +#define ZIP_ET_NONE 0 /* sys_err unused */ +#define ZIP_ET_SYS 1 /* sys_err is errno */ +#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ + +/* compression methods */ + +#define ZIP_CM_DEFAULT -1 /* better of deflate or store */ +#define ZIP_CM_STORE 0 /* stored (uncompressed) */ +#define ZIP_CM_SHRINK 1 /* shrunk */ +#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */ +#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */ +#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */ +#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */ +#define ZIP_CM_IMPLODE 6 /* imploded */ +/* 7 - Reserved for Tokenizing compression algorithm */ +#define ZIP_CM_DEFLATE 8 /* deflated */ +#define ZIP_CM_DEFLATE64 9 /* deflate64 */ +#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ +/* 11 - Reserved by PKWARE */ +#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ + +/* encryption methods */ + +#define ZIP_EM_NONE 0 /* not encrypted */ +#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */ +#if 0 /* Strong Encryption Header not parsed yet */ +#define ZIP_EM_DES 0x6601 /* strong encryption: DES */ +#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */ +#define ZIP_EM_3DES_168 0x6603 +#define ZIP_EM_3DES_112 0x6609 +#define ZIP_EM_AES_128 0x660e +#define ZIP_EM_AES_192 0x660f +#define ZIP_EM_AES_256 0x6610 +#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */ +#define ZIP_EM_RC4 0x6801 +#endif +#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */ + + + +enum zip_source_cmd { + ZIP_SOURCE_OPEN, /* prepare for reading */ + ZIP_SOURCE_READ, /* read data */ + ZIP_SOURCE_CLOSE, /* reading is done */ + ZIP_SOURCE_STAT, /* get meta information */ + ZIP_SOURCE_ERROR, /* get error information */ + ZIP_SOURCE_FREE /* cleanup and free resources */ +}; + +typedef ssize_t (*zip_source_callback)(void *state, void *data, + size_t len, enum zip_source_cmd cmd); + +struct zip_stat { + const char *name; /* name of the file */ + int index; /* index within archive */ + unsigned int crc; /* crc of file data */ + time_t mtime; /* modification time */ + off_t size; /* size of file (uncompressed) */ + off_t comp_size; /* size of file (compressed) */ + unsigned short comp_method; /* compression method used */ + unsigned short encryption_method; /* encryption method used */ +}; + +struct zip; +struct zip_file; +struct zip_source; + + + +int zip_add(struct zip *, const char *, struct zip_source *); +int zip_add_dir(struct zip *, const char *); +int zip_close(struct zip *); +int zip_delete(struct zip *, int); +void zip_error_clear(struct zip *); +void zip_error_get(struct zip *, int *, int *); +int zip_error_get_sys_type(int); +int zip_error_to_str(char *, size_t, int, int); +int zip_fclose(struct zip_file *); +void zip_file_error_clear(struct zip_file *); +void zip_file_error_get(struct zip_file *, int *, int *); +const char *zip_file_strerror(struct zip_file *); +struct zip_file *zip_fopen(struct zip *, const char *, int); +struct zip_file *zip_fopen_index(struct zip *, int, int); +ssize_t zip_fread(struct zip_file *, void *, size_t); +const char *zip_get_archive_comment(struct zip *, int *, int); +const char *zip_get_file_comment(struct zip *, int, int *, int); +const char *zip_get_name(struct zip *, int, int); +int zip_get_num_files(struct zip *); +int zip_name_locate(struct zip *, const char *, int); +struct zip *zip_open(const char *, int, int *); +int zip_rename(struct zip *, int, const char *); +int zip_replace(struct zip *, int, struct zip_source *); +int zip_set_archive_comment(struct zip *, const char *, int); +int zip_set_file_comment(struct zip *, int, const char *, int); +struct zip_source *zip_source_buffer(struct zip *, const void *, off_t, int); +struct zip_source *zip_source_file(struct zip *, const char *, off_t, off_t); +struct zip_source *zip_source_filep(struct zip *, FILE *, off_t, off_t); +void zip_source_free(struct zip_source *); +struct zip_source *zip_source_function(struct zip *, + zip_source_callback, void *); +struct zip_source *zip_source_zip(struct zip *, struct zip *, int, int, + off_t, off_t); +int zip_stat(struct zip *, const char *, int, struct zip_stat *); +int zip_stat_index(struct zip *, int, int, struct zip_stat *); +void zip_stat_init(struct zip_stat *); +const char *zip_strerror(struct zip *); +int zip_unchange(struct zip *, int); +int zip_unchange_all(struct zip *); +int zip_unchange_archive(struct zip *); + +#ifdef __cplusplus +} +#endif + +#endif /* _HAD_ZIP_H */ diff --git a/ext/phar/lib/zip_add.c b/ext/phar/lib/zip_add.c new file mode 100644 index 0000000000..535d6e4689 --- /dev/null +++ b/ext/phar/lib/zip_add.c @@ -0,0 +1,51 @@ +/* + $NiH: zip_add.c,v 1.14 2004/11/18 15:04:04 wiz Exp $ + + zip_add.c -- add file via callback function + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_add(struct zip *za, const char *name, struct zip_source *source) +{ + if (name == NULL || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + return _zip_replace(za, -1, name, source); +} diff --git a/ext/phar/lib/zip_add_dir.c b/ext/phar/lib/zip_add_dir.c new file mode 100644 index 0000000000..957aaf1d2e --- /dev/null +++ b/ext/phar/lib/zip_add_dir.c @@ -0,0 +1,83 @@ +/* + $NiH: zip_add_dir.c,v 1.1 2006/10/03 12:23:13 dillo Exp $ + + zip_add_dir.c -- add directory + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_add_dir(struct zip *za, const char *name) +{ + int len, ret; + char *s; + struct zip_source *source; + + if (name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + s = NULL; + len = strlen(name); + + if (name[len-1] != '/') { + if ((s=(char *)malloc(len+2)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + strcpy(s, name); + s[len] = '/'; + s[len+1] = '\0'; + } + + if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { + free(s); + return -1; + } + + ret = _zip_replace(za, -1, s ? s : name, source); + + free(s); + if (ret < 0) + zip_source_free(source); + + return ret; +} diff --git a/ext/phar/lib/zip_close.c b/ext/phar/lib/zip_close.c new file mode 100644 index 0000000000..e701321a81 --- /dev/null +++ b/ext/phar/lib/zip_close.c @@ -0,0 +1,558 @@ +/* + $NiH: zip_close.c,v 1.60 2006/05/09 17:21:47 wiz Exp $ + + zip_close.c -- close zip archive and update changes + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include + +#include "zip.h" +#include "zipint.h" + +static int add_data(struct zip *, int, struct zip_dirent *, FILE *); +static int add_data_comp(zip_source_callback, void *, struct zip_stat *, + FILE *, struct zip_error *); +static int add_data_uncomp(zip_source_callback, void *, struct zip_stat *, + FILE *, struct zip_error *); +static void ch_set_error(struct zip_error *, zip_source_callback, void *); +static int copy_data(FILE *, off_t, FILE *, struct zip_error *); +static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *); +static int _zip_changed(struct zip *, int *); +static char *_zip_create_temp_output(struct zip *, FILE **); + +int +zip_close(struct zip *za) +{ + int survivors; + int i, j, error; + char *temp; + FILE *out; + mode_t mask; + struct zip_cdir *cd; + struct zip_dirent de; + int rename_error = 0; + + if (!_zip_changed(za, &survivors)) { + _zip_free(za); + return 0; + } + + /* don't create zip files with no entries */ + if (survivors == 0) { + if (za->zn) { + if (remove(za->zn) != 0) { + _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); + return -1; + } + } + _zip_free(za); + return 0; + } + + if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) + return -1; + + for (i=0; ientry[i]); + + if (_zip_cdir_set_comment(cd, za) == -1) { + _zip_cdir_free(cd); + return -1; + } + + if ((temp=_zip_create_temp_output(za, &out)) == NULL) { + _zip_cdir_free(cd); + return -1; + } + + error = 0; + for (i=j=0; inentry; i++) { + if (za->entry[i].state == ZIP_ST_DELETED) + continue; + + /* create new local directory entry */ + if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { + _zip_dirent_init(&de); + /* use it as central directory entry */ + memcpy(cd->entry+j, &de, sizeof(cd->entry[j])); + + /* set/update file name */ + if (za->entry[i].ch_filename == NULL) { + if (za->entry[i].state == ZIP_ST_REPLACED) { + de.filename = strdup(za->cdir->entry[i].filename); + de.filename_len = strlen(de.filename); + cd->entry[j].filename = za->cdir->entry[i].filename; + cd->entry[j].filename_len = de.filename_len; + } + else { + de.filename = strdup("-"); + de.filename_len = 1; + cd->entry[j].filename = "-"; + cd->entry[j].filename_len = de.filename_len; + } + } + } + else { + /* copy existing directory entries */ + if (fseek(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + error = 1; + break; + } + if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0) { + error = 1; + break; + } + + if (de.bitflags & ZIP_GPBF_USE_DATA_DESCRIPTOR) { + de.crc = (za->cdir->entry+i)->crc; + de.comp_size = (za->cdir->entry+i)->comp_size; + de.uncomp_size = (za->cdir->entry+i)->uncomp_size; + } + memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); + } + + if (za->entry[i].ch_filename) { + free(de.filename); + if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) { + error = 1; + break; + } + de.filename_len = strlen(de.filename); + cd->entry[j].filename = za->entry[i].ch_filename; + cd->entry[j].filename_len = de.filename_len; + } + + if (za->entry[i].ch_comment_len != -1) { + /* as the rest of cd entries, its malloc/free is done by za */ + cd->entry[j].comment = za->entry[i].ch_comment; + cd->entry[j].comment_len = za->entry[i].ch_comment_len; + } + + cd->entry[j].offset = ftell(out); + + if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { + if (add_data(za, i, &de, out) < 0) { + error = 1; + break; + } + + cd->entry[j].last_mod = de.last_mod; + cd->entry[j].comp_method = de.comp_method; + cd->entry[j].comp_size = de.comp_size; + cd->entry[j].uncomp_size = de.uncomp_size; + cd->entry[j].crc = de.crc; + } + else { + if (_zip_dirent_write(&de, out, 1, &za->error) < 0) { + error = 1; + break; + } + /* we just read the local dirent, file is at correct position */ + if (copy_data(za->zp, de.comp_size, out, &za->error) < 0) { + error = 1; + break; + } + } + + j++; + + _zip_dirent_finalize(&de); + } + + if (!error) { + if (_zip_cdir_write(cd, out, &za->error) < 0) + error = 1; + } + + /* pointers in cd entries are owned by za */ + cd->nentry = 0; + _zip_cdir_free(cd); + + if (error) { + _zip_dirent_finalize(&de); + fclose(out); + remove(temp); + free(temp); + return -1; + } + + if (fclose(out) != 0) { + _zip_error_set(&za->error, ZIP_ER_CLOSE, errno); + remove(temp); + free(temp); + return -1; + } + + if (za->zp) { + fclose(za->zp); + za->zp = NULL; + } + +#ifdef PHP_WIN32 + if (!MoveFileEx(temp, za->zn, MOVEFILE_REPLACE_EXISTING)) { + rename_error = -1; + } +#else + if (rename(temp, za->zn) != 0) { + rename_error = -1; + } +#endif + + if (rename_error < 0) { + _zip_error_set(&za->error, ZIP_ER_RENAME, errno); + remove(temp); + free(temp); + return -1; + } + + mask = umask(0); + umask(mask); + chmod(za->zn, 0666&~mask); + + _zip_free(za); + free(temp); + return 0; +} + + + +static int +add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft) +{ + off_t offstart, offend; + zip_source_callback cb; + void *ud; + struct zip_stat st; + + cb = za->entry[idx].source->f; + ud = za->entry[idx].source->ud; + + if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) { + ch_set_error(&za->error, cb, ud); + return -1; + } + + if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) { + ch_set_error(&za->error, cb, ud); + return -1; + } + + offstart = ftell(ft); + + if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + return -1; + + if (st.comp_method != ZIP_CM_STORE) { + if (add_data_comp(cb, ud, &st, ft, &za->error) < 0) + return -1; + } + else { + if (add_data_uncomp(cb, ud, &st, ft, &za->error) < 0) + return -1; + } + + if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) { + ch_set_error(&za->error, cb, ud); + return -1; + } + + offend = ftell(ft); + + if (fseek(ft, offstart, SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + de->comp_method = st.comp_method; + de->last_mod = st.mtime; + de->crc = st.crc; + de->uncomp_size = st.size; + de->comp_size = st.comp_size; + + if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + return -1; + + if (fseek(ft, offend, SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + return 0; +} + + + +static int +add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft, + struct zip_error *error) +{ + char buf[BUFSIZE]; + ssize_t n; + + st->comp_size = 0; + while ((n=cb(ud, buf, sizeof(buf), ZIP_SOURCE_READ)) > 0) { + if (fwrite(buf, 1, n, ft) != (size_t)n) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + st->comp_size += n; + } + if (n < 0) { + ch_set_error(error, cb, ud); + return -1; + } + + return 0; +} + + + +static int +add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st, + FILE *ft, struct zip_error *error) +{ + char b1[BUFSIZE], b2[BUFSIZE]; + int end, flush, ret; + ssize_t n; + size_t n2; + z_stream zstr; + + st->comp_method = ZIP_CM_DEFLATE; + st->comp_size = st->size = 0; + st->crc = crc32(0, NULL, 0); + + zstr.zalloc = Z_NULL; + zstr.zfree = Z_NULL; + zstr.opaque = NULL; + zstr.avail_in = 0; + zstr.avail_out = 0; + + /* -15: undocumented feature of zlib to _not_ write a zlib header */ + deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 9, + Z_DEFAULT_STRATEGY); + + zstr.next_out = (Bytef *)b2; + zstr.avail_out = sizeof(b2); + zstr.avail_in = 0; + + flush = 0; + end = 0; + while (!end) { + if (zstr.avail_in == 0 && !flush) { + if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) { + ch_set_error(error, cb, ud); + deflateEnd(&zstr); + return -1; + } + if (n > 0) { + zstr.avail_in = n; + zstr.next_in = (Bytef *)b1; + st->size += n; + st->crc = crc32(st->crc, (Bytef *)b1, n); + } + else + flush = Z_FINISH; + } + + ret = deflate(&zstr, flush); + if (ret != Z_OK && ret != Z_STREAM_END) { + _zip_error_set(error, ZIP_ER_ZLIB, ret); + return -1; + } + + if (zstr.avail_out != sizeof(b2)) { + n2 = sizeof(b2) - zstr.avail_out; + + if (fwrite(b2, 1, n2, ft) != n2) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + zstr.next_out = (Bytef *)b2; + zstr.avail_out = sizeof(b2); + st->comp_size += n2; + } + + if (ret == Z_STREAM_END) { + deflateEnd(&zstr); + end = 1; + } + } + + return 0; +} + + + +static void +ch_set_error(struct zip_error *error, zip_source_callback cb, void *ud) +{ + int e[2]; + + if ((cb(ud, e, sizeof(e), ZIP_SOURCE_ERROR)) < (ssize_t)sizeof(e)) { + error->zip_err = ZIP_ER_INTERNAL; + error->sys_err = 0; + } + else { + error->zip_err = e[0]; + error->sys_err = e[1]; + } +} + + + +static int +copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) +{ + char buf[BUFSIZE]; + int n, nn; + + if (len == 0) + return 0; + + while (len > 0) { + nn = len > sizeof(buf) ? sizeof(buf) : len; + if ((n=fread(buf, 1, nn, fs)) < 0) { + _zip_error_set(error, ZIP_ER_READ, errno); + return -1; + } + else if (n == 0) { + _zip_error_set(error, ZIP_ER_EOF, 0); + return -1; + } + + if (fwrite(buf, 1, n, ft) != (size_t)n) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + len -= n; + } + + return 0; +} + + + +static int +_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src) +{ + if (src->ch_comment_len != -1) { + dest->comment = _zip_memdup(src->ch_comment, + src->ch_comment_len, &src->error); + if (dest->comment == NULL) + return -1; + dest->comment_len = src->ch_comment_len; + } else { + if (src->cdir && src->cdir->comment) { + dest->comment = _zip_memdup(src->cdir->comment, + src->cdir->comment_len, &src->error); + if (dest->comment == NULL) + return -1; + dest->comment_len = src->cdir->comment_len; + } + } + + return 0; +} + + + +static int +_zip_changed(struct zip *za, int *survivorsp) +{ + int changed, i, survivors; + + changed = survivors = 0; + + if (za->ch_comment_len != -1) + changed = 1; + + for (i=0; inentry; i++) { + if ((za->entry[i].state != ZIP_ST_UNCHANGED) + || (za->entry[i].ch_comment_len != -1)) + changed = 1; + if (za->entry[i].state != ZIP_ST_DELETED) + survivors++; + } + + *survivorsp = survivors; + + return changed; +} + + + +static char * +_zip_create_temp_output(struct zip *za, FILE **outp) +{ + char *temp; + int tfd; + FILE *tfp; + int len = strlen(za->zn) + 8; + + if ((temp=(char *)malloc(len)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + snprintf(temp, len, "%s.XXXXXX", za->zn); + + if ((tfd=mkstemp(temp)) == -1) { + _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return NULL; + } + + if ((tfp=fdopen(tfd, "r+b")) == NULL) { + _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); + close(tfd); + remove(temp); + free(temp); + return NULL; + } +#ifdef PHP_WIN32 + _setmode(_fileno(tfp), _O_BINARY ); +#endif + + *outp = tfp; + return temp; +} diff --git a/ext/phar/lib/zip_delete.c b/ext/phar/lib/zip_delete.c new file mode 100644 index 0000000000..7244e612f7 --- /dev/null +++ b/ext/phar/lib/zip_delete.c @@ -0,0 +1,61 @@ +/* + $NiH: zip_delete.c,v 1.17 2005/06/09 19:57:09 dillo Exp $ + + zip_delete.c -- delete file from zip archive + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_delete(struct zip *za, int idx) +{ + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + /* allow duplicate file names, because the file will + * be removed directly afterwards */ + if (_zip_unchange(za, idx, 1) != 0) + return -1; + + za->entry[idx].state = ZIP_ST_DELETED; + + return 0; +} + + diff --git a/ext/phar/lib/zip_dirent.c b/ext/phar/lib/zip_dirent.c new file mode 100644 index 0000000000..8423ad5343 --- /dev/null +++ b/ext/phar/lib/zip_dirent.c @@ -0,0 +1,531 @@ +/* + $NiH: zip_dirent.c,v 1.9 2006/04/23 14:51:45 wiz Exp $ + + zip_dirent.c -- read directory entry (local or central), clean dirent + Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "main/php_reentrancy.h" +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include + +#include "zip.h" +#include "zipint.h" + +static time_t _zip_d2u_time(int, int); +static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *); +static char *_zip_readstr(unsigned char **, int, int, struct zip_error *); +static void _zip_u2d_time(time_t, unsigned short *, unsigned short *); +static void _zip_write2(unsigned short, FILE *); +static void _zip_write4(unsigned int, FILE *); + + + +void +_zip_cdir_free(struct zip_cdir *cd) +{ + int i; + + if (!cd) + return; + + for (i=0; inentry; i++) + _zip_dirent_finalize(cd->entry+i); + free(cd->comment); + free(cd->entry); + free(cd); +} + + + +struct zip_cdir * +_zip_cdir_new(int nentry, struct zip_error *error) +{ + struct zip_cdir *cd; + + if ((cd=(struct zip_cdir *)malloc(sizeof(*cd))) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry)) + == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + free(cd); + return NULL; + } + + /* entries must be initialized by caller */ + + cd->nentry = nentry; + cd->size = cd->offset = 0; + cd->comment = NULL; + cd->comment_len = 0; + + return cd; +} + + + +int +_zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) +{ + int i; + + cd->offset = ftell(fp); + + for (i=0; inentry; i++) { + if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0) + return -1; + } + + cd->size = ftell(fp) - cd->offset; + + /* clearerr(fp); */ + fwrite(EOCD_MAGIC, 1, 4, fp); + _zip_write4(0, fp); + _zip_write2((unsigned short)cd->nentry, fp); + _zip_write2((unsigned short)cd->nentry, fp); + _zip_write4(cd->size, fp); + _zip_write4(cd->offset, fp); + _zip_write2(cd->comment_len, fp); + fwrite(cd->comment, 1, cd->comment_len, fp); + + if (ferror(fp)) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + return 0; +} + + + +void +_zip_dirent_finalize(struct zip_dirent *zde) +{ + free(zde->filename); + zde->filename = NULL; + free(zde->extrafield); + zde->extrafield = NULL; + free(zde->comment); + zde->comment = NULL; +} + + + +void +_zip_dirent_init(struct zip_dirent *de) +{ + de->version_madeby = 0; + de->version_needed = 20; /* 2.0 */ + de->bitflags = 0; + de->comp_method = 0; + de->last_mod = 0; + de->crc = 0; + de->comp_size = 0; + de->uncomp_size = 0; + de->filename = NULL; + de->filename_len = 0; + de->extrafield = NULL; + de->extrafield_len = 0; + de->comment = NULL; + de->comment_len = 0; + de->disk_number = 0; + de->int_attrib = 0; + de->ext_attrib = 0; + de->offset = 0; +} + + + +/* _zip_dirent_read(zde, fp, bufp, left, localp, error): + Fills the zip directory entry zde. + + If bufp is non-NULL, data is taken from there and bufp is advanced + by the amount of data used; no more than left bytes are used. + Otherwise data is read from fp as needed. + + If localp != 0, it reads a local header instead of a central + directory entry. + + Returns 0 if successful. On error, error is filled in and -1 is + returned. +*/ + +int +_zip_dirent_read(struct zip_dirent *zde, FILE *fp, + unsigned char **bufp, unsigned int left, int localp, + struct zip_error *error) +{ + unsigned char buf[CDENTRYSIZE]; + unsigned char *cur; + unsigned short dostime, dosdate; + unsigned int size; + + if (localp) + size = LENTRYSIZE; + else + size = CDENTRYSIZE; + + if (bufp) { + /* use data from buffer */ + cur = *bufp; + if (left < size) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + } + else { + /* read entry from disk */ + if ((fread(buf, 1, size, fp)version_madeby = _zip_read2(&cur); + else + zde->version_madeby = 0; + zde->version_needed = _zip_read2(&cur); + zde->bitflags = _zip_read2(&cur); + zde->comp_method = _zip_read2(&cur); + + /* convert to time_t */ + dostime = _zip_read2(&cur); + dosdate = _zip_read2(&cur); + zde->last_mod = _zip_d2u_time(dostime, dosdate); + + zde->crc = _zip_read4(&cur); + zde->comp_size = _zip_read4(&cur); + zde->uncomp_size = _zip_read4(&cur); + + zde->filename_len = _zip_read2(&cur); + zde->extrafield_len = _zip_read2(&cur); + + if (localp) { + zde->comment_len = 0; + zde->disk_number = 0; + zde->int_attrib = 0; + zde->ext_attrib = 0; + zde->offset = 0; + } else { + zde->comment_len = _zip_read2(&cur); + zde->disk_number = _zip_read2(&cur); + zde->int_attrib = _zip_read2(&cur); + zde->ext_attrib = _zip_read4(&cur); + zde->offset = _zip_read4(&cur); + } + + zde->filename = NULL; + zde->extrafield = NULL; + zde->comment = NULL; + + if (bufp) { + if (left < CDENTRYSIZE + (zde->filename_len+zde->extrafield_len + +zde->comment_len)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + if (zde->filename_len) { + zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error); + if (!zde->filename) + return -1; + } + + if (zde->extrafield_len) { + zde->extrafield = _zip_readstr(&cur, zde->extrafield_len, 0, + error); + if (!zde->extrafield) + return -1; + } + + if (zde->comment_len) { + zde->comment = _zip_readstr(&cur, zde->comment_len, 0, error); + if (!zde->comment) + return -1; + } + } + else { + if (zde->filename_len) { + zde->filename = _zip_readfpstr(fp, zde->filename_len, 1, error); + if (!zde->filename) + return -1; + } + + if (zde->extrafield_len) { + zde->extrafield = _zip_readfpstr(fp, zde->extrafield_len, 0, + error); + if (!zde->extrafield) + return -1; + } + + if (zde->comment_len) { + zde->comment = _zip_readfpstr(fp, zde->comment_len, 0, error); + if (!zde->comment) + return -1; + } + } + + if (bufp) + *bufp = cur; + + return 0; +} + + + +/* _zip_dirent_write(zde, fp, localp, error): + Writes zip directory entry zde to file fp. + + If localp != 0, it writes a local header instead of a central + directory entry. + + Returns 0 if successful. On error, error is filled in and -1 is + returned. +*/ + +int +_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, + struct zip_error *error) +{ + unsigned short dostime, dosdate; + + fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); + + if (!localp) + _zip_write2(zde->version_madeby, fp); + _zip_write2(zde->version_needed, fp); + _zip_write2(zde->bitflags, fp); + _zip_write2(zde->comp_method, fp); + + _zip_u2d_time(zde->last_mod, &dostime, &dosdate); + _zip_write2(dostime, fp); + _zip_write2(dosdate, fp); + + _zip_write4(zde->crc, fp); + _zip_write4(zde->comp_size, fp); + _zip_write4(zde->uncomp_size, fp); + + _zip_write2(zde->filename_len, fp); + _zip_write2(zde->extrafield_len, fp); + + if (!localp) { + _zip_write2(zde->comment_len, fp); + _zip_write2(zde->disk_number, fp); + _zip_write2(zde->int_attrib, fp); + _zip_write4(zde->ext_attrib, fp); + _zip_write4(zde->offset, fp); + } + + if (zde->filename_len) + fwrite(zde->filename, 1, zde->filename_len, fp); + + if (zde->extrafield_len) + fwrite(zde->extrafield, 1, zde->extrafield_len, fp); + + if (!localp) { + if (zde->comment_len) + fwrite(zde->comment, 1, zde->comment_len, fp); + } + + if (ferror(fp)) { + _zip_error_set(error, ZIP_ER_WRITE, errno); + return -1; + } + + return 0; +} + + + +static time_t +_zip_d2u_time(int dtime, int ddate) +{ + struct tm *tm, tmbuf; + time_t now; + + now = time(NULL); + tm = php_localtime_r(&now, &tmbuf); + + tm->tm_year = ((ddate>>9)&127) + 1980 - 1900; + tm->tm_mon = ((ddate>>5)&15) - 1; + tm->tm_mday = ddate&31; + + tm->tm_hour = (dtime>>11)&31; + tm->tm_min = (dtime>>5)&63; + tm->tm_sec = (dtime<<1)&62; + + return mktime(tm); +} + + + +unsigned short +_zip_read2(unsigned char **a) +{ + unsigned short ret; + + ret = (*a)[0]+((*a)[1]<<8); + *a += 2; + + return ret; +} + + + +unsigned int +_zip_read4(unsigned char **a) +{ + unsigned int ret; + + ret = ((((((*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + *a += 4; + + return ret; +} + + + +static char * +_zip_readfpstr(FILE *fp, unsigned int len, int nulp, struct zip_error *error) +{ + char *r, *o; + + r = (char *)malloc(nulp ? len+1 : len); + if (!r) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if (fread(r, 1, len, fp)>8)&0xff, fp); + + return; +} + + + +static void +_zip_write4(unsigned int i, FILE *fp) +{ + putc(i&0xff, fp); + putc((i>>8)&0xff, fp); + putc((i>>16)&0xff, fp); + putc((i>>24)&0xff, fp); + + return; +} + + + +static void +_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) +{ + struct tm *tm, tmbuf; + + tm = php_localtime_r(&time, &tmbuf); + *ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + + tm->tm_mday; + *dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + + ((tm->tm_sec)>>1); + + return; +} diff --git a/ext/phar/lib/zip_entry_free.c b/ext/phar/lib/zip_entry_free.c new file mode 100644 index 0000000000..48443cefd5 --- /dev/null +++ b/ext/phar/lib/zip_entry_free.c @@ -0,0 +1,55 @@ +/* + $NiH: zip_entry_free.c,v 1.2 2006/04/09 19:05:47 wiz Exp $ + + zip_entry_free.c -- free struct zip_entry + Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +void +_zip_entry_free(struct zip_entry *ze) +{ + free(ze->ch_filename); + ze->ch_filename = NULL; + free(ze->ch_comment); + ze->ch_comment = NULL; + ze->ch_comment_len = -1; + + _zip_unchange_data(ze); +} diff --git a/ext/phar/lib/zip_entry_new.c b/ext/phar/lib/zip_entry_new.c new file mode 100644 index 0000000000..390b72ad70 --- /dev/null +++ b/ext/phar/lib/zip_entry_new.c @@ -0,0 +1,81 @@ +/* + $NiH: zip_entry_new.c,v 1.2 2006/04/09 19:05:47 wiz Exp $ + + zip_entry_new.c -- create and init struct zip_entry + Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +struct zip_entry * +_zip_entry_new(struct zip *za) +{ + struct zip_entry *ze; + if (!za) { + ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); + if (!ze) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + } + else { + if (za->nentry >= za->nentry_alloc-1) { + za->nentry_alloc += 16; + za->entry = (struct zip_entry *)realloc(za->entry, + sizeof(struct zip_entry) + * za->nentry_alloc); + if (!za->entry) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + } + ze = za->entry+za->nentry; + } + + ze->state = ZIP_ST_UNCHANGED; + + ze->ch_filename = NULL; + ze->ch_comment = NULL; + ze->ch_comment_len = -1; + ze->source = NULL; + + if (za) + za->nentry++; + + return ze; +} diff --git a/ext/phar/lib/zip_err_str.c b/ext/phar/lib/zip_err_str.c new file mode 100644 index 0000000000..c74538d64a --- /dev/null +++ b/ext/phar/lib/zip_err_str.c @@ -0,0 +1,72 @@ +/* + This file was generated automatically by ./make_zip_err_str.sh + from ./zip.h; make changes there. + + NiH: make_zip_err_str.sh,v 1.8 2004/11/17 21:55:09 wiz Exp + NiH: zip.h,v 1.57 2006/04/24 14:04:19 dillo Exp + */ + +#include "zip.h" +#include "zipint.h" + + + +const char * const _zip_err_str[] = { + "No error", + "Multi-disk zip archives not supported", + "Renaming temporary file failed", + "Closing zip archive failed", + "Seek error", + "Read error", + "Write error", + "CRC error", + "Containing zip archive was closed", + "No such file", + "File already exists", + "Can't open file", + "Failure to create temporary file", + "Zlib error", + "Malloc failure", + "Entry has been changed", + "Compression method not supported", + "Premature EOF", + "Invalid argument", + "Not a zip archive", + "Internal error", + "Zip archive inconsistent", + "Can't remove file", + "Entry has been deleted", +}; + +const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); + +#define N ZIP_ET_NONE +#define S ZIP_ET_SYS +#define Z ZIP_ET_ZLIB + +const int _zip_err_type[] = { + N, + N, + S, + S, + S, + S, + S, + N, + N, + N, + N, + S, + S, + Z, + N, + N, + N, + N, + N, + N, + N, + N, + S, + N, +}; diff --git a/ext/phar/lib/zip_error.c b/ext/phar/lib/zip_error.c new file mode 100644 index 0000000000..aec1638dec --- /dev/null +++ b/ext/phar/lib/zip_error.c @@ -0,0 +1,104 @@ +/* + $NiH: zip_error.c,v 1.7 2005/06/09 19:57:09 dillo Exp $ + + zip_error.c -- struct zip_error helper functions + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +void +_zip_error_clear(struct zip_error *err) +{ + err->zip_err = ZIP_ER_OK; + err->sys_err = 0; +} + + + +void +_zip_error_copy(struct zip_error *dst, struct zip_error *src) +{ + dst->zip_err = src->zip_err; + dst->sys_err = src->sys_err; +} + + + +void +_zip_error_fini(struct zip_error *err) +{ + free(err->str); + err->str = NULL; +} + + + +void +_zip_error_get(struct zip_error *err, int *zep, int *sep) +{ + if (zep) + *zep = err->zip_err; + if (sep) { + if (zip_error_get_sys_type(err->zip_err) != ZIP_ET_NONE) + *sep = err->sys_err; + else + *sep = 0; + } +} + + + +void +_zip_error_init(struct zip_error *err) +{ + err->zip_err = ZIP_ER_OK; + err->sys_err = 0; + err->str = NULL; +} + + + +void +_zip_error_set(struct zip_error *err, int ze, int se) +{ + if (err) { + err->zip_err = ze; + err->sys_err = se; + } +} diff --git a/ext/phar/lib/zip_error_clear.c b/ext/phar/lib/zip_error_clear.c new file mode 100644 index 0000000000..e3c81eb318 --- /dev/null +++ b/ext/phar/lib/zip_error_clear.c @@ -0,0 +1,47 @@ +/* + $NiH: zip_error_clear.c,v 1.1 2006/10/04 15:21:09 dillo Exp $ + + zip_error_clear.c -- clear zip error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +void +zip_error_clear(struct zip *za) +{ + _zip_error_clear(&za->error); +} diff --git a/ext/phar/lib/zip_error_get.c b/ext/phar/lib/zip_error_get.c new file mode 100644 index 0000000000..712575a864 --- /dev/null +++ b/ext/phar/lib/zip_error_get.c @@ -0,0 +1,47 @@ +/* + $NiH: zip_error_get.c,v 1.1 2004/11/18 15:06:20 wiz Exp $ + + zip_error_get.c -- get zip error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +void +zip_error_get(struct zip *za, int *zep, int *sep) +{ + _zip_error_get(&za->error, zep, sep); +} diff --git a/ext/phar/lib/zip_error_get_sys_type.c b/ext/phar/lib/zip_error_get_sys_type.c new file mode 100644 index 0000000000..613ec94328 --- /dev/null +++ b/ext/phar/lib/zip_error_get_sys_type.c @@ -0,0 +1,50 @@ +/* + $NiH: zip_error_get_sys_type.c,v 1.1 2004/12/22 15:49:18 wiz Exp $ + + zip_error_get_sys_type.c -- return type of system error code + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_error_get_sys_type(int ze) +{ + if (ze < 0 || ze >= _zip_nerr_str) + return 0; + + return _zip_err_type[ze]; +} diff --git a/ext/phar/lib/zip_error_strerror.c b/ext/phar/lib/zip_error_strerror.c new file mode 100644 index 0000000000..e6eee081df --- /dev/null +++ b/ext/phar/lib/zip_error_strerror.c @@ -0,0 +1,93 @@ +/* + $NiH: zip_error_strerror.c,v 1.4 2006/02/21 09:41:00 dillo Exp $ + + zip_error_sterror.c -- get string representation of struct zip_error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +const char * +_zip_error_strerror(struct zip_error *err) +{ + const char *zs, *ss; + char buf[128], *s; + + _zip_error_fini(err); + + if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { + snprintf(buf, sizeof(buf), "Unknown error %d", err->zip_err); + zs = NULL; + ss = buf; + } + else { + zs = _zip_err_str[err->zip_err]; + + switch (_zip_err_type[err->zip_err]) { + case ZIP_ET_SYS: + ss = strerror(err->sys_err); + break; + + case ZIP_ET_ZLIB: + ss = zError(err->sys_err); + break; + + default: + ss = NULL; + } + } + + if (ss == NULL) + return zs; + else { + int l = strlen(ss) + (zs ? strlen(zs)+2 : 0) + 1; + if ((s=(char *)malloc(l)) == NULL) + return _zip_err_str[ZIP_ER_MEMORY]; + + snprintf(s, l, "%s%s%s", + (zs ? zs : ""), + (zs ? ": " : ""), + ss); + err->str = s; + + return ss; + } +} diff --git a/ext/phar/lib/zip_error_to_str.c b/ext/phar/lib/zip_error_to_str.c new file mode 100644 index 0000000000..e566192255 --- /dev/null +++ b/ext/phar/lib/zip_error_to_str.c @@ -0,0 +1,73 @@ +/* + $NiH: zip_error_to_str.c,v 1.1 2004/11/18 15:06:20 wiz Exp $ + + zip_error_to_str.c -- get string representation of zip error code + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_error_to_str(char *buf, size_t len, int ze, int se) +{ + const char *zs, *ss; + + if (ze < 0 || ze >= _zip_nerr_str) + return snprintf(buf, len, "Unknown error %d", ze); + + zs = _zip_err_str[ze]; + + switch (_zip_err_type[ze]) { + case ZIP_ET_SYS: + ss = strerror(se); + break; + + case ZIP_ET_ZLIB: + ss = zError(se); + break; + + default: + ss = NULL; + } + + return snprintf(buf, len, "%s%s%s", + zs, (ss ? ": " : ""), (ss ? ss : "")); +} diff --git a/ext/phar/lib/zip_fclose.c b/ext/phar/lib/zip_fclose.c new file mode 100644 index 0000000000..c0105a9290 --- /dev/null +++ b/ext/phar/lib/zip_fclose.c @@ -0,0 +1,76 @@ +/* + $NiH: zip_fclose.c,v 1.14 2005/06/09 19:57:09 dillo Exp $ + + zip_fclose.c -- close file in zip archive + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_fclose(struct zip_file *zf) +{ + int i, ret; + + if (zf->zstr) + inflateEnd(zf->zstr); + free(zf->buffer); + free(zf->zstr); + + if (zf->za) { + for (i=0; iza->nfile; i++) { + if (zf->za->file[i] == zf) { + zf->za->file[i] = zf->za->file[zf->za->nfile-1]; + zf->za->nfile--; + break; + } + } + } + + ret = 0; + if (zf->error.zip_err) + ret = zf->error.zip_err; + else if ((zf->flags & ZIP_ZF_CRC) && (zf->flags & ZIP_ZF_EOF)) { + /* if EOF, compare CRC */ + if (zf->crc_orig != zf->crc) + ret = ZIP_ER_CRC; + } + + free(zf); + return ret; +} diff --git a/ext/phar/lib/zip_file_error_clear.c b/ext/phar/lib/zip_file_error_clear.c new file mode 100644 index 0000000000..86ed68f273 --- /dev/null +++ b/ext/phar/lib/zip_file_error_clear.c @@ -0,0 +1,47 @@ +/* + $NiH: zip_file_error_clear.c,v 1.4 2006/10/04 18:37:54 wiz Exp $ + + zip_file_error_clear.c -- clear zip file error + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +void +zip_file_error_clear(struct zip_file *zf) +{ + _zip_error_clear(&zf->error); +} diff --git a/ext/phar/lib/zip_file_error_get.c b/ext/phar/lib/zip_file_error_get.c new file mode 100644 index 0000000000..2ab3a73a4c --- /dev/null +++ b/ext/phar/lib/zip_file_error_get.c @@ -0,0 +1,47 @@ +/* + $NiH: zip_file_error_get.c,v 1.1 2004/11/18 15:06:21 wiz Exp $ + + zip_file_error_get.c -- get zip file error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +void +zip_file_error_get(struct zip_file *zf, int *zep, int *sep) +{ + _zip_error_get(&zf->error, zep, sep); +} diff --git a/ext/phar/lib/zip_file_get_offset.c b/ext/phar/lib/zip_file_get_offset.c new file mode 100644 index 0000000000..8bcc64934d --- /dev/null +++ b/ext/phar/lib/zip_file_get_offset.c @@ -0,0 +1,80 @@ +/* + $NiH: zip_file_get_offset.c,v 1.4 2006/04/23 14:51:45 wiz Exp $ + + zip_file_get_offset.c -- get offset of file data in archive. + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +/* _zip_file_get_offset(za, ze): + Returns the offset of the file data for entry ze. + + On error, fills in za->error and returns 0. +*/ + +unsigned int +_zip_file_get_offset(struct zip *za, int idx) +{ + struct zip_dirent de; + unsigned int offset; + + offset = za->cdir->entry[idx].offset; + + if (fseek(za->zp, offset, SEEK_SET) != 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return 0; + } + + if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0) + return 0; + + offset += LENTRYSIZE + de.filename_len + de.extrafield_len; + + _zip_dirent_finalize(&de); + + return offset; +} diff --git a/ext/phar/lib/zip_file_strerror.c b/ext/phar/lib/zip_file_strerror.c new file mode 100644 index 0000000000..aaff189996 --- /dev/null +++ b/ext/phar/lib/zip_file_strerror.c @@ -0,0 +1,47 @@ +/* + $NiH: zip_file_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $ + + zip_file_sterror.c -- get string representation of zip file error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +const char * +zip_file_strerror(struct zip_file *zf) +{ + return _zip_error_strerror(&zf->error); +} diff --git a/ext/phar/lib/zip_fopen.c b/ext/phar/lib/zip_fopen.c new file mode 100644 index 0000000000..850a8d835a --- /dev/null +++ b/ext/phar/lib/zip_fopen.c @@ -0,0 +1,52 @@ +/* + $NiH: zip_fopen.c,v 1.12 2005/06/09 19:57:09 dillo Exp $ + + zip_fopen.c -- open file in zip archive for reading + Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +struct zip_file * +zip_fopen(struct zip *za, const char *fname, int flags) +{ + int idx; + + if ((idx=zip_name_locate(za, fname, flags)) < 0) + return NULL; + + return zip_fopen_index(za, idx, flags); +} diff --git a/ext/phar/lib/zip_fopen_index.c b/ext/phar/lib/zip_fopen_index.c new file mode 100644 index 0000000000..5da9230b2e --- /dev/null +++ b/ext/phar/lib/zip_fopen_index.c @@ -0,0 +1,219 @@ +/* + $NiH: zip_fopen_index.c,v 1.24 2005/05/20 21:54:53 wiz Exp $ + + zip_fopen_index.c -- open file in zip archive for reading by index + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include + +#include "zip.h" +#include "zipint.h" + +static struct zip_file *_zip_file_new(struct zip *za); + + + +struct zip_file * +zip_fopen_index(struct zip *za, int fileno, int flags) +{ + int len, ret; + int zfflags; + struct zip_file *zf; + + if ((fileno < 0) || (fileno >= za->nentry)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (fileno >= za->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + zfflags = 0; + switch (za->cdir->entry[fileno].comp_method) { + case ZIP_CM_STORE: + zfflags |= ZIP_ZF_CRC; + break; + + case ZIP_CM_DEFLATE: + if ((flags & ZIP_FL_COMPRESSED) == 0) + zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP; + break; + default: + if ((flags & ZIP_FL_COMPRESSED) == 0) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return NULL; + } + break; + } + + zf = _zip_file_new(za); + + zf->flags = zfflags; + /* zf->name = za->cdir->entry[fileno].filename; */ + zf->method = za->cdir->entry[fileno].comp_method; + zf->bytes_left = za->cdir->entry[fileno].uncomp_size; + zf->cbytes_left = za->cdir->entry[fileno].comp_size; + zf->crc_orig = za->cdir->entry[fileno].crc; + + if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) { + zip_fclose(zf); + return NULL; + } + + if ((zf->flags & ZIP_ZF_DECOMP) == 0) + zf->bytes_left = zf->cbytes_left; + else { + if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + zip_fclose(zf); + return NULL; + } + + len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf); + if (len <= 0) { + _zip_error_copy(&za->error, &zf->error); + zip_fclose(zf); + return NULL; + } + + if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + zip_fclose(zf); + return NULL; + } + zf->zstr->zalloc = Z_NULL; + zf->zstr->zfree = Z_NULL; + zf->zstr->opaque = NULL; + zf->zstr->next_in = (Bytef *)zf->buffer; + zf->zstr->avail_in = len; + + /* negative value to tell zlib that there is no header */ + if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) { + _zip_error_set(&za->error, ZIP_ER_ZLIB, ret); + zip_fclose(zf); + return NULL; + } + } + + return zf; +} + + + +int +_zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf) +{ + int i, j; + + if (zf->error.zip_err != ZIP_ER_OK) + return -1; + + if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0) + return 0; + + if (fseek(zf->za->zp, zf->fpos, SEEK_SET) < 0) { + _zip_error_set(&zf->error, ZIP_ER_SEEK, errno); + return -1; + } + if (buflen < zf->cbytes_left) + i = buflen; + else + i = zf->cbytes_left; + + j = fread(buf, 1, i, zf->za->zp); + if (j == 0) { + _zip_error_set(&zf->error, ZIP_ER_EOF, 0); + j = -1; + } + else if (j < 0) + _zip_error_set(&zf->error, ZIP_ER_READ, errno); + else { + zf->fpos += j; + zf->cbytes_left -= j; + } + + return j; +} + + + +static struct zip_file * +_zip_file_new(struct zip *za) +{ + struct zip_file *zf, **file; + int n; + + if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if (za->nfile >= za->nfile_alloc-1) { + n = za->nfile_alloc + 10; + file = (struct zip_file **)realloc(za->file, + n*sizeof(struct zip_file *)); + if (file == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + free(zf); + return NULL; + } + za->nfile_alloc = n; + za->file = file; + } + + za->file[za->nfile++] = zf; + + zf->za = za; + _zip_error_init(&zf->error); + zf->flags = 0; + zf->crc = crc32(0L, Z_NULL, 0); + zf->crc_orig = 0; + zf->method = -1; + zf->bytes_left = zf->cbytes_left = 0; + zf->fpos = 0; + zf->buffer = NULL; + zf->zstr = NULL; + + return zf; +} diff --git a/ext/phar/lib/zip_fread.c b/ext/phar/lib/zip_fread.c new file mode 100644 index 0000000000..aeb64c90fa --- /dev/null +++ b/ext/phar/lib/zip_fread.c @@ -0,0 +1,125 @@ +/* + $NiH: zip_fread.c,v 1.21 2006/04/23 14:49:50 wiz Exp $ + + zip_fread.c -- read from file + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +ssize_t +zip_fread(struct zip_file *zf, void *outbuf, size_t toread) +{ + int ret; + size_t out_before, len; + int i; + + if (!zf) + return -1; + + if (zf->error.zip_err != 0) + return -1; + + if ((zf->flags & ZIP_ZF_EOF) || (toread == 0)) + return 0; + + if (zf->bytes_left == 0) { + zf->flags |= ZIP_ZF_EOF; + if (zf->flags & ZIP_ZF_CRC) { + if (zf->crc != zf->crc_orig) { + _zip_error_set(&zf->error, ZIP_ER_CRC, 0); + return -1; + } + } + return 0; + } + + if ((zf->flags & ZIP_ZF_DECOMP) == 0) { + ret = _zip_file_fillbuf(outbuf, toread, zf); + if (ret > 0) { + if (zf->flags & ZIP_ZF_CRC) + zf->crc = crc32(zf->crc, (Bytef *)outbuf, ret); + zf->bytes_left -= ret; + } + return ret; + } + + zf->zstr->next_out = (Bytef *)outbuf; + zf->zstr->avail_out = toread; + out_before = zf->zstr->total_out; + + /* endless loop until something has been accomplished */ + for (;;) { + ret = inflate(zf->zstr, Z_SYNC_FLUSH); + + switch (ret) { + case Z_OK: + case Z_STREAM_END: + /* all ok */ + /* Z_STREAM_END probably won't happen, since we didn't + have a header */ + len = zf->zstr->total_out - out_before; + if (len >= zf->bytes_left || len >= toread) { + if (zf->flags & ZIP_ZF_CRC) + zf->crc = crc32(zf->crc, (Bytef *)outbuf, len); + zf->bytes_left -= len; + return len; + } + break; + + case Z_BUF_ERROR: + if (zf->zstr->avail_in == 0) { + i = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf); + if (i == 0) { + _zip_error_set(&zf->error, ZIP_ER_INCONS, 0); + return -1; + } + else if (i < 0) + return -1; + zf->zstr->next_in = (Bytef *)zf->buffer; + zf->zstr->avail_in = i; + continue; + } + /* fallthrough */ + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_STREAM_ERROR: + case Z_MEM_ERROR: + _zip_error_set(&zf->error, ZIP_ER_ZLIB, ret); + return -1; + } + } +} diff --git a/ext/phar/lib/zip_free.c b/ext/phar/lib/zip_free.c new file mode 100644 index 0000000000..c78697d254 --- /dev/null +++ b/ext/phar/lib/zip_free.c @@ -0,0 +1,86 @@ +/* + $NiH: zip_free.c,v 1.17 2005/06/09 19:57:10 dillo Exp $ + + zip_free.c -- free struct zip + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include "zip.h" +#include "zipint.h" + + + +/* _zip_free: + frees the space allocated to a zipfile struct, and closes the + corresponding file. */ + +void +_zip_free(struct zip *za) +{ + int i; + + if (za == NULL) + return; + + if (za->zn) + free(za->zn); + + if (za->zp) + fclose(za->zp); + + if (za->ch_comment) + free(za->ch_comment); + + _zip_cdir_free(za->cdir); + + if (za->entry) { + for (i=0; inentry; i++) { + _zip_entry_free(za->entry+i); + } + free(za->entry); + } + + for (i=0; infile; i++) { + if (za->file[i]->error.zip_err == ZIP_ER_OK) { + _zip_error_set(&za->file[i]->error, ZIP_ER_ZIPCLOSED, 0); + za->file[i]->za = NULL; + } + } + + free(za->file); + + free(za); + + return; +} diff --git a/ext/phar/lib/zip_get_archive_comment.c b/ext/phar/lib/zip_get_archive_comment.c new file mode 100644 index 0000000000..7844c5e191 --- /dev/null +++ b/ext/phar/lib/zip_get_archive_comment.c @@ -0,0 +1,58 @@ +/* + $NiH: zip_get_archive_comment.c,v 1.4 2006/04/23 16:11:33 wiz Exp $ + + zip_get_archive_comment.c -- get archive comment + Copyright (C) 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +const char * +zip_get_archive_comment(struct zip *za, int *lenp, int flags) +{ + if ((flags & ZIP_FL_UNCHANGED) + || (za->ch_comment_len == -1)) { + if (za->cdir) { + if (lenp != NULL) + *lenp = za->cdir->comment_len; + return za->cdir->comment; + } + } + + if (lenp != NULL) + *lenp = za->ch_comment_len; + return za->ch_comment; +} diff --git a/ext/phar/lib/zip_get_file_comment.c b/ext/phar/lib/zip_get_file_comment.c new file mode 100644 index 0000000000..79a5c236bc --- /dev/null +++ b/ext/phar/lib/zip_get_file_comment.c @@ -0,0 +1,61 @@ +/* + $NiH: zip_get_file_comment.c,v 1.2 2006/04/23 13:06:28 wiz Exp $ + + zip_get_file_comment.c -- get file comment + Copyright (C) 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +const char * +zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags) +{ + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) + || (za->entry[idx].ch_comment_len == -1)) { + if (lenp != NULL) + *lenp = za->cdir->entry[idx].comment_len; + return za->cdir->entry[idx].comment; + } + + if (lenp != NULL) + *lenp = za->entry[idx].ch_comment_len; + return za->entry[idx].ch_comment; +} diff --git a/ext/phar/lib/zip_get_name.c b/ext/phar/lib/zip_get_name.c new file mode 100644 index 0000000000..c45dd0333f --- /dev/null +++ b/ext/phar/lib/zip_get_name.c @@ -0,0 +1,74 @@ +/* + $NiH: zip_get_name.c,v 1.13 2005/01/20 21:00:54 dillo Exp $ + + zip_get_name.c -- get filename for a file in zip file + Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +const char * +zip_get_name(struct zip *za, int idx, int flags) +{ + return _zip_get_name(za, idx, flags, &za->error); +} + + + +const char * +_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error) +{ + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0) { + if (za->entry[idx].state == ZIP_ST_DELETED) { + _zip_error_set(error, ZIP_ER_DELETED, 0); + return NULL; + } + if (za->entry[idx].ch_filename) + return za->entry[idx].ch_filename; + } + + if (za->cdir == NULL || idx >= za->cdir->nentry) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return za->cdir->entry[idx].filename; +} diff --git a/ext/phar/lib/zip_get_num_files.c b/ext/phar/lib/zip_get_num_files.c new file mode 100644 index 0000000000..0cc81edb06 --- /dev/null +++ b/ext/phar/lib/zip_get_num_files.c @@ -0,0 +1,50 @@ +/* + $NiH: zip_get_num_files.c,v 1.2 2003/12/27 22:53:15 wiz Exp $ + + zip_get_num_files.c -- get number of files in archive + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_get_num_files(struct zip *za) +{ + if (za == NULL) + return -1; + + return za->nentry; +} diff --git a/ext/phar/lib/zip_memdup.c b/ext/phar/lib/zip_memdup.c new file mode 100644 index 0000000000..c4ecf4a69f --- /dev/null +++ b/ext/phar/lib/zip_memdup.c @@ -0,0 +1,58 @@ +/* + $NiH: zip_memdup.c,v 1.2 2006/04/24 10:34:39 dillo Exp $ + + zip_memdup.c -- internal zip function, "strdup" with len + Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +void * +_zip_memdup(const void *mem, size_t len, struct zip_error *error) +{ + void *ret; + + ret = malloc(len); + if (!ret) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + memcpy(ret, mem, len); + + return ret; +} diff --git a/ext/phar/lib/zip_name_locate.c b/ext/phar/lib/zip_name_locate.c new file mode 100644 index 0000000000..a2fce2d034 --- /dev/null +++ b/ext/phar/lib/zip_name_locate.c @@ -0,0 +1,91 @@ +/* + $NiH: zip_name_locate.c,v 1.19 2005/06/09 19:57:10 dillo Exp $ + + zip_name_locate.c -- get index by name + Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_name_locate(struct zip *za, const char *fname, int flags) +{ + return _zip_name_locate(za, fname, flags, &za->error); +} + + + +int +_zip_name_locate(struct zip *za, const char *fname, int flags, + struct zip_error *error) +{ + int (*cmp)(const char *, const char *); + const char *fn, *p; + int i, n; + + if (fname == NULL) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return -1; + } + + cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; + + n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; + for (i=0; icdir->entry[i].filename; + else + fn = _zip_get_name(za, i, flags, error); + + /* newly added (partially filled) entry */ + if (fn == NULL) + continue; + + if (flags & ZIP_FL_NODIR) { + p = strrchr(fn, '/'); + if (p) + fn = p+1; + } + + if (cmp(fname, fn) == 0) + return i; + } + + _zip_error_set(error, ZIP_ER_NOENT, 0); + return -1; +} diff --git a/ext/phar/lib/zip_new.c b/ext/phar/lib/zip_new.c new file mode 100644 index 0000000000..660183a15c --- /dev/null +++ b/ext/phar/lib/zip_new.c @@ -0,0 +1,71 @@ +/* + $NiH: zip_new.c,v 1.12 2006/04/23 00:40:47 wiz Exp $ + + zip_new.c -- create and init struct zip + Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include "zip.h" +#include "zipint.h" + + + +/* _zip_new: + creates a new zipfile struct, and sets the contents to zero; returns + the new struct. */ + +struct zip * +_zip_new(struct zip_error *error) +{ + struct zip *za; + + za = (struct zip *)malloc(sizeof(struct zip)); + if (!za) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + za->zn = NULL; + za->zp = NULL; + _zip_error_init(&za->error); + za->cdir = NULL; + za->ch_comment = NULL; + za->ch_comment_len = -1; + za->nentry = za->nentry_alloc = 0; + za->entry = NULL; + za->nfile = za->nfile_alloc = 0; + za->file = NULL; + + return za; +} diff --git a/ext/phar/lib/zip_open.c b/ext/phar/lib/zip_open.c new file mode 100644 index 0000000000..60526e8c91 --- /dev/null +++ b/ext/phar/lib/zip_open.c @@ -0,0 +1,468 @@ +/* + $NiH: zip_open.c,v 1.38 2006/05/04 00:01:26 dillo Exp $ + + zip_open.c -- open zip archive + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include "zip.h" +#include "zipint.h" + +static void set_error(int *, struct zip_error *, int); +static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); +static int _zip_headercomp(struct zip_dirent *, int, + struct zip_dirent *, int); +static unsigned char *_zip_memmem(const unsigned char *, int, + const unsigned char *, int); +static struct zip_cdir *_zip_readcdir(FILE *, unsigned char *, unsigned char *, + int, int, struct zip_error *); + + + +struct zip * +zip_open(const char *fn, int flags, int *zep) +{ + FILE *fp; + unsigned char *buf, *match; + int a, i, buflen, best; + struct zip *za; + struct zip_cdir *cdir, *cdirnew; + long len; + struct stat st; + struct zip_error error, err2; + + if (fn == NULL) { + set_error(zep, NULL, ZIP_ER_INVAL); + return NULL; + } + + if (flags & ZIP_OVERWRITE || stat(fn, &st) != 0) { + if ((flags & ZIP_CREATE) || (flags & ZIP_OVERWRITE)) { + if ((za=_zip_new(&error)) == NULL) { + set_error(zep, &error, 0); + return NULL; + } + + za->zn = strdup(fn); + if (!za->zn) { + _zip_free(za); + set_error(zep, NULL, ZIP_ER_MEMORY); + return NULL; + } + return za; + } + else { + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + } + else if ((flags & ZIP_EXCL)) { + set_error(zep, NULL, ZIP_ER_EXISTS); + return NULL; + } + + /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, + just like open() */ + if ((fp=fopen(fn, "rb")) == NULL) { + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + +#ifdef PHP_WIN32 + _setmode(_fileno(fp), _O_BINARY ); +#endif + + clearerr(fp); + fseek(fp, 0, SEEK_END); + len = ftell(fp); + i = fseek(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); + if (i == -1 && errno != EFBIG) { + /* seek before start of file on my machine */ + set_error(zep, NULL, ZIP_ER_SEEK); + fclose(fp); + return NULL; + } + + /* 64k is too much for stack */ + if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) { + set_error(zep, NULL, ZIP_ER_MEMORY); + fclose(fp); + return NULL; + } + + clearerr(fp); + buflen = fread(buf, 1, CDBUFSIZE, fp); + + if (ferror(fp)) { + set_error(zep, NULL, ZIP_ER_READ); + free(buf); + fclose(fp); + return NULL; + } + + best = -2; + cdir = NULL; + match = buf; + while ((match=_zip_memmem(match, buflen-(match-buf)-18, + (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { + /* found match -- check, if good */ + /* to avoid finding the same match all over again */ + match++; + if ((cdirnew=_zip_readcdir(fp, buf, match-1, buflen, flags, + &err2)) == NULL) { + if (best == -2) { + set_error(zep, &err2, 0); + best = -1; + } + continue; + } + + if (cdir) { + if (best <= 0) + best = _zip_checkcons(fp, cdir, &err2); + a = _zip_checkcons(fp, cdirnew, &err2); + if (best < a) { + _zip_cdir_free(cdir); + cdir = cdirnew; + best = a; + } + else + _zip_cdir_free(cdirnew); + } + else { + cdir = cdirnew; + if (flags & ZIP_CHECKCONS) + best = _zip_checkcons(fp, cdir, &err2); + else + best = 0; + } + cdirnew = NULL; + } + + free(buf); + + if (best < 0) { + /* no consistent eocd found */ + if (best == -2) { + /* no eocd found at all */ + set_error(zep, NULL, ZIP_ER_NOZIP); + } + _zip_cdir_free(cdir); + fclose(fp); + return NULL; + } + + if ((za=_zip_new(&error)) == NULL) { + set_error(zep, &error, 0); + _zip_cdir_free(cdir); + fclose(fp); + return NULL; + } + + za->zp = fp; + za->cdir = cdir; + + if ((za->zn=strdup(fn)) == NULL) { + set_error(zep, NULL, ZIP_ER_MEMORY); + _zip_free(za); + return NULL; + } + + if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) + * cdir->nentry)) == NULL) { + set_error(zep, NULL, ZIP_ER_MEMORY); + _zip_free(za); + return NULL; + } + for (i=0; inentry; i++) + _zip_entry_new(za); + + return za; +} + + + +static void +set_error(int *zep, struct zip_error *err, int ze) +{ + int se; + + if (err) { + _zip_error_get(err, &ze, &se); + if (zip_error_get_sys_type(ze) == ZIP_ET_SYS) + errno = se; + } + + if (zep) + *zep = ze; +} + + + +/* _zip_readcdir: + tries to find a valid end-of-central-directory at the beginning of + buf, and then the corresponding central directory entries. + Returns a struct zip_cdir which contains the central directory + entries, or NULL if unsuccessful. */ + +static struct zip_cdir * +_zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, + int flags, struct zip_error *error) +{ + struct zip_cdir *cd; + unsigned char *cdp, **bufp; + int i, comlen, nentry; + + comlen = buf + buflen - eocd - EOCDLEN; + if (comlen < 0) { + /* not enough bytes left for comment */ + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return NULL; + } + + /* check for end-of-central-dir magic */ + if (memcmp(eocd, EOCD_MAGIC, 4) != 0) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return NULL; + } + + if (memcmp(eocd+4, "\0\0\0\0", 4) != 0) { + _zip_error_set(error, ZIP_ER_MULTIDISK, 0); + return NULL; + } + + cdp = eocd + 8; + /* number of cdir-entries on this disk */ + i = _zip_read2(&cdp); + /* number of cdir-entries */ + nentry = _zip_read2(&cdp); + + if ((cd=_zip_cdir_new(nentry, error)) == NULL) + return NULL; + + cd->size = _zip_read4(&cdp); + cd->offset = _zip_read4(&cdp); + cd->comment = NULL; + cd->comment_len = _zip_read2(&cdp); + + if ((comlen < cd->comment_len) || (cd->nentry != i)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + free(cd); + return NULL; + } + if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + free(cd); + return NULL; + } + + if (cd->comment_len) + if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, + cd->comment_len, error)) + == NULL) { + free(cd); + return NULL; + } + + cdp = eocd; + if (cd->size < (unsigned int)(eocd-buf)) { + /* if buffer already read in, use it */ + cdp = eocd - cd->size; + bufp = &cdp; + } + else { + /* go to start of cdir and read it entry by entry */ + bufp = NULL; + clearerr(fp); + fseek(fp, -(cd->size+cd->comment_len+EOCDLEN), SEEK_END); + if (ferror(fp) || ((unsigned int)ftell(fp) != cd->offset)) { + /* seek error or offset of cdir wrong */ + if (ferror(fp)) + _zip_error_set(error, ZIP_ER_SEEK, errno); + else + _zip_error_set(error, ZIP_ER_NOZIP, 0); + free(cd); + return NULL; + } + } + + for (i=0; inentry; i++) { + if ((_zip_dirent_read(cd->entry+i, fp, bufp, eocd-cdp, 0, + error)) < 0) { + cd->nentry = i; + _zip_cdir_free(cd); + return NULL; + } + } + + return cd; +} + + + +/* _zip_checkcons: + Checks the consistency of the central directory by comparing central + directory entries with local headers and checking for plausible + file and header offsets. Returns -1 if not plausible, else the + difference between the lowest and the highest fileposition reached */ + +static int +_zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) +{ + int i; + unsigned int min, max, j; + struct zip_dirent temp; + + if (cd->nentry) { + max = cd->entry[0].offset; + min = cd->entry[0].offset; + } + else + min = max = 0; + + for (i=0; inentry; i++) { + if (cd->entry[i].offset < min) + min = cd->entry[i].offset; + if (min > cd->offset) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + j = cd->entry[i].offset + cd->entry[i].comp_size + + cd->entry[i].filename_len + LENTRYSIZE; + if (j > max) + max = j; + if (max > cd->offset) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + if (fseek(fp, cd->entry[i].offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, 0); + return -1; + } + + if (_zip_dirent_read(&temp, fp, NULL, 0, 1, error) == -1) + return -1; + + if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + _zip_dirent_finalize(&temp); + return -1; + } + _zip_dirent_finalize(&temp); + } + + return max - min; +} + + + +/* _zip_headercomp: + compares two headers h1 and h2; if they are local headers, set + local1p or local2p respectively to 1, else 0. Return 0 if they + are identical, -1 if not. */ + +static int +_zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, + int local2p) +{ + if ((h1->version_needed != h2->version_needed) +#if 0 + /* some zip-files have different values in local + and global headers for the bitflags */ + || (h1->bitflags != h2->bitflags) +#endif + || (h1->comp_method != h2->comp_method) + || (h1->last_mod != h2->last_mod) + || (h1->crc != h2->crc) + || (h1->comp_size != h2->comp_size) + || (h1->uncomp_size != h2->uncomp_size) + || (h1->filename_len != h2->filename_len) + || !h1->filename || !h2->filename + || strcmp(h1->filename, h2->filename)) + return -1; + + if ((local1p == local2p) + && ((h1->extrafield_len != h2->extrafield_len) + || (h1->extrafield_len && h2->extrafield + && memcmp(h1->extrafield, h2->extrafield, + h1->extrafield_len)))) + return -1; + + /* if either is local, nothing more to check */ + if (local1p || local2p) + return 0; + + if ((h1->version_madeby != h2->version_madeby) + || (h1->disk_number != h2->disk_number) + || (h1->int_attrib != h2->int_attrib) + || (h1->ext_attrib != h2->ext_attrib) + || (h1->offset != h2->offset) + || (h1->comment_len != h2->comment_len) + || (h1->comment_len && h2->comment + && memcmp(h1->comment, h2->comment, h1->comment_len))) + return -1; + + return 0; +} + + + +static unsigned char * +_zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, + int littlelen) +{ + const unsigned char *p; + + if ((biglen < littlelen) || (littlelen == 0)) + return NULL; + p = big-1; + while ((p=(const unsigned char *) + memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1))) + != NULL) { + if (memcmp(p+1, little+1, littlelen-1)==0) + return (unsigned char *)p; + } + + return NULL; +} diff --git a/ext/phar/lib/zip_rename.c b/ext/phar/lib/zip_rename.c new file mode 100644 index 0000000000..f35291893f --- /dev/null +++ b/ext/phar/lib/zip_rename.c @@ -0,0 +1,52 @@ +/* + $NiH: zip_rename.c,v 1.15 2004/11/30 22:19:38 wiz Exp $ + + zip_rename.c -- rename file in zip archive + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_rename(struct zip *za, int idx, const char *name) +{ + if (idx >= za->nentry || idx < 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + return _zip_set_name(za, idx, name); +} diff --git a/ext/phar/lib/zip_replace.c b/ext/phar/lib/zip_replace.c new file mode 100644 index 0000000000..ae78e62b80 --- /dev/null +++ b/ext/phar/lib/zip_replace.c @@ -0,0 +1,82 @@ +/* + $NiH: zip_replace.c,v 1.20 2006/04/09 14:52:02 wiz Exp $ + + zip_replace.c -- replace file via callback function + Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_replace(struct zip *za, int idx, struct zip_source *source) +{ + if (idx < 0 || idx >= za->nentry || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_replace(za, idx, NULL, source) == -1) + return -1; + + return 0; +} + + + + +int +_zip_replace(struct zip *za, int idx, const char *name, + struct zip_source *source) +{ + if (idx == -1) { + if (_zip_entry_new(za) == NULL) + return -1; + idx = za->nentry - 1; + } + + + _zip_unchange_data(za->entry+idx); + + if (name && _zip_set_name(za, idx, name) != 0) + return -1; + + + za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry) + ? ZIP_ST_ADDED : ZIP_ST_REPLACED); + za->entry[idx].source = source; + + return idx; +} diff --git a/ext/phar/lib/zip_set_archive_comment.c b/ext/phar/lib/zip_set_archive_comment.c new file mode 100644 index 0000000000..b0929e56b6 --- /dev/null +++ b/ext/phar/lib/zip_set_archive_comment.c @@ -0,0 +1,68 @@ +/* + $NiH: zip_set_archive_comment.c,v 1.3 2006/04/24 10:34:39 dillo Exp $ + + zip_set_archive_comment.c -- set archive comment + Copyright (C) 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_set_archive_comment(struct zip *za, const char *comment, int len) +{ + char *tmpcom; + + if (len < 0 || len > MAXCOMLEN + || (len > 0 && comment == NULL)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (len > 0) { + if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) + return -1; + } + else + tmpcom = NULL; + + if (za->ch_comment) free(za->ch_comment); + za->ch_comment = tmpcom; + za->ch_comment_len = len; + + return 0; +} diff --git a/ext/phar/lib/zip_set_file_comment.c b/ext/phar/lib/zip_set_file_comment.c new file mode 100644 index 0000000000..cbf71db5c2 --- /dev/null +++ b/ext/phar/lib/zip_set_file_comment.c @@ -0,0 +1,69 @@ +/* + $NiH: zip_set_file_comment.c,v 1.4 2006/04/24 10:34:39 dillo Exp $ + + zip_set_file_comment.c -- set comment for file in archive + Copyright (C) 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_set_file_comment(struct zip *za, int idx, const char *comment, int len) +{ + char *tmpcom; + + if (idx < 0 || idx >= za->nentry + || len < 0 || len > MAXCOMLEN + || (len > 0 && comment == NULL)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (len > 0) { + if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) + return -1; + } + else + tmpcom = NULL; + + free(za->entry[idx].ch_comment); + za->entry[idx].ch_comment = tmpcom; + za->entry[idx].ch_comment_len = len; + + return 0; +} diff --git a/ext/phar/lib/zip_set_name.c b/ext/phar/lib/zip_set_name.c new file mode 100644 index 0000000000..46dca56466 --- /dev/null +++ b/ext/phar/lib/zip_set_name.c @@ -0,0 +1,77 @@ +/* + $NiH: zip_set_name.c,v 1.16 2004/11/30 23:02:47 wiz Exp $ + + zip_set_name.c -- rename helper function + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include "zip.h" +#include "zipint.h" + + + +int +_zip_set_name(struct zip *za, int idx, const char *name) +{ + char *s; + int i; + + if (idx < 0 || idx >= za->nentry || name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) { + _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); + return -1; + } + + /* no effective name change */ + if (i == idx) + return 0; + + if ((s=strdup(name)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + + if (za->entry[idx].state == ZIP_ST_UNCHANGED) + za->entry[idx].state = ZIP_ST_RENAMED; + + free(za->entry[idx].ch_filename); + za->entry[idx].ch_filename = s; + + return 0; +} diff --git a/ext/phar/lib/zip_source_buffer.c b/ext/phar/lib/zip_source_buffer.c new file mode 100644 index 0000000000..a01f18d3f2 --- /dev/null +++ b/ext/phar/lib/zip_source_buffer.c @@ -0,0 +1,160 @@ +/* + $NiH: zip_source_buffer.c,v 1.8 2006/04/23 14:50:49 wiz Exp $ + + zip_source_buffer.c -- create zip data source from buffer + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zip.h" +#include "zipint.h" + +struct read_data { + const char *buf, *data, *end; + time_t mtime; + int freep; +}; + +static ssize_t read_data(void *state, void *data, size_t len, + enum zip_source_cmd cmd); + + + +struct zip_source * +zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) +{ + struct read_data *f; + struct zip_source *zs; + + if (za == NULL) + return NULL; + + if (len < 0 || (data == NULL && len > 0)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((f=(struct read_data *)malloc(sizeof(*f))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + f->data = (const char *)data; + f->end = ((const char *)data)+len; + f->freep = freep; + f->mtime = time(NULL); + + if ((zs=zip_source_function(za, read_data, f)) == NULL) { + free(f); + return NULL; + } + + return zs; +} + +static ssize_t +read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + struct read_data *z; + char *buf; + size_t n; + + z = (struct read_data *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + z->buf = z->data; + return 0; + + case ZIP_SOURCE_READ: + n = z->end - z->buf; + if (n > len) + n = len; + if (n < 0) + n = 0; + + if (n) { + memcpy(buf, z->buf, n); + z->buf += n; + } + + return n; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + + if (len < sizeof(*st)) + return -1; + + st = (struct zip_stat *)data; + + zip_stat_init(st); + st->mtime = z->mtime; + st->size = z->end - z->data; + + return sizeof(*st); + } + + case ZIP_SOURCE_ERROR: + { + int *e; + + if (len < sizeof(int)*2) + return -1; + + e = (int *)data; + e[0] = e[1] = 0; + } + return sizeof(int)*2; + + case ZIP_SOURCE_FREE: + if (z->freep) { + free((void *)z->data); + z->data = NULL; + } + free(z); + return 0; + + default: + ; + } + + return -1; +} diff --git a/ext/phar/lib/zip_source_file.c b/ext/phar/lib/zip_source_file.c new file mode 100644 index 0000000000..d635da3421 --- /dev/null +++ b/ext/phar/lib/zip_source_file.c @@ -0,0 +1,75 @@ +/* + $NiH: zip_source_file.c,v 1.2 2004/11/18 16:28:13 wiz Exp $ + + zip_source_file.c -- create data source from file + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +struct zip_source * +zip_source_file(struct zip *za, const char *fname, off_t start, off_t len) +{ + struct zip_source *zs; + FILE *fp; + + if (za == NULL) + return NULL; + + if (fname == NULL || start < 0 || len < -1) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((fp=fopen(fname, "rb")) == NULL) { + _zip_error_set(&za->error, ZIP_ER_OPEN, errno); + return NULL; + } + +#ifdef PHP_WIN32 + _setmode(_fileno(fp), _O_BINARY ); +#endif + + if ((zs=zip_source_filep(za, fp, start, len)) == NULL) { + fclose(fp); + return NULL; + } + + return zs; +} diff --git a/ext/phar/lib/zip_source_filep.c b/ext/phar/lib/zip_source_filep.c new file mode 100644 index 0000000000..efc702686c --- /dev/null +++ b/ext/phar/lib/zip_source_filep.c @@ -0,0 +1,176 @@ +/* + $NiH: zip_source_filep.c,v 1.6 2005/06/09 19:57:10 dillo Exp $ + + zip_source_filep.c -- create data source from FILE * + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include +#include +#include +#include + +#include "zip.h" +#include "zipint.h" + +struct read_file { + FILE *f; /* file to copy from */ + off_t off; /* start offset of */ + off_t len; /* lengt of data to copy */ + off_t remain; /* bytes remaining to be copied */ + int e[2]; /* error codes */ +}; + +static ssize_t read_file(void *state, void *data, size_t len, + enum zip_source_cmd cmd); + + + +struct zip_source * +zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len) +{ + struct read_file *f; + struct zip_source *zs; + + if (za == NULL) + return NULL; + + if (file == NULL || start < 0 || len < -1) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + f->f = file; + f->off = start; + f->len = (len ? len : -1); + + if ((zs=zip_source_function(za, read_file, f)) == NULL) { + free(f); + return NULL; + } + + return zs; +} + + + +static ssize_t +read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + struct read_file *z; + char *buf; + int i, n; + + z = (struct read_file *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + if (fseeko(z->f, z->off, SEEK_SET) < 0) { + z->e[0] = ZIP_ER_SEEK; + z->e[1] = errno; + return -1; + } + z->remain = z->len; + return 0; + + case ZIP_SOURCE_READ: + if (z->remain != -1) + n = len > z->remain ? z->remain : len; + else + n = len; + + if ((i=fread(buf, 1, n, z->f)) < 0) { + z->e[0] = ZIP_ER_READ; + z->e[1] = errno; + return -1; + } + + if (z->remain != -1) + z->remain -= i; + + return i; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + struct stat fst; + + if (len < sizeof(*st)) + return -1; + + if (fstat(fileno(z->f), &fst) != 0) { + z->e[0] = ZIP_ER_READ; /* best match */ + z->e[1] = errno; + return -1; + } + + st = (struct zip_stat *)data; + + zip_stat_init(st); + st->mtime = fst.st_mtime; + if (z->len != -1) + st->size = z->len; + else if ((fst.st_mode&S_IFMT) == S_IFREG) + st->size = fst.st_size; + + return sizeof(*st); + } + + case ZIP_SOURCE_ERROR: + if (len < sizeof(int)*2) + return -1; + + memcpy(data, z->e, sizeof(int)*2); + return sizeof(int)*2; + + case ZIP_SOURCE_FREE: + fclose(z->f); + free(z); + return 0; + + default: + ; + } + + return -1; +} diff --git a/ext/phar/lib/zip_source_free.c b/ext/phar/lib/zip_source_free.c new file mode 100644 index 0000000000..33e36eaf43 --- /dev/null +++ b/ext/phar/lib/zip_source_free.c @@ -0,0 +1,54 @@ +/* + $NiH: zip_source_free.c,v 1.2 2004/12/22 16:32:00 dillo Exp $ + + zip_source_free.c -- free zip data source + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +void +zip_source_free(struct zip_source *source) +{ + if (source == NULL) + return; + + (void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE); + + free(source); +} diff --git a/ext/phar/lib/zip_source_function.c b/ext/phar/lib/zip_source_function.c new file mode 100644 index 0000000000..4f01a43c51 --- /dev/null +++ b/ext/phar/lib/zip_source_function.c @@ -0,0 +1,62 @@ +/* + $NiH: zip_source_function.c,v 1.4 2006/02/21 09:41:00 dillo Exp $ + + zip_source_function.c -- create zip data source from callback function + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zip.h" +#include "zipint.h" + + + +struct zip_source * +zip_source_function(struct zip *za, zip_source_callback zcb, void *ud) +{ + struct zip_source *zs; + + if (za == NULL) + return NULL; + + if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + zs->f = zcb; + zs->ud = ud; + + return zs; +} diff --git a/ext/phar/lib/zip_source_zip.c b/ext/phar/lib/zip_source_zip.c new file mode 100644 index 0000000000..a31fd2787e --- /dev/null +++ b/ext/phar/lib/zip_source_zip.c @@ -0,0 +1,189 @@ +/* + $NiH: zip_source_zip.c,v 1.7 2006/02/21 09:41:00 dillo Exp $ + + zip_source_zip.c -- create data source from zip file + Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zip.h" +#include "zipint.h" + +struct read_zip { + struct zip_file *zf; + struct zip_stat st; + off_t off, len; +}; + +static ssize_t read_zip(void *st, void *data, size_t len, + enum zip_source_cmd cmd); + + + +struct zip_source * +zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, + off_t start, off_t len) +{ + struct zip_error error; + struct zip_source *zs; + struct read_zip *p; + + if (za == NULL) + return NULL; + + if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (len == 0) + len = -1; + + if (start == 0 && len == -1) + flags |= ZIP_FL_COMPRESSED; + else + flags &= ~ZIP_FL_COMPRESSED; + + if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + _zip_error_copy(&error, &srcza->error); + + if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0 + || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) { + free(p); + _zip_error_copy(&za->error, &srcza->error); + _zip_error_copy(&srcza->error, &error); + + return NULL; + } + p->off = start; + p->len = len; + + if ((flags & ZIP_FL_COMPRESSED) == 0) { + p->st.size = p->st.comp_size = len; + p->st.comp_method = ZIP_CM_STORE; + p->st.crc = 0; + } + + if ((zs=zip_source_function(za, read_zip, p)) == NULL) { + free(p); + return NULL; + } + + return zs; +} + + + +static ssize_t +read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + struct read_zip *z; + char b[8192], *buf; + int i, n; + + z = (struct read_zip *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + for (n=0; noff; n+= i) { + i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n); + if ((i=zip_fread(z->zf, b, i)) < 0) { + zip_fclose(z->zf); + z->zf = NULL; + return -1; + } + } + return 0; + + case ZIP_SOURCE_READ: + if (z->len != -1) + n = len > z->len ? z->len : len; + else + n = len; + + + if ((i=zip_fread(z->zf, buf, n)) < 0) + return -1; + + if (z->len != -1) + z->len -= i; + + return i; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + if (len < sizeof(z->st)) + return -1; + len = sizeof(z->st); + + memcpy(data, &z->st, len); + return len; + + case ZIP_SOURCE_ERROR: + { + int *e; + + if (len < sizeof(int)*2) + return -1; + + e = (int *)data; + zip_file_error_get(z->zf, e, e+1); + } + return sizeof(int)*2; + + case ZIP_SOURCE_FREE: + zip_fclose(z->zf); + free(z); + return 0; + + default: + ; + } + + return -1; +} diff --git a/ext/phar/lib/zip_stat.c b/ext/phar/lib/zip_stat.c new file mode 100644 index 0000000000..bea153d157 --- /dev/null +++ b/ext/phar/lib/zip_stat.c @@ -0,0 +1,52 @@ +/* + $NiH: zip_stat.c,v 1.3 2004/04/16 09:40:30 dillo Exp $ + + zip_stat.c -- get information about file by name + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st) +{ + int idx; + + if ((idx=zip_name_locate(za, fname, flags)) < 0) + return -1; + + return zip_stat_index(za, idx, flags, st); +} diff --git a/ext/phar/lib/zip_stat_index.c b/ext/phar/lib/zip_stat_index.c new file mode 100644 index 0000000000..bab79a74ba --- /dev/null +++ b/ext/phar/lib/zip_stat_index.c @@ -0,0 +1,93 @@ +/* + $NiH: zip_stat_index.c,v 1.10 2006/04/24 14:04:19 dillo Exp $ + + zip_stat_index.c -- get information about file by index + Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +int +zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st) +{ + const char *name; + + if (index < 0 || index >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((name=zip_get_name(za, index, flags)) == NULL) + return -1; + + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && ZIP_ENTRY_DATA_CHANGED(za->entry+index)) { + if (za->entry[index].source->f(za->entry[index].source->ud, + st, sizeof(*st), ZIP_SOURCE_STAT) < 0) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return -1; + } + } + else { + if (za->cdir == NULL || index >= za->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + st->crc = za->cdir->entry[index].crc; + st->size = za->cdir->entry[index].uncomp_size; + st->mtime = za->cdir->entry[index].last_mod; + st->comp_size = za->cdir->entry[index].comp_size; + st->comp_method = za->cdir->entry[index].comp_method; + if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) { + if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { + /* XXX */ + st->encryption_method = ZIP_EM_UNKNOWN; + } + else + st->encryption_method = ZIP_EM_TRAD_PKWARE; + } + else + st->encryption_method = ZIP_EM_NONE; + /* st->bitflags = za->cdir->entry[index].bitflags; */ + } + + st->index = index; + st->name = name; + + return 0; +} diff --git a/ext/phar/lib/zip_stat_init.c b/ext/phar/lib/zip_stat_init.c new file mode 100644 index 0000000000..7ab0f4da75 --- /dev/null +++ b/ext/phar/lib/zip_stat_init.c @@ -0,0 +1,53 @@ +/* + $NiH: zip_stat_init.c,v 1.1 2006/10/31 12:03:04 dillo Exp $ + + zip_stat_init.c -- initialize struct zip_stat. + Copyright (C) 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + + + +void +zip_stat_init(struct zip_stat *st) +{ + st->name = NULL; + st->index = -1; + st->crc = 0; + st->mtime = (time_t)-1; + st->size = -1; + st->comp_size = -1; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; +} diff --git a/ext/phar/lib/zip_strerror.c b/ext/phar/lib/zip_strerror.c new file mode 100644 index 0000000000..83e2985068 --- /dev/null +++ b/ext/phar/lib/zip_strerror.c @@ -0,0 +1,47 @@ +/* + $NiH: zip_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $ + + zip_sterror.c -- get string representation of zip error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +const char * +zip_strerror(struct zip *za) +{ + return _zip_error_strerror(&za->error); +} diff --git a/ext/phar/lib/zip_unchange.c b/ext/phar/lib/zip_unchange.c new file mode 100644 index 0000000000..34e7f2d367 --- /dev/null +++ b/ext/phar/lib/zip_unchange.c @@ -0,0 +1,84 @@ +/* + $NiH: zip_unchange.c,v 1.19 2006/04/23 13:21:18 wiz Exp $ + + zip_unchange.c -- undo changes to file in zip archive + Copyright (C) 1999, 2004, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include "zip.h" +#include "zipint.h" + + + +int +zip_unchange(struct zip *za, int idx) +{ + return _zip_unchange(za, idx, 0); +} + + + +int +_zip_unchange(struct zip *za, int idx, int allow_duplicates) +{ + int i; + + if (idx < 0 || idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (za->entry[idx].ch_filename) { + if (!allow_duplicates) { + i = _zip_name_locate(za, + _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), + 0, NULL); + if (i != -1 && i != idx) { + _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); + return -1; + } + } + + free(za->entry[idx].ch_filename); + za->entry[idx].ch_filename = NULL; + } + + free(za->entry[idx].ch_comment); + za->entry[idx].ch_comment = NULL; + za->entry[idx].ch_comment_len = -1; + + _zip_unchange_data(za->entry+idx); + + return 0; +} diff --git a/ext/phar/lib/zip_unchange_all.c b/ext/phar/lib/zip_unchange_all.c new file mode 100644 index 0000000000..f1e27da045 --- /dev/null +++ b/ext/phar/lib/zip_unchange_all.c @@ -0,0 +1,56 @@ +/* + $NiH: zip_unchange_all.c,v 1.10 2006/04/23 13:14:46 wiz Exp $ + + zip_unchange.c -- undo changes to all files in zip archive + Copyright (C) 1999, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include "zip.h" +#include "zipint.h" + + + +int +zip_unchange_all(struct zip *za) +{ + int ret, i; + + ret = 0; + for (i=0; inentry; i++) + ret |= _zip_unchange(za, i, 1); + + ret |= zip_unchange_archive(za); + + return ret; +} diff --git a/ext/phar/lib/zip_unchange_archive.c b/ext/phar/lib/zip_unchange_archive.c new file mode 100644 index 0000000000..7418aaf6ac --- /dev/null +++ b/ext/phar/lib/zip_unchange_archive.c @@ -0,0 +1,52 @@ +/* + $NiH: zip_unchange_archive.c,v 1.1 2006/04/23 13:14:46 wiz Exp $ + + zip_unchange_archive.c -- undo global changes to ZIP archive + Copyright (C) 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include "zip.h" +#include "zipint.h" + + + +int +zip_unchange_archive(struct zip *za) +{ + free(za->ch_comment); + za->ch_comment = NULL; + za->ch_comment_len = -1; + + return 0; +} diff --git a/ext/phar/lib/zip_unchange_data.c b/ext/phar/lib/zip_unchange_data.c new file mode 100644 index 0000000000..2526769261 --- /dev/null +++ b/ext/phar/lib/zip_unchange_data.c @@ -0,0 +1,53 @@ +/* + $NiH: zip_unchange_data.c,v 1.15 2004/12/22 16:32:00 dillo Exp $ + + zip_unchange_data.c -- undo helper function + Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zipint.h" + +void +_zip_unchange_data(struct zip_entry *ze) +{ + if (ze->source) { + (void)ze->source->f(ze->source->ud, NULL, 0, ZIP_SOURCE_FREE); + free(ze->source); + ze->source = NULL; + } + + ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED; +} + diff --git a/ext/phar/lib/zip_win32.h b/ext/phar/lib/zip_win32.h new file mode 100644 index 0000000000..a33347ba0c --- /dev/null +++ b/ext/phar/lib/zip_win32.h @@ -0,0 +1,29 @@ + +#ifdef _MSC_VER + +#define _POSIX_ +#include +#include +#include + +#ifndef ssize_t +# define ssize_t SSIZE_T +#endif +#ifndef mode_t +# define mode_t int +#endif +#ifndef strcasecmp +# define strcasecmp stricmp +#endif +#ifndef snprintf +# define snprintf _snprintf +#endif +#ifndef mkstemp +# define mkstemp(t) _creat(_mktemp(t), _S_IREAD|_S_IWRITE) +#endif +/* +#ifndef fseeko +# define fseeko fseek +#endif +*/ +#endif diff --git a/ext/phar/lib/zipint.h b/ext/phar/lib/zipint.h new file mode 100644 index 0000000000..ebf2743f99 --- /dev/null +++ b/ext/phar/lib/zipint.h @@ -0,0 +1,226 @@ +#ifndef _HAD_ZIPINT_H +#define _HAD_ZIPINT_H + +/* + $NiH: zipint.h,v 1.48 2006/04/24 14:04:19 dillo Exp $ + + zipint.h -- internal declarations. + Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "zip.h" +#ifndef HAVE_FSEEKO +#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) +#endif + +#define CENTRAL_MAGIC "PK\1\2" +#define LOCAL_MAGIC "PK\3\4" +#define EOCD_MAGIC "PK\5\6" +#define DATADES_MAGIC "PK\7\8" +#define CDENTRYSIZE 46u +#define LENTRYSIZE 30 +#define MAXCOMLEN 65536 +#define EOCDLEN 22 +#define CDBUFSIZE (MAXCOMLEN+EOCDLEN) +#define BUFSIZE 8192 + + + +/* state of change of a file in zip archive */ + +enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, + ZIP_ST_ADDED, ZIP_ST_RENAMED }; + +/* constants for struct zip_file's member flags */ + +#define ZIP_ZF_EOF 1 /* EOF reached */ +#define ZIP_ZF_DECOMP 2 /* decompress data */ +#define ZIP_ZF_CRC 4 /* compute and compare CRC */ + +/* directory entry: general purpose bit flags */ + +#define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ +#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ +#define ZIP_GPBF_USE_DATA_DESCRIPTOR 0x0008 /* uses crc and size from data header */ + +/* error information */ + +struct zip_error { + int zip_err; /* libzip error code (ZIP_ER_*) */ + int sys_err; /* copy of errno (E*) or zlib error code */ + char *str; /* string representation or NULL */ +}; + +/* zip archive, part of API */ + +struct zip { + char *zn; /* file name */ + FILE *zp; /* file */ + struct zip_error error; /* error information */ + + struct zip_cdir *cdir; /* central directory */ + char *ch_comment; /* changed archive comment */ + int ch_comment_len; /* length of changed zip archive + * comment, -1 if unchanged */ + int nentry; /* number of entries */ + int nentry_alloc; /* number of entries allocated */ + struct zip_entry *entry; /* entries */ + int nfile; /* number of opened files within archive */ + int nfile_alloc; /* number of files allocated */ + struct zip_file **file; /* opened files within archive */ +}; + +/* file in zip archive, part of API */ + +struct zip_file { + struct zip *za; /* zip archive containing this file */ + struct zip_error error; /* error information */ + int flags; /* -1: eof, >0: error */ + + int method; /* compression method */ + long fpos; /* position within zip file (fread/fwrite) */ + unsigned long bytes_left; /* number of bytes left to read */ + unsigned long cbytes_left; /* number of bytes of compressed data left */ + + unsigned long crc; /* CRC so far */ + unsigned long crc_orig; /* CRC recorded in archive */ + + char *buffer; + z_stream *zstr; +}; + +/* zip archive directory entry (central or local) */ + +struct zip_dirent { + unsigned short version_madeby; /* (c) version of creator */ + unsigned short version_needed; /* (cl) version needed to extract */ + unsigned short bitflags; /* (cl) general purpose bit flag */ + unsigned short comp_method; /* (cl) compression method used */ + time_t last_mod; /* (cl) time of last modification */ + unsigned int crc; /* (cl) CRC-32 of uncompressed data */ + unsigned int comp_size; /* (cl) size of commpressed data */ + unsigned int uncomp_size; /* (cl) size of uncommpressed data */ + char *filename; /* (cl) file name (NUL-terminated) */ + unsigned short filename_len; /* (cl) length of filename (w/o NUL) */ + char *extrafield; /* (cl) extra field */ + unsigned short extrafield_len; /* (cl) length of extra field */ + char *comment; /* (c) file comment */ + unsigned short comment_len; /* (c) length of file comment */ + unsigned short disk_number; /* (c) disk number start */ + unsigned short int_attrib; /* (c) internal file attributes */ + unsigned int ext_attrib; /* (c) external file attributes */ + unsigned int offset; /* (c) offset of local header */ +}; + +/* zip archive central directory */ + +struct zip_cdir { + struct zip_dirent *entry; /* directory entries */ + int nentry; /* number of entries */ + + unsigned int size; /* size of central direcotry */ + unsigned int offset; /* offset of central directory in file */ + char *comment; /* zip archive comment */ + unsigned short comment_len; /* length of zip archive comment */ +}; + + + +struct zip_source { + zip_source_callback f; + void *ud; +}; + +/* entry in zip archive directory */ + +struct zip_entry { + enum zip_state state; + struct zip_source *source; + char *ch_filename; + char *ch_comment; + int ch_comment_len; +}; + + + +extern const char * const _zip_err_str[]; +extern const int _zip_nerr_str; +extern const int _zip_err_type[]; + + + +#define ZIP_ENTRY_DATA_CHANGED(x) \ + ((x)->state == ZIP_ST_REPLACED \ + || (x)->state == ZIP_ST_ADDED) + + + +void _zip_cdir_free(struct zip_cdir *); +struct zip_cdir *_zip_cdir_new(int, struct zip_error *); +int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); + +void _zip_dirent_finalize(struct zip_dirent *); +void _zip_dirent_init(struct zip_dirent *); +int _zip_dirent_read(struct zip_dirent *, FILE *, + unsigned char **, unsigned int, int, struct zip_error *); +int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); + +void _zip_entry_free(struct zip_entry *); +void _zip_entry_init(struct zip *, int); +struct zip_entry *_zip_entry_new(struct zip *); + +void _zip_error_clear(struct zip_error *); +void _zip_error_copy(struct zip_error *, struct zip_error *); +void _zip_error_fini(struct zip_error *); +void _zip_error_get(struct zip_error *, int *, int *); +void _zip_error_init(struct zip_error *); +void _zip_error_set(struct zip_error *, int, int); +const char *_zip_error_strerror(struct zip_error *); + +int _zip_file_fillbuf(void *, size_t, struct zip_file *); +unsigned int _zip_file_get_offset(struct zip *, int); + +void _zip_free(struct zip *); +const char *_zip_get_name(struct zip *, int, int, struct zip_error *); +int _zip_local_header_read(struct zip *, int); +void *_zip_memdup(const void *, size_t, struct zip_error *); +int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); +struct zip *_zip_new(struct zip_error *); +unsigned short _zip_read2(unsigned char **); +unsigned int _zip_read4(unsigned char **); +int _zip_replace(struct zip *, int, const char *, struct zip_source *); +int _zip_set_name(struct zip *, int, const char *); +int _zip_unchange(struct zip *, int, int); +void _zip_unchange_data(struct zip_entry *); + +#endif /* zipint.h */ diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 18c1be04f9..43e66b54c6 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -25,6 +25,27 @@ ZEND_DECLARE_MODULE_GLOBALS(phar) +#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 60000) + +static int _php_stream_unlink(char *url, int options, php_stream_context *context TSRMLS_DC) +{ + php_stream_wrapper *wrapper = php_stream_locate_url_wrapper(url, NULL, options TSRMLS_CC); + + if (!wrapper || !wrapper->wops) { + return 0; + } + + if (!wrapper->wops->unlink) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper"); + return 0; + } + return wrapper->wops->unlink(wrapper, url, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC); +} + +#define php_stream_unlink(url, options, context) _php_stream_unlink((url), (options), (context) TSRMLS_CC) + +#endif + /* if the original value is 0 (disabled), then allow setting/unsetting at will otherwise, only allow 1 (enabled), and error on disabling */ ZEND_INI_MH(phar_ini_modify_handler) /* {{{ */ @@ -206,7 +227,12 @@ static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */ php_stream_close(data->fp); data->fp = 0; } - +#if HAVE_PHAR_ZIP + if (data->zip) { + zip_close(data->zip); + data->zip = 0; + } +#endif efree(data); } /* }}}*/ @@ -296,6 +322,12 @@ static void destroy_phar_manifest(void *pDest) /* {{{ */ entry->metadata_str.c = 0; } efree(entry->filename); +#if HAVE_PHAR_ZIP + if (entry->zip) { + zip_fclose(entry->zip); + entry->zip = 0; + } +#endif } /* }}} */ @@ -392,13 +424,13 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in if (!path_len && !dir) { if (error) { - spprintf(error, 0, "phar error: invalid path \"%s\" must not be empty", path); + spprintf(error, 4096, "phar error: invalid path \"%s\" must not be empty", path); } return NULL; } if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) { if (error) { - spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error); + spprintf(error, 4096, "phar error: invalid path \"%s\" contains %s", path, pcr_error); } return NULL; } @@ -407,6 +439,21 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in return NULL; } if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) { +#if HAVE_PHAR_ZIP + if (phar->is_zip) { + /* construct phar_entry_info JIT */ + if (path[path_len - 1] == '/') { + if (!dir) { + if (error) { + spprintf(error, 4096, "phar error: path \"%s\" is a directory", path); + } + return NULL; + } + + entry->is_dir = 1; + } + } +#endif if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return NULL; @@ -445,6 +492,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in /* found a file in this path */ entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info)); entry->is_dir = 1; + /* this next line tells PharFileInfo->__destruct() to efree the filename */ + entry->is_zip = 0; entry->filename = (char *) estrndup(path, path_len + 1); entry->filename_len = path_len; return entry; @@ -461,11 +510,12 @@ typedef struct { size_t fpos; size_t fsize; size_t smax; - int mode; + int mode; php_stream **owner_ptr; } php_stream_memory_data; #endif +/* this is only called for non-zip-based phars */ static int phar_open_entry_file(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC) /* {{{ */ { if (error) { @@ -538,13 +588,13 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char } if (entry->is_modified && !for_write) { if (error) { - spprintf(error, 0, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname); + spprintf(error, 4096, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname); } return FAILURE; } if (entry->fp_refcount && for_write) { if (error) { - spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname); + spprintf(error, 4096, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname); } return FAILURE; } @@ -552,6 +602,19 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char if (!for_create) { return FAILURE; } +#if HAVE_PHAR_ZIP + if (entry->is_zip) { + /* for new files, start with an empty string */ + struct zip_source *s = zip_source_buffer(entry->phar->zip, (void *)"", 0, 0); + if (-1 == zip_replace(entry->phar->zip, entry->index, s)) { + if (error) { + spprintf(error, 4096, "phar error: zip-based phar \"%s\" entry \"%s\" error \"%s\"", entry->phar->fname, fname, zip_strerror(phar->zip)); + } + zip_error_clear(phar->zip); + return FAILURE; + } + } +#endif entry->is_deleted = 0; } *ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data)); @@ -560,6 +623,7 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char (*ret)->phar = phar; (*ret)->for_write = for_write; (*ret)->internal_file = entry; + (*ret)->is_zip = entry->is_zip; if (entry->fp) { /* make a copy */ if (for_trunc) { @@ -659,6 +723,15 @@ void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC) /* {{{ */ if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->internal_file->fp) { php_stream_close(idata->fp); } +#if HAVE_PHAR_ZIP + if (idata->internal_file->is_zip) { + if (idata->internal_file->zip) { + zip_fclose(idata->internal_file->zip); + idata->internal_file->zip = 0; + } + zip_delete(phar->zip, idata->internal_file->index); + } +#endif zend_hash_del(&idata->phar->manifest, idata->internal_file->filename, idata->internal_file->filename_len); idata->phar->refcount--; efree(idata); @@ -714,13 +787,43 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char } etemp.fp_refcount = 1; etemp.is_modified = 1; - etemp.filename = estrndup(path, path_len); etemp.timestamp = time(0); etemp.offset_within_phar = -1; etemp.is_crc_checked = 1; etemp.flags = PHAR_ENT_PERM_DEF_FILE; etemp.old_flags = PHAR_ENT_PERM_DEF_FILE; etemp.phar = phar; +#if HAVE_PHAR_ZIP + if (phar->is_zip) { + int zindex; + etemp.is_zip = 1; + /* prevent attempts to check the CRC */ + etemp.is_crc_checked = 1; + /* for new files, start with an empty string */ + struct zip_source *s = zip_source_buffer(phar->zip, (void *)"", 0, 0); + if (-1 == (zindex = zip_add(phar->zip, path, s))) { + if (error) { + spprintf(error, 4096, "phar error: zip-based phar \"%s\" entry \"%s\" error \"%s\"", path, phar->fname, zip_strerror(phar->zip)); + } + zip_error_clear(phar->zip); + return NULL; + } + etemp.index = zindex; + etemp.filename = (char *) zip_get_name(phar->zip, zindex, 0); + if (NULL == etemp.filename) { + if (error) { + spprintf(error, 4096, "phar error: zip-based phar \"%s\" entry \"%s\" error \"%s\"", path, phar->fname, zip_strerror(phar->zip)); + } + zip_error_clear(phar->zip); + return NULL; + } + etemp.filename = estrndup(etemp.filename, strlen(etemp.filename)); + } else { + etemp.filename = estrndup(path, path_len); + } +#else + etemp.filename = estrndup(path, path_len); +#endif zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), NULL); /* retrieve the phar manifest copy */ entry = phar_get_entry_info(phar, path, path_len, error TSRMLS_CC); @@ -779,7 +882,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char /** * Open an already loaded phar */ -static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ +int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ { phar_archive_data *phar; #ifdef PHP_WIN32 @@ -837,13 +940,17 @@ static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_l * * data is the serialized zval */ -static int phar_parse_metadata(php_stream *fp, char **buffer, char *endbuffer, zval **metadata TSRMLS_DC) /* {{{ */ +static int phar_parse_metadata(char **buffer, zval **metadata, int is_zip TSRMLS_DC) /* {{{ */ { const unsigned char *p; php_uint32 buf_len; php_unserialize_data_t var_hash; - PHAR_GET_32(*buffer, buf_len); + if (!is_zip) { + PHAR_GET_32(*buffer, buf_len); + } else { + buf_len = is_zip; + } if (buf_len) { ALLOC_INIT_ZVAL(*metadata); @@ -881,6 +988,199 @@ static int phar_hex_str(const char *digest, size_t digest_len, char ** signature return pos; } +/** + * Does not check for a previously opened phar in the cache. + * + * Parse a new one and add it to the cache, returning either SUCCESS or + * FAILURE, and setting pphar to the pointer to the manifest entry + * + * This is used by phar_open_fp to process a zip-based phar, but can be called + * directly. + */ +int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ +{ +#if HAVE_PHAR_ZIP + struct zip *zip; + int ziperror, i, phar_alias_index, register_alias, metadata_len; + phar_entry_info entry = {0}; + struct zip_stat zs; + char tmp_buf[1024], *metadata; + + if (error) { + *error = NULL; + } + + zip = zip_open(fname, 0, &ziperror); + if (!zip) { + if (error) { + /* now for the stupid hoops libzip forces... */ + char *tmp; + int tmp_len; + tmp_len = zip_error_to_str(NULL, 0, ziperror, ziperror); + if (!(tmp = emalloc((tmp_len + 1) * sizeof(char)))) { + spprintf(error, 4096, "phar zip error: cannot open zip-based phar \"%s\"", fname); + } else { + if (!zip_error_to_str(tmp, tmp_len + 1, ziperror, ziperror)) { + spprintf(error, 4096, "phar zip error: cannot open zip-based phar \"%s\"", fname); + } else { + spprintf(error, 4096, "phar zip error: cannot open zip-based phar \"%s\": %s", fname, tmp); + efree(tmp); + } + } + } + return FAILURE; + } + phar_archive_data *mydata = NULL; + mydata = ecalloc(sizeof(phar_archive_data), 1); + mydata->fname = estrndup(fname, fname_len); +#ifdef PHP_WIN32 + phar_unixify_path_separators(mydata->fname, fname_len); +#endif + mydata->fname_len = fname_len; + if (-1 != (phar_alias_index = zip_name_locate(zip, "./phar/alias.txt", 0))) { + struct zip_file *zf = zip_fopen_index(zip, phar_alias_index, 0); + int tmp_len; + + tmp_len = zip_fread(zf, tmp_buf, 1024); + zip_fclose(zf); + /* if the alias is stored we enforce it (implicit overrides explicit) */ + if (tmp_len != -1 && alias && alias_len && (alias_len != tmp_len || strncmp(alias, tmp_buf, tmp_len))) + { + if (error) { + spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%s\" under different alias \"%s\"", fname, tmp_buf, alias); + } + return FAILURE; + } + if (tmp_len != -1) { + /* use implicit alias */ + alias = tmp_buf; + alias_len = tmp_len; + register_alias = 0; + } + } else { + register_alias = alias ? 1 : 0; + } + mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname; + mydata->alias_len = alias ? alias_len : fname_len; + mydata->is_zip = 1; + mydata->zip = zip; + + phar_request_initialize(TSRMLS_C); + + /* read in phar metadata (zip file comment) */ + metadata = (char *) zip_get_archive_comment(zip, &metadata_len, 0); + if (metadata) { + if (phar_parse_metadata(&metadata, &mydata->metadata, metadata_len TSRMLS_CC) == FAILURE) { + /* if not valid serialized data, it is a regular string */ + ALLOC_INIT_ZVAL(mydata->metadata); + Z_STRVAL_P(mydata->metadata) = estrndup(metadata, metadata_len); + Z_STRLEN_P(mydata->metadata) = metadata_len; + Z_TYPE_P(mydata->metadata) = IS_STRING; + } + } else { + mydata->metadata = NULL; + } + /* set up our manifest */ + zend_hash_init(&mydata->manifest, sizeof(phar_entry_info), + zend_get_hash_value, destroy_phar_manifest, 0); + entry.phar = mydata; + entry.is_zip = 1; + /* prevent CRC checking */ + entry.is_crc_checked = 1; + for (i = 0; i < zip_get_num_files(zip); i++) { + char *name; + name = (char *) zip_get_name(zip, i, 0); + if (name) { + /* get file stat */ + if (-1 != zip_stat_index(zip, i, 0, &zs)) { + entry.compressed_filesize = zs.comp_size; + entry.uncompressed_filesize = zs.size; + entry.crc32 = zs.crc; + entry.timestamp = (php_uint32) zs.mtime; + entry.flags = 0; + switch (zs.comp_method) { + case ZIP_CM_DEFLATE : + /* if we have zip, we have zlib decompression */ + entry.flags |= PHAR_ENT_COMPRESSED_GZ; + break; + case ZIP_CM_BZIP2 : +#if !HAVE_BZ2 + if (mydata->metadata) { + zval_dtor(mydata->metadata); + } + efree(mydata->fname); + if (mydata->alias) { + efree(mydata->alias); + } + zip_close(zip); + zend_hash_destroy(&(mydata->manifest)); + efree(mydata); + if (error) { + spprintf(error, 0, "bz2 extension is required for Bzip2 compressed zip-based .phar file \"%s\"", fname); + } + return FAILURE; +#else + if (!phar_has_bz2) { + if (mydata->metadata) { + zval_dtor(mydata->metadata); + } + efree(mydata->fname); + if (mydata->alias) { + efree(mydata->alias); + } + zip_close(zip); + zend_hash_destroy(&(mydata->manifest)); + efree(mydata); + if (error) { + spprintf(error, 0, "bz2 extension is required for gz compressed zip-based .phar file \"%s\"", fname); + } + return FAILURE; + } +#endif + entry.flags |= PHAR_ENT_COMPRESSED_BZ2; + break; + } + } + entry.index = i; + entry.filename_len = strlen(name); + entry.filename = estrndup(name, entry.filename_len); + /* get file metadata */ + metadata = (char *) zip_get_file_comment(zip, i, &metadata_len, 0); + if (metadata) { + if (phar_parse_metadata(&metadata, &(entry.metadata), metadata_len TSRMLS_CC) == FAILURE) { + /* if not valid serialized data, it is a regular string */ + ALLOC_INIT_ZVAL(entry.metadata); + Z_STRVAL_P(entry.metadata) = estrndup(metadata, metadata_len); + Z_STRLEN_P(entry.metadata) = metadata_len; + Z_TYPE_P(entry.metadata) = IS_STRING; + } + } else { + entry.metadata = NULL; + } + zend_hash_add(&mydata->manifest, name, strlen(name), (void *)&entry,sizeof(phar_entry_info), NULL); + } + } + /* ignore all errors in loading up manifest */ + zip_error_clear(zip); + + zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL); + if (register_alias) { + mydata->is_explicit_alias = 1; + zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL); + } else { + mydata->is_explicit_alias = 0; + } + if (pphar) { + *pphar = mydata; + } + return SUCCESS; +#else + spprintf(error, 4096, "Error: Cannot open zip-based phar \"%s\"", fname); + return FAILURE; +#endif +} +/* }}} */ + /** * Does not check for a previously opened phar in the cache. * @@ -1217,10 +1517,10 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int mydata = ecalloc(sizeof(phar_archive_data), 1); /* check whether we have meta data, zero check works regardless of byte order */ - if (phar_parse_metadata(fp, &buffer, endbuffer, &mydata->metadata TSRMLS_CC) == FAILURE) { + if (phar_parse_metadata(&buffer, &mydata->metadata, 0 TSRMLS_CC) == FAILURE) { MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\""); } - + /* set up our manifest */ zend_hash_init(&mydata->manifest, sizeof(phar_entry_info), zend_get_hash_value, destroy_phar_manifest, 0); @@ -1254,7 +1554,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int PHAR_GET_32(buffer, entry.compressed_filesize); PHAR_GET_32(buffer, entry.crc32); PHAR_GET_32(buffer, entry.flags); - if (phar_parse_metadata(fp, &buffer, endbuffer, &entry.metadata TSRMLS_CC) == FAILURE) { + if (phar_parse_metadata(&buffer, &entry.metadata, 0 TSRMLS_CC) == FAILURE) { efree(entry.filename); MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\""); } @@ -1346,19 +1646,89 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int } /* }}} */ +/* forward declaration */ +static int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC); + /** * Create or open a phar for writing */ -int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ +int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ { - phar_archive_data *mydata; - char *my_realpath; +#if HAVE_PHAR_ZIP + phar_archive_data *phar; + int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC); int register_alias; - php_stream *fp; - if (!pphar) { - pphar = &mydata; + if (FAILURE == ret) { + return FAILURE; + } + if ((*pphar)->is_zip) { + return ret; + } + + phar = *pphar; + if (phar->is_brandnew) { + int *errorp; + phar->is_zip = 1; + if (phar->fp) { + php_stream_close(phar->fp); + phar->fp = NULL; + php_stream_unlink(phar->fname, 0, NULL); + } + phar->zip = zip_open(fname, 0 | ZIP_CREATE | ZIP_EXCL, errorp); + if (NULL != phar->zip) { + return SUCCESS; + } + /* fail - free newly created manifest entry */ + if (register_alias) { + zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len); + } + zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len); + efree(phar->fname); + efree(phar->alias); + efree(phar); + *pphar = NULL; + + if (error) { + /* now for the stupid hoops libzip forces... */ + char *tmp; + int tmp_len; + tmp_len = zip_error_to_str(NULL, 0, *errorp, *errorp); + if (!(tmp = emalloc((tmp_len + 1) * sizeof(char)))) { + spprintf(error, 4096, "phar zip error: cannot create zip-based phar \"%s\"", fname); + } else { + if (!zip_error_to_str(tmp, tmp_len + 1, *errorp, *errorp)) { + spprintf(error, 4096, "phar zip error: cannot create zip-based phar \"%s\"", fname); + } else { + spprintf(error, 4096, "phar zip error: cannot create zip-based phar \"%s\": %s", fname, tmp); + efree(tmp); + } + } + } + return FAILURE; + } + + /* we've reached here - the phar exists and is a regular phar */ + if (error) { + spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", fname); } + return FAILURE; +#else + if (error) { + spprintf(error, 4096, "phar zip error: phar \"%s\" cannot be created as zip-based phar, zip-based phars are disabled", fname); + } + return FAILURE; +#endif /* #if HAVE_PHAR_ZIP */ +} + +/** + * Create or open a phar for writing + */ +int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ +{ + char *ext_str; + int ext_len; + if (error) { *error = NULL; } @@ -1370,6 +1740,25 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al return SUCCESS; } + if (phar_detect_phar_fname_ext(fname, 1, &ext_str, &ext_len) == SUCCESS) { + if (ext_len >= sizeof(".phar.zip")-1 && !memcmp((void *) ext_str, (void *) ".phar.zip", sizeof(".phar.zip")-1)) { + /* assume zip-based phar */ + return phar_open_or_create_zip(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC); + } + } + return phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC); +} + +static int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ +{ + phar_archive_data *mydata; + char *my_realpath; + int register_alias; + php_stream *fp; + + if (!pphar) { + pphar = &mydata; + } #if PHP_MAJOR_VERSION < 6 if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) { return FAILURE; @@ -1500,7 +1889,8 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */ { const char token[] = "__HALT_COMPILER();"; - char *pos, buffer[1024 + sizeof(token)]; + const char zip_magic[] = "PK\x03\x04"; + char *pos, buffer[1024 + sizeof(token)], test = '\0'; const long readsize = sizeof(buffer) - sizeof(token); const long tokenlen = sizeof(token) - 1; long halt_offset; @@ -1523,6 +1913,14 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) < (size_t) tokenlen) { MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)") } + if (!test) { + test = '\1'; + pos = buffer+tokenlen; + if (!memcmp(pos, zip_magic, 4)) { + php_stream_close(fp); + return phar_open_zipfile(fname, fname_len, alias, alias_len, pphar, error TSRMLS_CC); + } + } if ((pos = strstr(buffer, token)) != NULL) { halt_offset += (pos - buffer); /* no -tokenlen+tokenlen here */ return phar_open_file(fp, fname, fname_len, alias, alias_len, halt_offset, pphar, error TSRMLS_CC); @@ -1540,6 +1938,8 @@ int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ex { char end; char *pos_p = strstr(filename, ".phar.php"); + char *pos_zi = strstr(filename, ".phar.zip"); + char *pos_zi2 = strstr(filename, ".phar.zip.php"); char *pos_z = strstr(filename, ".phar.gz"); char *pos_b = strstr(filename, ".phar.bz2"); @@ -1555,6 +1955,12 @@ int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ex } else if (pos_b) { *ext_str = pos_b; *ext_len = 9; + } else if (pos_zi2) { + *ext_str = pos_zi2; + *ext_len = 13; + } else if (pos_zi) { + *ext_str = pos_zi; + *ext_len = 9; } else if ((pos_p = strstr(filename, ".phar")) != NULL) { *ext_str = pos_p; *ext_len = 5; @@ -1863,9 +2269,38 @@ int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC) *error = NULL; } fname = zend_get_executed_filename(TSRMLS_C); - fname_len = strlen(fname); + if (strstr(fname, "phar://") && strstr(fname, ".phar/stub.php")) { + char *arch, *entry; + int arch_len, entry_len; + phar_archive_data *phar; + + if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + efree(entry); + efree(arch); + goto regular_error; + } + if (strcmp(entry, "/.phar/stub.php")) { + efree(entry); + efree(arch); + goto regular_error; + } + + /* we're running from inside a zip-based phar */ + efree(entry); + entry = fname; + fname = arch; + fname_len = arch_len; + if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && phar->is_zip) { + efree(arch); + return SUCCESS; + } + /* restore original value for error purpose */ + fname = entry; + } +regular_error: + if (phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) { return SUCCESS; } @@ -2009,18 +2444,133 @@ static char * phar_decompress_filter(phar_entry_info * entry, int return_unknown /** * helper function to open an internal file's fp just-in-time */ -static phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp, +phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp, char **error, int for_write TSRMLS_DC) { php_uint32 offset, flags; php_stream_filter *filter/*, *consumed */; - char tmpbuf[8]; char *filter_name; char *buffer; if (error) { *error = NULL; } +#if HAVE_PHAR_ZIP + if (entry->is_zip) { + char readbuf[8192]; + int got; + if (entry->fp) { + return entry; + } + if (!entry->zip) { + if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) { +# if HAVE_BZ2 + char *filter_name; + php_stream_filter *filter; + php_stream *fp; + /* we have to decompress this by hand */ + + if (!phar_has_bz2) { + if (error) { + spprintf(error, 4096, "phar error, cannot decompress bzip2-compressed entry"); + } + return NULL; + } + + /* first, read into a temp stream */ + fp = php_stream_temp_new(); + entry->zip = zip_fopen_index(phar->zip, entry->index, ZIP_FL_COMPRESSED); + if (!entry->zip) { + if (error) { + spprintf(error, 4096, "phar error: %s", zip_strerror(phar->zip)); + } + zip_error_clear(phar->zip); + return NULL; + } + do { + size_t check; + got = zip_fread(entry->zip, (void *)readbuf, 8192); + if (-1 == got) break; + check = got; + if (check != php_stream_write(fp, readbuf, got)) { + if (error) { + spprintf(error, 4096, "phar error: could not copy full zip file contents of entry \"%s\"", entry->filename); + } + fclose(fp); + entry->fp = NULL; + zip_fclose(entry->zip); + entry->zip = NULL; + return NULL; + } + } while (got == 8192); + zip_fclose(entry->zip); + php_stream_seek(fp, 0, SEEK_SET); + + /* now use a decompression filter to inflate into our temp file */ + if ((filter_name = phar_decompress_filter(entry, 0)) != NULL) { + filter = php_stream_filter_create(phar_decompress_filter(phar, 0), NULL, php_stream_is_persistent(fp) TSRMLS_CC); + } else { + filter = NULL; + } + if (!filter) { + spprintf(error, 0, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->phar->fname, phar_decompress_filter(entry, 1), entry->filename); + return NULL; + } + + /* now we can safely use proper decompression */ + entry->fp = php_stream_temp_new(); + php_stream_filter_append(&entry->fp->writefilters, filter); + if (php_stream_copy_to_stream(fp, entry->fp, entry->compressed_filesize) != entry->compressed_filesize || php_stream_tell(entry->fp) != (off_t) entry->uncompressed_filesize) { + spprintf(error, 0, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename); + php_stream_filter_remove(filter, 1 TSRMLS_CC); + return NULL; + } + php_stream_filter_flush(filter, 1); + php_stream_filter_remove(filter, 1 TSRMLS_CC); + php_stream_close(fp); + return entry; +# else /* #if HAVE_BZ2 */ + if (error) { + spprintf(error, 4096, "phar error, cannot decompress bzip2-compressed entry"); + } + return NULL; +# endif /* #if HAVE_BZ2 */ + } else { + /* uncompressed or zlib-compressed */ + entry->zip = zip_fopen_index(phar->zip, entry->index, 0); + if (!entry->zip) { + if (error) { + spprintf(error, 4096, "phar error: %s", zip_strerror(phar->zip)); + } + zip_error_clear(phar->zip); + return NULL; + } + } + } + + /* load contents of zip file to temp stream */ + entry->fp = php_stream_temp_new(); + do { + size_t check; + got = zip_fread(entry->zip, (void *)readbuf, 8192); + if (-1 == got) break; + check = got; + if (check != php_stream_write(entry->fp, readbuf, got)) { + if (error) { + spprintf(error, 4096, "phar error: could not copy full zip file contents of entry \"%s\"", entry->filename); + } + php_stream_close(entry->fp); + entry->fp = NULL; + zip_fclose(entry->zip); + entry->zip = NULL; + return NULL; + } + } while (got == 8192); + zip_fclose(entry->zip); + entry->zip = NULL; + return entry; + } +#endif /* #if HAVE_PHAR_ZIP */ /* seek to start of internal file and read it */ offset = phar->internal_file_start + entry->offset_within_phar; if (-1 == php_stream_seek(fp, offset, SEEK_SET)) { @@ -2067,7 +2617,6 @@ static phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info entry->fp = phar->fp; return entry; } - buffer = &tmpbuf[0]; /* bypass to temp stream */ entry->fp = php_stream_temp_new(); if (php_stream_copy_to_stream(fp, entry->fp, entry->uncompressed_filesize) != entry->uncompressed_filesize) { @@ -2214,7 +2763,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat fp = idata->phar->fp; - if (!fp) { + if (!idata->phar->is_zip && !fp) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot open phar \"%s\"", idata->phar->fname); phar_entry_delref(idata TSRMLS_CC); efree(internal_file); @@ -2490,6 +3039,247 @@ static int phar_flush_clean_deleted_apply(void *data TSRMLS_DC) /* {{{ */ } /* }}} */ +#if HAVE_PHAR_ZIP +static ssize_t phar_zip_source(void *state, void *data, size_t len, enum zip_source_cmd cmd) +{ + char *buf = (char *) data; + phar_entry_info *entry = (phar_entry_info *) state; + size_t read; + struct zip_stat *sb = (struct zip_stat *) data; + TSRMLS_FETCH(); + + switch (cmd) { + case ZIP_SOURCE_OPEN : + php_stream_seek(entry->fp, 0, SEEK_SET); + return 0; + case ZIP_SOURCE_READ : + read = php_stream_read(entry->fp, buf, len); + if (read < 0) return 0; + return read; + case ZIP_SOURCE_STAT : + zip_stat_init(sb); + sb->mtime = time(NULL); + sb->size = entry->uncompressed_filesize; + return sizeof(struct zip_stat); + default: + return len; + } +} + +/* reconstruct the zip index of each manifest entry */ +static int phar_zip_reconstruct_apply(void *data TSRMLS_DC) /* {{{ */ +{ + phar_entry_info *entry = (phar_entry_info *)data; + if (entry->is_deleted) { + entry->index = -1; + if (entry->fp_refcount <= 0) { + return ZEND_HASH_APPLY_REMOVE; + } else { + /* we can't delete this in-memory until it is closed */ + return ZEND_HASH_APPLY_KEEP; + } + } + entry->index = zip_name_locate(entry->phar->zip, entry->filename, 0); + return ZEND_HASH_APPLY_KEEP; +} + +/* perform final modification of zip contents for each file in the manifest before saving */ +static int phar_zip_changed_apply(void *data TSRMLS_DC) /* {{{ */ +{ + phar_entry_info *entry = (phar_entry_info *)data; + + if (entry->is_deleted) { + if (entry->fp_refcount <= 0) { + return ZEND_HASH_APPLY_REMOVE; + } else { + /* we can't delete this in-memory until it is closed */ + return ZEND_HASH_APPLY_KEEP; + } + } + if (entry->is_modified) { + ssize_t (*cb)(void *state, void *data, size_t len, enum zip_source_cmd cmd) = phar_zip_source; + if (entry->fp) { + struct zip_source *s = zip_source_function(entry->phar->zip, cb, entry); + if (-1 == zip_replace(entry->phar->zip, entry->index, s)) { + zip_error_clear(entry->phar->zip); + return ZEND_HASH_APPLY_REMOVE; + } + } + + /* set file metadata */ + if (entry->metadata) { + php_serialize_data_t metadata_hash; + if (entry->metadata_str.c) { + smart_str_free(&entry->metadata_str); + } + entry->metadata_str.c = 0; + entry->metadata_str.len = 0; + PHP_VAR_SERIALIZE_INIT(metadata_hash); + php_var_serialize(&entry->metadata_str, &entry->metadata, &metadata_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(metadata_hash); + if (-1 == zip_set_file_comment(entry->phar->zip, entry->index, entry->metadata_str.c, entry->metadata_str.len)) { + return ZEND_HASH_APPLY_STOP; + } + } else { + zip_set_file_comment(entry->phar->zip, entry->index, NULL, 0); + } + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */ +{ + char *pos; + smart_str main_metadata_str = {0}; + int ziperrint; + static const char newstub[] = "manifest, phar_zip_changed_apply TSRMLS_CC); + if (archive->zip->error.str) { + if (error) { + spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", archive->fname, zip_strerror(archive->zip)); + } + return EOF; + } + + /* set phar metadata */ + main_metadata_str.c = 0; + if (archive->metadata) { + PHP_VAR_SERIALIZE_INIT(metadata_hash); + php_var_serialize(&main_metadata_str, &archive->metadata, &metadata_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(metadata_hash); + zip_set_archive_comment(archive->zip, main_metadata_str.c, main_metadata_str.len); + smart_str_free(&main_metadata_str); + } else { + zip_set_archive_comment(archive->zip, NULL, 0); + } + + /* set alias */ + if (archive->is_explicit_alias) { + struct zip_source *source; + phar_alias_index = zip_name_locate(archive->zip, ".phar/alias.txt", 0); + if (NULL == (source = zip_source_buffer(archive->zip, archive->alias, archive->alias_len, 0)) || + (-1 == phar_alias_index && -1 == zip_add(archive->zip, ".phar/alias.txt", source)) || + (-1 != phar_alias_index && -1 == zip_replace(archive->zip, phar_alias_index, source))) { + if (error) { + spprintf(error, 0, "unable to set alias in new zip-based phar \"%s\": %s", archive->fname, zip_strerror(archive->zip)); + } + zip_error_clear(archive->zip); + return EOF; + } + } + /* set stub */ + phar_stub_index = zip_name_locate(archive->zip, ".phar/stub.php", 0); + zip_error_clear(archive->zip); + if (user_stub) { + struct zip_source *source; + if (len < 0) { + /* resource passed in */ + if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) { + if (error) { + spprintf(error, 0, "unable to access resource to copy stub to new phar \"%s\"", archive->fname); + } + return EOF; + } + if (len == -1) { + len = PHP_STREAM_COPY_ALL; + } else { + len = -len; + } + user_stub = 0; + if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) { + if (error) { + spprintf(error, 0, "unable to read resource to copy stub to new phar \"%s\"", archive->fname); + } + return EOF; + } + free_user_stub = 1; + } else { + free_user_stub = 0; + } + if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL) + { + if (error) { + spprintf(error, 0, "illegal stub for phar \"%s\"", archive->fname); + } + if (free_user_stub) { + efree(user_stub); + } + return EOF; + } + len = pos - user_stub + 18; + if (NULL == (source = zip_source_buffer(archive->zip, user_stub, len, 0)) || + (-1 == phar_stub_index && -1 == zip_add(archive->zip, ".phar/stub.php", source)) || + (-1 != phar_stub_index && -1 == zip_replace(archive->zip, phar_stub_index, source))) { + if (error) { + spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\": %s", archive->fname, zip_strerror(archive->zip)); + } + if (free_user_stub) { + efree(user_stub); + } + zip_error_clear(archive->zip); + return EOF; + } + if (free_user_stub) { + efree(user_stub); + } + } else { + if (archive->is_brandnew) { + struct zip_source *source; + /* this is a brand new phar, add the stub */ + if (NULL == (source = zip_source_buffer(archive->zip, newstub, sizeof(newstub) - 1, 0)) || -1 == zip_add(archive->zip, ".phar/stub.php", source)) { + if (error) { + spprintf(error, 0, "unable to create stub in new zip-based phar \"%s\": %s", archive->fname, zip_strerror(archive->zip)); + } + zip_error_clear(archive->zip); + return EOF; + } + } + } + + /* save zip */ + if (-1 == zip_close(archive->zip)) { + if (error) { + spprintf(error, 4096, "saving of zip-based phar \"%s\" failed: %s", archive->fname, zip_strerror(archive->zip)); + } + return EOF; + } + + /* re-open */ + archive->zip = zip_open(archive->fname, 0, &ziperrint); + if (!archive->zip) { + if (error) { + /* now for the stupid hoops libzip forces... */ + char *tmp; + int tmp_len; + tmp_len = zip_error_to_str(NULL, 0, ziperrint, ziperrint); + if (!(tmp = emalloc((tmp_len + 1) * sizeof(char)))) { + spprintf(error, 4096, "phar zip error: cannot re-open zip-based phar \"%s\"", archive->fname); + } else { + if (!zip_error_to_str(tmp, tmp_len + 1, ziperrint, ziperrint)) { + spprintf(error, 4096, "phar zip error: cannot re-open zip-based phar \"%s\"", archive->fname); + } else { + spprintf(error, 4096, "phar zip error: cannot re-open zip-based phar \"%s\": %s", archive->fname, tmp); + efree(tmp); + } + } + } + return EOF; + } + + /* reconstruct manifest zip index map */ + zend_hash_apply(&archive->manifest, phar_zip_reconstruct_apply TSRMLS_CC); + return EOF; +} +/* }}} */ +#endif /* if HAVE_PHAR_ZIP */ + /** * Save phar contents to disk * @@ -2522,6 +3312,11 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err return EOF; } +#if HAVE_PHAR_ZIP + if (archive->is_zip) { + return phar_zip_flush(archive, user_stub, len, error TSRMLS_CC); + } +#endif if (archive->fp && !archive->is_brandnew) { oldfile = archive->fp; closeoldfile = 0; @@ -3500,27 +4295,6 @@ PHAR_ADD_ENTRY: } /* }}}*/ -#if defined(PHP_VERSION_ID) && (PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 60000) - -static int _php_stream_unlink(char *url, int options, php_stream_context *context TSRMLS_DC) -{ - php_stream_wrapper *wrapper = php_stream_locate_url_wrapper(url, NULL, options TSRMLS_CC); - - if (!wrapper || !wrapper->wops) { - return 0; - } - - if (!wrapper->wops->unlink) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper"); - return 0; - } - return wrapper->wops->unlink(wrapper, url, ENFORCE_SAFE_MODE | REPORT_ERRORS, context TSRMLS_CC); -} - -#define php_stream_unlink(url, options, context) _php_stream_unlink((url), (options), (context) TSRMLS_CC) - -#endif - /** * Unlink a file within a phar archive */ @@ -3896,13 +4670,24 @@ static void php_phar_init_globals_module(zend_phar_globals *phar_globals) static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { zend_op_array *res; - char *s, *name = NULL; + char *name = NULL; char *fname = NULL; int fname_len, failed; zend_op_array *(*save)(zend_file_handle *file_handle, int type TSRMLS_DC); save = zend_compile_file; /* restore current handler or we cause trouble */ zend_compile_file = phar_orig_compile_file; + if (strstr(file_handle->filename, ".phar.zip") && !strstr(file_handle->filename, ":\\")) { + /* zip-based phar */ + spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php"); + file_handle->type = ZEND_HANDLE_FILENAME; + file_handle->free_filename = 1; + file_handle->filename = name; + if (file_handle->opened_path) { + efree(file_handle->opened_path); + } + goto skip_phar; + } if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { char *arch, *entry; int arch_len, entry_len; @@ -3916,13 +4701,11 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type efree(entry); entry = file_handle->filename; /* include within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = strlen(entry); - for (s = entry; s < (entry + entry_len - 4); s++) { - if (*s == ':' && *(s + 1) == '/' && *(s + 2) == '/') { - efree(arch); - goto skip_phar; - } + if (strstr(entry, "://")) { + efree(arch); + goto skip_phar; } + entry_len = strlen(entry); /* auto-convert to phar:// */ spprintf(&name, 4096, "phar://%s/%s", arch, entry); efree(arch); @@ -4075,6 +4858,15 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */ php_info_print_table_row(2, "Phar EXT version", PHAR_EXT_VERSION_STR); php_info_print_table_row(2, "Phar API version", PHAR_API_VERSION_STR); php_info_print_table_row(2, "CVS revision", "$Revision$"); + php_info_print_table_row(2, "Phar-based phar archives", + "enabled"); +#if HAVE_PHAR_ZIP + php_info_print_table_row(2, "ZIP-based phar archives", + "enabled"); +#else + php_info_print_table_row(2, "ZIP-based phar archives", + "disabled"); +#endif #if HAVE_ZLIB if (phar_has_zlib) { php_info_print_table_row(2, "gzip compression", diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index c3b0d42776..a39d7e93d5 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -50,6 +50,10 @@ #ifndef PHP_WIN32 #include "TSRM/tsrm_strtok_r.h" #endif +#if HAVE_PHAR_ZIP +#include "lib/zip.h" +#include "lib/zipint.h" +#endif #if HAVE_SPL #include "ext/spl/spl_array.h" #include "ext/spl/spl_directory.h" @@ -180,6 +184,12 @@ typedef struct _phar_entry_info { int is_dir:1; phar_archive_data *phar; smart_str metadata_str; + /* zip-based phar file stuff */ + int is_zip:1; +#if HAVE_PHAR_ZIP + int index; + struct zip_file *zip; +#endif } phar_entry_info; /* information about a phar file (the archive itself) */ @@ -207,6 +217,11 @@ struct _phar_archive_data { int is_brandnew:1; /* defer phar creation */ int donotflush:1; + /* zip-based phar variables */ + int is_zip:1; +#if HAVE_PHAR_ZIP + struct zip *zip; +#endif }; #define PHAR_MIME_PHP '\0' @@ -229,6 +244,7 @@ typedef struct _phar_entry_data { /* for copies of the phar fp, defines where 0 is */ off_t zero; int for_write:1; + int is_zip:1; phar_entry_info *internal_file; } phar_entry_data; @@ -268,7 +284,9 @@ void phar_object_init(TSRMLS_D); int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC); int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC); int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC); - +phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp, + char **error, int for_write TSRMLS_DC); +int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC); #ifdef PHAR_MAIN static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 1efa016c18..8f5be1c79e 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -135,10 +135,15 @@ static int phar_file_action(phar_entry_data *phar, char *mime_type, int code, ch /* prepare to output */ if (!phar->fp) { - phar->internal_file->fp_refcount++; - phar->fp = phar->phar->fp; - phar->zero = phar->phar->internal_file_start + phar->internal_file->offset_within_phar; - phar->internal_file->fp = phar->phar->fp; + char *error; + if (!phar_open_jit(phar->phar, phar->internal_file, phar->phar->fp, &error, 0 TSRMLS_CC)) { + if (error) { + zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); + efree(error); + } + return -1; + } + phar->fp = phar->internal_file->fp; } php_stream_seek(phar->fp, phar->position + phar->zero, SEEK_SET); do { @@ -273,6 +278,32 @@ PHP_METHOD(Phar, webPhar) fname = zend_get_executed_filename(TSRMLS_C); fname_len = strlen(fname); + + if (strstr(fname, "://")) { + char *arch, *entry; + int arch_len, entry_len; + phar_archive_data *phar; + + /* running within a zip-based phar, acquire the actual name */ + if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + efree(entry); + efree(arch); + return; /* this, incidentally, should be impossible */ + } + + efree(entry); + entry = fname; + fname = arch; + fname_len = arch_len; + if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && phar->is_zip) { + efree(arch); + fname = phar->fname; + fname_len = phar->fname_len; + } else { + efree(arch); + fname = entry; + } + } #ifdef PHP_WIN32 fname = estrndup(fname, fname_len); phar_unixify_path_separators(fname, fname_len); @@ -1103,8 +1134,13 @@ PHP_METHOD(Phar, setAlias) } efree(phar_obj->arc.archive->alias); - phar_obj->arc.archive->alias = estrndup(alias, alias_len); + if (alias_len) { + phar_obj->arc.archive->alias = estrndup(alias, alias_len); + } else { + phar_obj->arc.archive->alias = NULL; + } phar_obj->arc.archive->alias_len = alias_len; + phar_obj->arc.archive->is_explicit_alias = 0; phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); @@ -1541,6 +1577,11 @@ PHP_METHOD(Phar, copy) newentry.metadata_str.c = NULL; newentry.metadata_str.len = 0; } +#if HAVE_PHAR_ZIP + if (oldentry->is_zip) { + newentry.index = -1; + } +#endif newentry.fp = fp; newentry.filename = estrndup(newfile, newfile_len); newentry.filename_len = newfile_len; @@ -1552,7 +1593,7 @@ PHP_METHOD(Phar, copy) zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error); efree(error); } - + RETURN_TRUE; } @@ -1694,6 +1735,15 @@ PHP_METHOD(Phar, offsetUnset) } entry->is_modified = 0; entry->is_deleted = 1; +#if HAVE_PHAR_ZIP + if (entry->is_zip) { + if (entry->zip) { + zip_fclose(entry->zip); + entry->zip = 0; + } + zip_delete(phar_obj->arc.archive->zip, entry->index); + } +#endif /* we need to "flush" the stream to save the newly deleted file on disk */ phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC); if (error) { @@ -1718,6 +1768,36 @@ PHP_METHOD(Phar, getStub) php_stream *fp; PHAR_ARCHIVE_OBJECT(); +#if HAVE_PHAR_ZIP + if (phar_obj->arc.archive->is_zip) { + struct zip_stat zs; + struct zip_file *zf; + int index; + + if (-1 == zip_stat(phar_obj->arc.archive->zip, ".phar/stub.php", 0, &zs)) { + zip_error_clear(phar_obj->arc.archive->zip); + RETURN_STRINGL("", 0, 1); + } + index = zs.index; + len = zs.size; + zf = zip_fopen_index(phar_obj->arc.archive->zip, index, 0); + if (!zf) { + zip_error_clear(phar_obj->arc.archive->zip); + RETURN_STRINGL("", 0, 1); + } + buf = safe_emalloc(len, 1, 1); + if (len != zip_fread(zf, buf, len)) { + zip_fclose(zf); + efree(buf); + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, + "Unable to read stub"); + return; + } + buf[len] = '\0'; + + RETURN_STRINGL(buf, len, 0); + } +#endif len = phar_obj->arc.archive->halt_offset; if (phar_obj->arc.archive->fp && !phar_obj->arc.archive->is_brandnew) { @@ -1747,7 +1827,7 @@ PHP_METHOD(Phar, getStub) php_stream_close(fp); } buf[len] = '\0'; - + RETURN_STRINGL(buf, len, 0); } /* }}}*/ @@ -1913,7 +1993,7 @@ PHP_METHOD(PharFileInfo, __destruct) PHAR_ENTRY_OBJECT(); if (entry_obj->ent.entry->is_dir) { - if (entry_obj->ent.entry->filename) { + if (!entry_obj->ent.entry->is_zip && entry_obj->ent.entry->filename) { efree(entry_obj->ent.entry->filename); entry_obj->ent.entry->filename = NULL; } @@ -2198,6 +2278,10 @@ PHP_METHOD(PharFileInfo, setCompressedBZIP2) char *error; PHAR_ENTRY_OBJECT(); + if (entry_obj->ent.entry->is_zip) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot compress with Bzip2 compression, not possible with zip-based phar archives"); + } if (!phar_has_bz2) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot compress with Bzip2 compression, bz2 extension is not enabled"); diff --git a/ext/phar/tests/001.phpt b/ext/phar/tests/001.phpt index 26c225deb0..397501e8e4 100644 --- a/ext/phar/tests/001.phpt +++ b/ext/phar/tests/001.phpt @@ -8,5 +8,5 @@ var_dump(Phar::apiVersion()); ?> ===DONE=== --EXPECT-- -string(5) "1.2.0" +string(5) "1.1.0" ===DONE=== -- 2.50.1