diff options
author | SVN Migration <svn@php.net> | 2006-10-15 21:09:28 +0000 |
---|---|---|
committer | SVN Migration <svn@php.net> | 2006-10-15 21:09:28 +0000 |
commit | 88ec761548b66f58acc1a86cdd0fc164ca925476 (patch) | |
tree | d0af978fa00d83bb1d82c613f66477fbd6bb18aa /ext/zip/lib/zip_open.c | |
parent | 268984b4787e797db6054313fc9ba3b9e845306e (diff) | |
download | php-git-PECL_OPENSSL.tar.gz |
This commit was manufactured by cvs2svn to create branch 'PECL_OPENSSL'.PECL_OPENSSL
Diffstat (limited to 'ext/zip/lib/zip_open.c')
-rw-r--r-- | ext/zip/lib/zip_open.c | 465 |
1 files changed, 0 insertions, 465 deletions
diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c deleted file mode 100644 index 0a14abda58..0000000000 --- a/ext/zip/lib/zip_open.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - $NiH: zip_open.c,v 1.38 2006/05/04 00:01:26 dillo Exp $ - - zip_open.c -- open 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 <nih@giga.or.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 <sys/stat.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifndef _MSC_VER -#include <unistd.h> -#endif -#include <sys/types.h> -#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; - } - - 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; i<cdir->nentry; 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; i<cd->nentry; 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; i<cd->nentry; 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; -} |