]> granicus.if.org Git - php/commitdiff
initial libzip upgrade patch to 0.10.1
authorAnatoliy Belsky <ab@php.net>
Mon, 4 Jun 2012 19:30:04 +0000 (21:30 +0200)
committerAnatoliy Belsky <ab@php.net>
Thu, 7 Jun 2012 19:01:31 +0000 (21:01 +0200)
64 files changed:
ext/zip/config.m4
ext/zip/config.w32
ext/zip/lib/zip.h
ext/zip/lib/zip_add.c
ext/zip/lib/zip_add_dir.c
ext/zip/lib/zip_close.c
ext/zip/lib/zip_delete.c
ext/zip/lib/zip_dirent.c
ext/zip/lib/zip_entry_free.c
ext/zip/lib/zip_entry_new.c
ext/zip/lib/zip_err_str.c
ext/zip/lib/zip_error.c
ext/zip/lib/zip_error_to_str.c
ext/zip/lib/zip_fclose.c
ext/zip/lib/zip_fdopen.c [new file with mode: 0644]
ext/zip/lib/zip_filerange_crc.c
ext/zip/lib/zip_fopen.c
ext/zip/lib/zip_fopen_encrypted.c [new file with mode: 0644]
ext/zip/lib/zip_fopen_index.c
ext/zip/lib/zip_fopen_index_encrypted.c [new file with mode: 0644]
ext/zip/lib/zip_fread.c
ext/zip/lib/zip_free.c
ext/zip/lib/zip_get_archive_comment.c
ext/zip/lib/zip_get_archive_flag.c
ext/zip/lib/zip_get_compression_implementation.c [new file with mode: 0644]
ext/zip/lib/zip_get_encryption_implementation.c [new file with mode: 0644]
ext/zip/lib/zip_get_file_comment.c
ext/zip/lib/zip_get_file_extra.c [new file with mode: 0644]
ext/zip/lib/zip_get_name.c
ext/zip/lib/zip_get_num_entries.c [new file with mode: 0644]
ext/zip/lib/zip_name_locate.c
ext/zip/lib/zip_new.c
ext/zip/lib/zip_open.c
ext/zip/lib/zip_rename.c
ext/zip/lib/zip_replace.c
ext/zip/lib/zip_set_archive_comment.c
ext/zip/lib/zip_set_archive_flag.c
ext/zip/lib/zip_set_default_password.c [new file with mode: 0644]
ext/zip/lib/zip_set_file_comment.c
ext/zip/lib/zip_set_file_extra.c [new file with mode: 0644]
ext/zip/lib/zip_set_name.c
ext/zip/lib/zip_source_buffer.c
ext/zip/lib/zip_source_close.c [new file with mode: 0644]
ext/zip/lib/zip_source_crc.c [new file with mode: 0644]
ext/zip/lib/zip_source_deflate.c [new file with mode: 0644]
ext/zip/lib/zip_source_error.c [new file with mode: 0644]
ext/zip/lib/zip_source_file.c
ext/zip/lib/zip_source_filep.c
ext/zip/lib/zip_source_free.c
ext/zip/lib/zip_source_function.c
ext/zip/lib/zip_source_layered.c [new file with mode: 0644]
ext/zip/lib/zip_source_open.c [new file with mode: 0644]
ext/zip/lib/zip_source_pkware.c [new file with mode: 0644]
ext/zip/lib/zip_source_pop.c [new file with mode: 0644]
ext/zip/lib/zip_source_read.c [new file with mode: 0644]
ext/zip/lib/zip_source_stat.c [new file with mode: 0644]
ext/zip/lib/zip_source_zip.c
ext/zip/lib/zip_stat_index.c
ext/zip/lib/zip_stat_init.c
ext/zip/lib/zip_unchange.c
ext/zip/lib/zip_unchange_archive.c
ext/zip/lib/zip_unchange_data.c
ext/zip/lib/zipconf.h [new file with mode: 0644]
ext/zip/lib/zipint.h

index d5c24ce9cf4071a66115a19975efc3d88f05f681..85f9119f5aac126803537bf25155fe38db962706 100644 (file)
@@ -89,7 +89,14 @@ yes
                          lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.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"
+                         lib/zip_error_clear.c lib/zip_file_error_clear.c \
+                                                lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \
+                                                lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \
+                                                lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \
+                                                lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \
+                                                lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \
+                                                lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \
+                                                lib/zip_source_read.c lib/zip_source_stat.c"
 
   AC_DEFINE(HAVE_ZIP,1,[ ])
   PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared)
index e60a983b3a89db1b397db5072e79b09d76e17ffd..b63817080738fbd195ce93396e2423a9dc67616c 100644 (file)
@@ -27,7 +27,14 @@ if (PHP_ZIP != "no") {
                      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", "zip");
+                     zip_add_dir.c zip_file_error_clear.c zip_error_clear.c
+                                        lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \
+                                        lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \
+                                        lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \
+                                        lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \
+                                        lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \
+                                        lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \
+                                        lib/zip_source_read.c lib/zip_source_stat.c", "zip");
 
                AC_DEFINE('HAVE_ZIP', 1);
        } else {
index 14a57bc5829bc3a0730f7209c1becd11726581fc..4a80c9e1065749831006c3f1043ec1ee829f9658 100644 (file)
@@ -3,7 +3,7 @@
 
 /*
   zip.h -- exported declarations.
-  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -52,6 +52,8 @@
 
 BEGIN_EXTERN_C()
 
+#include <lib/zipconf.h>
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <time.h>
@@ -71,10 +73,19 @@ BEGIN_EXTERN_C()
 #define ZIP_FL_COMPRESSED      4 /* read compressed data */
 #define ZIP_FL_UNCHANGED       8 /* use original data, ignoring changes */
 #define ZIP_FL_RECOMPRESS      16 /* force recompression of data */
+#define ZIP_FL_ENCRYPTED       32 /* read encrypted data
+                                    (implies ZIP_FL_COMPRESSED) */
 
 /* archive global flags flags */
 
 #define ZIP_AFL_TORRENT                1 /* torrent zipped */
+#define ZIP_AFL_RDONLY         2 /* read only -- cannot be cleared */
+
+
+/* flags for compression and encryption sources */
+
+#define ZIP_CODEC_ENCODE       1 /* compress/encrypt */
+
 
 /* libzip error codes */
 
@@ -102,7 +113,10 @@ BEGIN_EXTERN_C()
 #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 */
-
+#define ZIP_ER_ENCRNOTSUPP   24  /* N Encryption method not supported */
+#define ZIP_ER_RDONLY        25  /* N Read-only archive */ 
+#define ZIP_ER_NOPASSWD      26  /* N No password provided */
+#define ZIP_ER_WRONGPASSWD   27  /* N Wrong password provided */
 
 /* type of system error value */
 
@@ -162,69 +176,99 @@ enum zip_source_cmd {
     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);
+#define ZIP_SOURCE_ERR_LOWER   -2
+
+#define ZIP_STAT_NAME                  0x0001
+#define ZIP_STAT_INDEX                 0x0002
+#define ZIP_STAT_SIZE                  0x0004
+#define ZIP_STAT_COMP_SIZE             0x0008
+#define ZIP_STAT_MTIME                 0x0010
+#define ZIP_STAT_CRC                   0x0020
+#define ZIP_STAT_COMP_METHOD           0x0040
+#define ZIP_STAT_ENCRYPTION_METHOD     0x0080
+#define ZIP_STAT_FLAGS                 0x0100
 
 struct zip_stat {
+    zip_uint64_t valid;                        /* which fields have valid values */
     const char *name;                  /* name of the file */
-    int index;                         /* index within archive */
-    unsigned int crc;                  /* crc of file data */
+    zip_uint64_t index;                        /* index within archive */
+    zip_uint64_t size;                 /* size of file (uncompressed) */
+    zip_uint64_t comp_size;            /* size of file (compressed) */
     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 */
+    zip_uint32_t crc;                  /* crc of file data */
+    zip_uint16_t comp_method;          /* compression method used */
+    zip_uint16_t encryption_method;    /* encryption method used */
+    zip_uint32_t flags;                        /* reserved for future use */
 };
 
 struct zip;
 struct zip_file;
 struct zip_source;
 
+typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t,
+                                          enum zip_source_cmd);
+
 \f
 
-ZIP_EXTERN(int) zip_add(struct zip *, const char *, struct zip_source *);
-ZIP_EXTERN(int) zip_add_dir(struct zip *, const char *);
+ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *);
+ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *);
 ZIP_EXTERN(int) zip_close(struct zip *);
-ZIP_EXTERN(int) zip_delete(struct zip *, int);
+ZIP_EXTERN(int) zip_delete(struct zip *, zip_uint64_t);
 ZIP_EXTERN(void) zip_error_clear(struct zip *);
 ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *);
 ZIP_EXTERN(int) zip_error_get_sys_type(int);
-ZIP_EXTERN(int) zip_error_to_str(char *, size_t, int, int);
+ZIP_EXTERN(int) zip_error_to_str(char *, zip_uint64_t, int, int);
 ZIP_EXTERN(int) zip_fclose(struct zip_file *);
+ZIP_EXTERN(struct zip *)zip_fdopen(int, int, int *);
 ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *);
 ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *);
 ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *);
-ZIP_EXTERN(struct zip_file *)zip_fopen(struct zip *, const char *, int);
-ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, int, int);
-ZIP_EXTERN(ssize_t) zip_fread(struct zip_file *, void *, size_t);
+ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int);
+ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *,
+                                               int, const char *);
+ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, zip_uint64_t, int);
+ZIP_EXTERN(struct zip_file *)zip_fopen_index_encrypted(struct zip *,
+                                                     zip_uint64_t, int,
+                                                     const char *);
+ZIP_EXTERN(zip_int64_t) zip_fread(struct zip_file *, void *, zip_uint64_t);
 ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int);
 ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int);
-ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, int, int *, int);
-ZIP_EXTERN(const char *)zip_get_name(struct zip *, int, int);
-ZIP_EXTERN(int) zip_get_num_files(struct zip *);
+ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t,
+                                           int *, int);
+ZIP_EXTERN(const char *)zip_get_file_extra(struct zip *, zip_uint64_t,
+                                         int *, int);
+ZIP_EXTERN(const char *)zip_get_name(struct zip *, zip_uint64_t, int);
+ZIP_EXTERN(zip_uint64_t) zip_get_num_entries(struct zip *, int);
+ZIP_EXTERN(int) zip_get_num_files(struct zip *);  /* deprecated, use zip_get_num_entries instead */
 ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int);
 ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *);
-ZIP_EXTERN(int) zip_rename(struct zip *, int, const char *);
-ZIP_EXTERN(int) zip_replace(struct zip *, int, struct zip_source *);
+ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *);
+ZIP_EXTERN(int) zip_replace(struct zip *, zip_uint64_t, struct zip_source *);
 ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int);
 ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int);
-ZIP_EXTERN(int) zip_set_file_comment(struct zip *, int, const char *, int);
-ZIP_EXTERN(struct zip_source *)zip_source_buffer(struct zip *, const void *,
-                                               off_t, int);
-ZIP_EXTERN(struct zip_source *)zip_source_file(struct zip *, const char *,
-                                             off_t, off_t);
-ZIP_EXTERN(struct zip_source *)zip_source_filep(struct zip *, FILE *,
-                                              off_t, off_t);
+ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *);
+ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t,
+                                   const char *, int);
+ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t,
+                                 const char *, int);
+ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *,
+                                               zip_uint64_t, int);
+ZIP_EXTERN(struct) zip_source *zip_source_file(struct zip *, const char *,
+                                             zip_uint64_t, zip_int64_t);
+ZIP_EXTERN(struct) zip_source *zip_source_filep(struct zip *, FILE *,
+                                              zip_uint64_t, zip_int64_t);
 ZIP_EXTERN(void) zip_source_free(struct zip_source *);
 ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *,
                                                  zip_source_callback, void *);
 ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *,
-                                            int, int, off_t, off_t);
+                                            zip_uint64_t, int,
+                                            zip_uint64_t, zip_int64_t);
 ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *);
-ZIP_EXTERN(int) zip_stat_index(struct zip *, int, int, struct zip_stat *);
+ZIP_EXTERN(int) zip_stat_index(struct zip *, zip_uint64_t, int,
+                             struct zip_stat *);
 ZIP_EXTERN(void) zip_stat_init(struct zip_stat *);
 ZIP_EXTERN(const char *)zip_strerror(struct zip *);
-ZIP_EXTERN(int) zip_unchange(struct zip *, int);
+ZIP_EXTERN(int) zip_unchange(struct zip *, zip_uint64_t);
 ZIP_EXTERN(int) zip_unchange_all(struct zip *);
 ZIP_EXTERN(int) zip_unchange_archive(struct zip *);
 
index 85d5997911b9420557dbb28cda3362ce99e7a1b7..6067abbac491fb64532b2d195af7ce08de3fee26 100644 (file)
 
 \f
 
-ZIP_EXTERN(int)
+/*
+  NOTE: Return type is signed so we can return -1 on error.
+        The index can not be larger than ZIP_INT64_MAX since the size
+        of the central directory cannot be larger than
+        ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
+*/
+
+ZIP_EXTERN(zip_int64_t)
 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);
+       
+    return _zip_replace(za, ZIP_UINT64_MAX, name, source);
 }
index 9b23425194298bac1da4369f46d517829091a4e3..0a9d7f4863011edb8ff89fd4c624a3d0e31a6cb3 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_add_dir.c -- add directory
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 
 \f
 
-ZIP_EXTERN(int)
+/* NOTE: Signed due to -1 on error.  See zip_add.c for more details. */
+
+ZIP_EXTERN(zip_int64_t)
 zip_add_dir(struct zip *za, const char *name)
 {
-    int len, ret;
+    int len;
+    zip_int64_t ret;
     char *s;
     struct zip_source *source;
 
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
     if (name == NULL) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
index 0796f27462bbf9466c61386ff8674e1267155fdc..fc1ad02d52c10c1f1d5c66d3cd5143ae718c304b 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_close.c -- close zip archive and update changes
-  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 
 \f
 
+#include "zipint.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
-
-#include "zipint.h"
+#ifdef PHP_WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
 
 static int add_data(struct zip *, struct zip_source *, 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(struct zip *, zip_source_callback, void *,
-                          struct zip_stat *, FILE *);
-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 copy_source(struct zip *, struct zip_source *, FILE *);
 static int write_cdir(struct zip *, struct zip_cdir *, FILE *);
 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 **);
 static int _zip_torrentzip_cmp(const void *, const void *);
 
@@ -72,7 +74,9 @@ zip_close(struct zip *za)
     int i, j, error;
     char *temp;
     FILE *out;
+#ifndef PHP_WIN32
     mode_t mask;
+#endif
     struct zip_cdir *cd;
     struct zip_dirent de;
     struct filelist *filelist;
@@ -99,7 +103,7 @@ zip_close(struct zip *za)
        }
        _zip_free(za);
        return 0;
-    }
+    }         
 
     if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors))
        == NULL)
@@ -126,11 +130,11 @@ zip_close(struct zip *za)
        cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN;
     }
     else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) {
-    if (_zip_cdir_set_comment(cd, za) == -1) {
-       _zip_cdir_free(cd);
+       if (_zip_cdir_set_comment(cd, za) == -1) {
+           _zip_cdir_free(cd);
            free(filelist);
-       return -1;
-    }
+           return -1;
+       }
     }
 
     if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
@@ -198,8 +202,7 @@ zip_close(struct zip *za)
                error = 1;
                break;
            }
-           memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
-
+           memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
            if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
                de.crc = za->cdir->entry[i].crc;
                de.comp_size = za->cdir->entry[i].comp_size;
@@ -220,6 +223,22 @@ zip_close(struct zip *za)
            cd->entry[j].filename_len = de.filename_len;
        }
 
+       if (za->entry[i].ch_extra_len != -1) {
+           free(de.extrafield);
+           if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) {
+               error = 1;
+               break;
+           }
+           memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len);
+           de.extrafield_len = za->entry[i].ch_extra_len;
+           /* as the rest of cd entries, its malloc/free is done by za */
+           /* TODO unsure if this should also be set in the CD --
+            * not done for now
+           cd->entry[j].extrafield = za->entry[i].ch_extra;
+           cd->entry[j].extrafield_len = za->entry[i].ch_extra_len;
+           */
+       }
+
        if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0
            && za->entry[i].ch_comment_len != -1) {
            /* as the rest of cd entries, its malloc/free is done by za */
@@ -234,16 +253,22 @@ zip_close(struct zip *za)
 
            zs = NULL;
            if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
-                       if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) == NULL) {
-                               error = 1;
-                               break;
-               }
+               if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1))
+                   == NULL) {
+                   error = 1;
+                   break;
+               }
            }
 
            if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) {
                error = 1;
+               if (zs)
+                   zip_source_free(zs);
                break;
            }
+           if (zs)
+               zip_source_free(zs);
+           
            cd->entry[j].last_mod = de.last_mod;
            cd->entry[j].comp_method = de.comp_method;
            cd->entry[j].comp_size = de.comp_size;
@@ -307,9 +332,11 @@ zip_close(struct zip *za)
                }
                return -1;
        }
+#ifndef PHP_WIN32
     mask = umask(0);
     umask(mask);
     chmod(za->zn, 0666&~mask);
+#endif
     if (za->ch_comment)
         free(za->ch_comment);
 
@@ -322,23 +349,17 @@ zip_close(struct zip *za)
 \f
 
 static int
-add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
+add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
+        FILE *ft)
 {
-    off_t offstart, offend;
-    zip_source_callback cb;
-    void *ud;
+    off_t offstart, offdata, offend;
     struct zip_stat st;
-
-    cb = zs->f;
-    ud = zs->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);
+    struct zip_source *s2;
+    zip_compression_implementation comp_impl;
+    int ret;
+    
+    if (zip_source_stat(src, &st) < 0) {
+       _zip_error_set_from_source(&za->error, src);
        return -1;
     }
 
@@ -347,19 +368,49 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *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;
+    if ((s2=zip_source_crc(za, src, 0)) == NULL) {
+       zip_source_pop(s2);
+       return -1;
     }
-    else {
-       if (add_data_uncomp(za, cb, ud, &st, ft) < 0)
+    
+    /* XXX: deflate 0-byte files for torrentzip? */
+    if (((st.valid & ZIP_STAT_COMP_METHOD) == 0
+        || st.comp_method == ZIP_CM_STORE)
+       && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
+       comp_impl = NULL;
+       if ((comp_impl=zip_get_compression_implementation(ZIP_CM_DEFLATE))
+           == NULL) {
+           _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+           zip_source_pop(s2);
+           return -1;
+       }
+       if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE))
+           == NULL) {
+           /* XXX: set error? */
+           zip_source_pop(s2);
            return -1;
+       }
+    }
+    else
+       s2 = src;
+
+    offdata = ftello(ft);
+       
+    ret = copy_source(za, s2, ft);
+       
+    if (zip_source_stat(s2, &st) < 0)
+       ret = -1;
+    
+    while (s2 != src) {
+       if ((s2=zip_source_pop(s2)) == NULL) {
+           /* XXX: set erorr */
+           ret = -1;
+           break;
+       }
     }
 
-    if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) {
-       ch_set_error(&za->error, cb, ud);
+    if (ret < 0)
        return -1;
-    }
 
     offend = ftello(ft);
 
@@ -368,19 +419,18 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
        return -1;
     }
 
-    
     de->last_mod = st.mtime;
     de->comp_method = st.comp_method;
     de->crc = st.crc;
     de->uncomp_size = st.size;
-    de->comp_size = st.comp_size;
+    de->comp_size = offend - offdata;
 
     if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
        _zip_dirent_torrent_normalize(de);
 
     if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
        return -1;
-
+    
     if (fseeko(ft, offend, SEEK_SET) < 0) {
        _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
        return -1;
@@ -391,133 +441,6 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
 
 \f
 
-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;
-}
-
-\f
-
-static int
-add_data_uncomp(struct zip *za, zip_source_callback cb, void *ud,
-               struct zip_stat *st, FILE *ft)
-{
-    char b1[BUFSIZE], b2[BUFSIZE];
-    int end, flush, ret;
-    ssize_t n;
-    size_t n2;
-    z_stream zstr;
-    int mem_level;
-
-    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;
-
-    if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
-       mem_level = TORRENT_MEM_LEVEL;
-    else
-       mem_level = MAX_MEM_LEVEL;
-
-    /* -MAX_WBITS: undocumented feature of zlib to _not_ write a zlib header */
-    deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, mem_level,
-                Z_DEFAULT_STRATEGY);
-
-    zstr.next_out = (Bytef *)b2;
-    zstr.avail_out = sizeof(b2);
-    zstr.next_in = NULL;
-    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(&za->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(&za->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(&za->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;
-}
-
-\f
-
-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];
-    }
-}
-
-\f
-
 static int
 copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
 {
@@ -551,6 +474,40 @@ copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
 
 \f
 
+static int
+copy_source(struct zip *za, struct zip_source *src, FILE *ft)
+{
+    char buf[BUFSIZE];
+    zip_int64_t n;
+    int ret;
+
+    if (zip_source_open(src) < 0) {
+       _zip_error_set_from_source(&za->error, src);
+       return -1;
+    }
+
+    ret = 0;
+    while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
+       if (fwrite(buf, 1, n, ft) != (size_t)n) {
+           _zip_error_set(&za->error, ZIP_ER_WRITE, errno);
+           ret = -1;
+           break;
+       }
+    }
+    
+    if (n < 0) {
+       if (ret == 0)
+           _zip_error_set_from_source(&za->error, src);
+       ret = -1;
+    }  
+
+    zip_source_close(src);
+    
+    return ret;
+}
+
+\f
+
 static int
 write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
 {
@@ -613,7 +570,7 @@ _zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
 
 \f
 
-static int
+int
 _zip_changed(struct zip *za, int *survivorsp)
 {
     int changed, i, survivors;
@@ -626,13 +583,15 @@ _zip_changed(struct zip *za, int *survivorsp)
 
     for (i=0; i<za->nentry; i++) {
        if ((za->entry[i].state != ZIP_ST_UNCHANGED)
+           || (za->entry[i].ch_extra_len != -1)
            || (za->entry[i].ch_comment_len != -1))
            changed = 1;
        if (za->entry[i].state != ZIP_ST_DELETED)
            survivors++;
     }
 
-    *survivorsp = survivors;
+    if (survivorsp)
+       *survivorsp = survivors;
 
     return changed;
 }
@@ -668,6 +627,10 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
        return NULL;
     }
 #ifdef PHP_WIN32
+    /*
+      According to Pierre Joye, Windows in some environments per
+      default creates text files, so force binary mode.
+    */
        _setmode(_fileno(tfp), _O_BINARY );
 #endif
 
index 4591ff7f86a0fea58328db361c46fba840f7b64a..da3e65b28a3723199c8cd469dff020abd3ccb948 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_delete.c -- delete file from zip archive
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 \f
 
 ZIP_EXTERN(int)
-zip_delete(struct zip *za, int idx)
+zip_delete(struct zip *za, zip_uint64_t idx)
 {
     if (idx < 0 || idx >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
     /* allow duplicate file names, because the file will
      * be removed directly afterwards */
     if (_zip_unchange(za, idx, 1) != 0)
index 59f8ab0af9c6c5ace52c863526e66e0d7e7928c5..6cb9ee3ee51350bcb8617a9567c1563eaa00e51e 100644 (file)
@@ -45,7 +45,6 @@
 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 *);
 
@@ -213,13 +212,13 @@ _zip_dirent_init(struct zip_dirent *de)
 
 int
 _zip_dirent_read(struct zip_dirent *zde, FILE *fp,
-                unsigned char **bufp, unsigned int *leftp, int local,
+                unsigned char **bufp, zip_uint32_t *leftp, int local,
                 struct zip_error *error)
 {
     unsigned char buf[CDENTRYSIZE];
     unsigned char *cur;
     unsigned short dostime, dosdate;
-    unsigned int size;
+    zip_uint32_t size;
 
     if (local)
        size = LENTRYSIZE;
@@ -475,6 +474,8 @@ _zip_d2u_time(int dtime, int ddate)
 {
     struct tm tm = {0};
 
+    memset(&tm, 0, sizeof(tm));
+    
     /* let mktime decide if DST is in effect */
     tm.tm_isdst = -1;
     
@@ -598,7 +599,7 @@ _zip_write4(unsigned int i, FILE *fp)
 
 \f
 
-static void
+void
 _zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate)
 {
     struct tm *tm;
index c50c9434bdd93a138f02bf6bf917bc68fdda64ae..e8a77707f0bfa991954dde1256c307babdd9515a 100644 (file)
@@ -44,6 +44,9 @@ _zip_entry_free(struct zip_entry *ze)
 {
     free(ze->ch_filename);
     ze->ch_filename = NULL;
+    free(ze->ch_extra);
+    ze->ch_extra = NULL;
+    ze->ch_extra_len = -1;
     free(ze->ch_comment);
     ze->ch_comment = NULL;
     ze->ch_comment_len = -1;
index 7059b1b060749d93cacfb7f499b1b072a25eee54..ad5d59975a927444fef49e5d1e48e4badc0a681c 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_entry_new.c -- create and init struct zip_entry
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -46,20 +46,21 @@ _zip_entry_new(struct zip *za)
     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) {
+       if (za->nentry+1 >= za->nentry_alloc) {
+           struct zip_entry *rentries;
            za->nentry_alloc += 16;
-           za->entry = (struct zip_entry *)realloc(za->entry,
-                                                   sizeof(struct zip_entry)
-                                                   * za->nentry_alloc);
-           if (!za->entry) {
+           rentries = (struct zip_entry *)realloc(za->entry,
+                                                  sizeof(struct zip_entry)
+                                                  * za->nentry_alloc);
+           if (!rentries) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return NULL;
            }
+           za->entry = rentries;
        }
        ze = za->entry+za->nentry;
     }
@@ -67,6 +68,8 @@ _zip_entry_new(struct zip *za)
     ze->state = ZIP_ST_UNCHANGED;
 
     ze->ch_filename = NULL;
+    ze->ch_extra = NULL;
+    ze->ch_extra_len = -1;
     ze->ch_comment = NULL;
     ze->ch_comment_len = -1;
     ze->source = NULL;
index 3fcdf1738a8636ab01859dc9f4f00ea53a6d3a67..8fb60036e078e32fb1d35da7704586b8625a4b89 100644 (file)
@@ -32,6 +32,10 @@ const char * const _zip_err_str[] = {
     "Zip archive inconsistent",
     "Can't remove file",
     "Entry has been deleted",
+    "Encryption method not supported",
+    "Read-only archive", 
+    "No password provided",
+    "Wrong password provided",
 };
 
 const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
@@ -65,4 +69,8 @@ const int _zip_err_type[] = {
     N,
     S,
     N,
+    N,
+    N, 
+    N,
+    N,
 };
index aab70794566c0d2e248e88dada5c08827e70bcc4..b8d907abf4d9a56531363c446533f187a6b4ce0c 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_error.c -- struct zip_error helper functions
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -99,3 +99,14 @@ _zip_error_set(struct zip_error *err, int ze, int se)
        err->sys_err = se;
     }
 }
+
+\f
+
+void
+_zip_error_set_from_source(struct zip_error *err, struct zip_source *src)
+{
+    int ze, se;
+    
+    zip_source_error(src, &ze, &se);
+    _zip_error_set(err, ze, se);
+}
index 4dea4d667a5ee28976564edd130fa9894e3339c7..bafe74335a04942a74c4e5d75ef9741900d68e7e 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_error_to_str.c -- get string representation of zip error code
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -43,7 +43,7 @@
 \f
 
 ZIP_EXTERN(int)
-zip_error_to_str(char *buf, size_t len, int ze, int se)
+zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
 {
     const char *zs, *ss;
 
index 8f062d9d090f72c4438caba11482dd213acaf76a..eb55ddbcea4559827ec27b0b0fdb0b33c73d08ae 100644 (file)
@@ -44,28 +44,20 @@ 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; i<zf->za->nfile; i++) {
-                       if (zf->za->file[i] == zf) {
-                               zf->za->file[i] = zf->za->file[zf->za->nfile-1];
-                               zf->za->nfile--;
-                               break;
-                       }
-               }
+    if (zf->src)
+       zip_source_free(zf->src);
+
+    for (i=0; i<zf->za->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/zip/lib/zip_fdopen.c b/ext/zip/lib/zip_fdopen.c
new file mode 100644 (file)
index 0000000..df70f27
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+  zip_fdopen.c -- open read-only archive from file descriptor
+  Copyright (C) 2009-2010 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(struct zip *)
+zip_fdopen(int fd_orig, int flags, int *zep)
+{
+    int fd;
+    FILE *fp;
+
+    /* We dup() here to avoid messing with the passed in fd.
+       We could not restore it to the original state in case of error. */
+
+    if ((fd=dup(fd_orig)) < 0) {
+       *zep = ZIP_ER_OPEN;
+       return NULL;
+    }
+
+    if ((fp=fdopen(fd, "rb")) == NULL) {
+       close(fd);
+       *zep = ZIP_ER_OPEN;
+       return NULL;
+    }
+
+    close(fd_orig);
+    return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep);
+}
index c6890987b16df928362d6dedc7c75ff1714fbcc9..4d1ad566929f8d5d0c0d15833340f3584d039289 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_filerange_crc.c -- compute CRC32 for a range of a file
-  Copyright (C) 2008-2009 Dieter Baron and Thomas Klausner
+  Copyright (C) 2008 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
index b4b76049f4430e625d456537d349ba14b9880d18..f62adbbf926925c9edec4e2b6592f704203ea9d2 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_fopen.c -- open file in zip archive for reading
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -45,5 +45,5 @@ zip_fopen(struct zip *za, const char *fname, int flags)
     if ((idx=zip_name_locate(za, fname, flags)) < 0)
        return NULL;
 
-    return zip_fopen_index(za, idx, flags);
+    return zip_fopen_index_encrypted(za, idx, flags, za->default_password);
 }
diff --git a/ext/zip/lib/zip_fopen_encrypted.c b/ext/zip/lib/zip_fopen_encrypted.c
new file mode 100644 (file)
index 0000000..8aba062
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+  zip_fopen_encrypted.c -- open file for reading with password
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(struct zip_file *)
+zip_fopen_encrypted(struct zip *za, const char *fname, int flags,
+                   const char *password)
+{
+    int idx;
+
+    if ((idx=zip_name_locate(za, fname, flags)) < 0)
+       return NULL;
+
+    return zip_fopen_index_encrypted(za, idx, flags, password);
+}
index 1e7e4198970aa073fe662f711d24329abad4f8d6..5c777ee0ffaf8cdef6847a14812ba8617391c5d8 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_fopen_index.c -- open file in zip archive for reading by index
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 
 #include "zipint.h"
 
-static struct zip_file *_zip_file_new(struct zip *za);
 
 \f
 
 ZIP_EXTERN(struct zip_file *)
-zip_fopen_index(struct zip *za, int fileno, int flags)
+zip_fopen_index(struct zip *za, zip_uint64_t 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;
-}
-
-\f
-
-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 (fseeko(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;  
-}
-
-\f
-
-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;
+    return zip_fopen_index_encrypted(za, fileno, flags, za->default_password);
 }
diff --git a/ext/zip/lib/zip_fopen_index_encrypted.c b/ext/zip/lib/zip_fopen_index_encrypted.c
new file mode 100644 (file)
index 0000000..988a78f
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+  zip_fopen_index_encrypted.c -- open file for reading by index w/ password
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "zipint.h"
+
+static struct zip_file *_zip_file_new(struct zip *za);
+
+\f
+
+ZIP_EXTERN(struct zip_file *)
+zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags,
+                         const char *password)
+{
+    struct zip_file *zf;
+    zip_compression_implementation comp_impl;
+    zip_encryption_implementation enc_impl;
+    struct zip_source *src, *s2;
+    zip_uint64_t start;
+    struct zip_stat st;
+
+    if (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;
+    }
+
+    if (flags & ZIP_FL_ENCRYPTED)
+       flags |= ZIP_FL_COMPRESSED;
+
+    zip_stat_index(za, fileno, flags, &st);
+
+    enc_impl = NULL;
+    if ((flags & ZIP_FL_ENCRYPTED) == 0) {
+       if (st.encryption_method != ZIP_EM_NONE) {
+           if (password == NULL) {
+               _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
+               return NULL;
+           }
+           if ((enc_impl=zip_get_encryption_implementation(
+                    st.encryption_method)) == NULL) {
+               _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+               return NULL;
+           }
+       }
+    }
+
+    comp_impl = NULL;
+    if ((flags & ZIP_FL_COMPRESSED) == 0) {
+       if (st.comp_method != ZIP_CM_STORE) {
+           if ((comp_impl=zip_get_compression_implementation(
+                    st.comp_method)) == NULL) {
+               _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+               return NULL;
+           }
+       }
+    }
+
+    if ((start=_zip_file_get_offset(za, fileno)) == 0)
+       return NULL;
+
+    if (st.comp_size == 0) {
+       if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL)
+           return NULL;
+    }
+    else {
+       if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size,
+                                      0, &st)) == NULL)
+           return NULL;
+       if (enc_impl) {
+           if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0,
+                            password)) == NULL) {
+               zip_source_free(src);
+               /* XXX: set error (how?) */
+               return NULL;
+           }
+           src = s2;
+       }
+       if (comp_impl) {
+           if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method,
+                             0)) == NULL) {
+               zip_source_free(src);
+               /* XXX: set error (how?) */
+               return NULL;
+           }
+           src = s2;
+       }
+       if ((flags & ZIP_FL_COMPRESSED) == 0
+           || st.comp_method == ZIP_CM_STORE ) {
+           if ((s2=zip_source_crc(za, src, 1)) == NULL) {
+               zip_source_free(src);
+               /* XXX: set error (how?) */
+               return NULL;
+           }
+           src = s2;
+       }
+    }
+
+    if (zip_source_open(src) < 0) {
+       _zip_error_set_from_source(&za->error, src);
+       zip_source_free(src);
+       return NULL;
+    }
+
+    zf = _zip_file_new(za);
+
+    zf->src = src;
+
+    return zf;
+}
+
+\f
+
+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->eof = 0;
+    zf->src = NULL;
+
+    return zf;
+}
index 00a6bdc4e05ad4582c7a6c22dba2fcc22ef8ef1c..4c828a843346f9b89a3126a1149baa7a5c5bb377 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_fread.c -- read from file
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 
 \f
 
-ZIP_EXTERN(ssize_t)
-zip_fread(struct zip_file *zf, void *outbuf, size_t toread)
+ZIP_EXTERN(zip_int64_t)
+zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread)
 {
-    int ret;
-       size_t out_before, len;
-    int i;
+    zip_int64_t n;
 
     if (!zf)
        return -1;
@@ -50,81 +48,27 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread)
     if (zf->error.zip_err != 0)
        return -1;
 
-    if ((zf->flags & ZIP_ZF_EOF) || (toread == 0))
-       return 0;
+    if (toread > ZIP_INT64_MAX) {
+       _zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
+       return -1;
+    }
 
-    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;
-           }
-       }
+    if ((zf->eof) || (toread == 0))
        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;
+    if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
+       _zip_error_set_from_source(&zf->error, zf->src);
+       return -1;
     }
     
-    zf->zstr->next_out = (Bytef *)outbuf;
+       /* XXX the following left from the previous PHP port, let's see how to use it now */
+    /*zf->zstr->next_out = (Bytef *)outbuf;
     zf->zstr->avail_out = toread;
-    out_before = zf->zstr->total_out;
+    out_before = zf->zstr->total_out;*/
     
     /* endless loop until something has been accomplished */
-    for (;;) {
-       ret = inflate(zf->zstr, Z_SYNC_FLUSH);
+    /*for (;;) {
+       ret = inflate(zf->zstr, Z_SYNC_FLUSH);*/
 
-       switch (ret) {
-       case Z_STREAM_END:
-           if (zf->zstr->total_out == out_before) {
-               if (zf->crc != zf->crc_orig) {
-                   _zip_error_set(&zf->error, ZIP_ER_CRC, 0);
-                   return -1;
-               }
-               else
-                   return 0;
-           }
-
-           /* fallthrough */
-
-       case Z_OK:
-           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;
-       }
-    }
+    return n;
 }
index 76c3a9673ff539433d4515d40cbecebfd4521dc7..9932c14fec9a2067cf36f52cb16fd051c77e159c 100644 (file)
@@ -57,7 +57,9 @@ _zip_free(struct zip *za)
     if (za->zp)
        fclose(za->zp);
 
+    free(za->default_password);
     _zip_cdir_free(za->cdir);
+    free(za->ch_comment);
 
     if (za->entry) {
        for (i=0; i<za->nentry; i++) {
index ed1324fd5b9c0d7b8eefe613efe91130dd05dda2..fe97e6e8c18a1fd8dc6945ee3b58e91c4ed33be9 100644 (file)
@@ -42,11 +42,11 @@ 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 (za->cdir) {
+           if (lenp != NULL)
+               *lenp = za->cdir->comment_len;
+           return za->cdir->comment;
+       }
        else {
            if (lenp != NULL)
                *lenp = -1;
index a595c51f59942d8bb944bc996d804bf4ac4a0eb6..2d46aa39ffbb4d4323e85129a9dcedb4ad5bb50c 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_get_archive_flag.c -- get archive global flag
-  Copyright (C) 2008-2009 Dieter Baron and Thomas Klausner
+  Copyright (C) 2008 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
diff --git a/ext/zip/lib/zip_get_compression_implementation.c b/ext/zip/lib/zip_get_compression_implementation.c
new file mode 100644 (file)
index 0000000..197cd49
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+  zip_get_compression_implementation.c -- get compression implementation
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(zip_compression_implementation)
+zip_get_compression_implementation(zip_uint16_t cm)
+{
+    if (cm == ZIP_CM_DEFLATE)
+       return zip_source_deflate;
+    return NULL;
+}
diff --git a/ext/zip/lib/zip_get_encryption_implementation.c b/ext/zip/lib/zip_get_encryption_implementation.c
new file mode 100644 (file)
index 0000000..783d538
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+  zip_get_encryption_implementation.c -- get encryption implementation
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(zip_encryption_implementation)
+zip_get_encryption_implementation(zip_uint16_t em)
+{
+    if (em == ZIP_EM_TRAD_PKWARE)
+       return zip_source_pkware;
+    return NULL;
+}
index 57dd9028bc1387b7a5f8fa616382aa79b183454a..43c1520e1d438f4df758d2be88c290421bc29f0e 100644 (file)
@@ -38,9 +38,9 @@
 \f
 
 ZIP_EXTERN(const char *)
-zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags)
+zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
 {
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
     }
diff --git a/ext/zip/lib/zip_get_file_extra.c b/ext/zip/lib/zip_get_file_extra.c
new file mode 100644 (file)
index 0000000..a27edd8
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+  zip_get_file_extra.c -- get file extra field
+  Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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"
+
+
+
+ZIP_EXTERN(const char *)
+zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
+{
+    if (idx >= za->nentry) {
+       _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+       return NULL;
+    }
+
+    if ((flags & ZIP_FL_UNCHANGED)
+       || (za->entry[idx].ch_extra_len == -1)) {
+       if (lenp != NULL)
+           *lenp = za->cdir->entry[idx].extrafield_len;
+       return za->cdir->entry[idx].extrafield;
+    }
+
+    if (lenp != NULL)
+       *lenp = za->entry[idx].ch_extra_len;
+    return za->entry[idx].ch_extra;
+}
index b58d972058897e4f9c218f2d8043f33ce61d8a58..945e24e1501d58f96aa4093d7f4078c676b3c330 100644 (file)
@@ -38,7 +38,7 @@
 \f
 
 ZIP_EXTERN(const char *)
-zip_get_name(struct zip *za, int idx, int flags)
+zip_get_name(struct zip *za, zip_uint64_t idx, int flags)
 {
     return _zip_get_name(za, idx, flags, &za->error);
 }
@@ -46,9 +46,10 @@ zip_get_name(struct zip *za, int idx, int flags)
 \f
 
 const char *
-_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error)
+_zip_get_name(struct zip *za, zip_uint64_t idx, int flags,
+             struct zip_error *error)
 {
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
        _zip_error_set(error, ZIP_ER_INVAL, 0);
        return NULL;
     }
diff --git a/ext/zip/lib/zip_get_num_entries.c b/ext/zip/lib/zip_get_num_entries.c
new file mode 100644 (file)
index 0000000..dd392e9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+  zip_get_num_entries.c -- get number of entries in archive
+  Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(zip_uint64_t)
+zip_get_num_entries(struct zip *za, int flags)
+{
+    if (za == NULL)
+       return -1;
+
+    if (flags & ZIP_FL_UNCHANGED) {
+      if (za->cdir == NULL)
+       return 0;
+      return za->cdir->nentry;
+    }
+    return za->nentry;
+}
index 96c4f937e0540ddeb9d7b6523e53ffc44db8d8bd..08d5b1fbf80d262d32d6960bd4312d24e0c35023 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_name_locate.c -- get index by name
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -17,7 +17,7 @@
   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
@@ -55,16 +55,20 @@ _zip_name_locate(struct zip *za, const char *fname, int flags,
     const char *fn, *p;
     int i, n;
 
+    if (za == NULL)
+       return -1;
+
     if (fname == NULL) {
        _zip_error_set(error, ZIP_ER_INVAL, 0);
        return -1;
     }
 
-    if((flags & ZIP_FL_UNCHANGED)  && !za->cdir) {
-       return -1;
+    if ((flags & ZIP_FL_UNCHANGED)  && za->cdir == NULL) {
+        _zip_error_set(error, ZIP_ER_NOENT, 0);
+        return -1;
     }
 
-    cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : strcmp;
+    cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
 
     n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry;
     for (i=0; i<n; i++) {
index 3e8ccee644bc2e091a3d0c89a204abf95c7f4723..7ce1237cdbabdb7d7f269a15ca00e67254f8985b 100644 (file)
@@ -65,6 +65,7 @@ _zip_new(struct zip_error *error)
     za->nfile = za->nfile_alloc = 0;
     za->file = NULL;
     za->flags = za->ch_flags = 0;
+    za->default_password = NULL;
     
     return za;
 }
index 31e12f4fc5f4e5e44a8e99ca3c2aaebcdda11964..11c6fe05a68a9cb152d0c25180aa2ccc554e55a0 100644 (file)
@@ -1,6 +1,6 @@
 /*
-  zip_open.c -- open zip archive
-  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+  zip_open.c -- open zip archive by name
+  Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -52,7 +52,7 @@ 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 *,
+static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, unsigned char *,
                                 int, int, struct zip_error *);
 
 \f
@@ -61,24 +61,12 @@ ZIP_EXTERN(struct zip *)
 zip_open(const char *fn, int flags, int *zep)
 {
     FILE *fp;
-    struct zip *za;
-    struct zip_cdir *cdir;
-    int i;
-    off_t len;
-
-    if (flags & ZIP_OVERWRITE) {
-       return _zip_allocate_new(fn, zep);
-    }
-
+    
     switch (_zip_file_exists(fn, flags, zep)) {
     case -1:
-                       if (!(flags & ZIP_OVERWRITE)) {
-                               return NULL;
-                       }
-
+       return NULL;
     case 0:
        return _zip_allocate_new(fn, zep);
-
     default:
        break;
     }
@@ -88,7 +76,23 @@ zip_open(const char *fn, int flags, int *zep)
        return NULL;
     }
 
-    fseeko(fp, 0, SEEK_END);
+    return _zip_open(fn, fp, flags, 0, zep);
+}
+
+\f
+
+struct zip *
+_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
+{
+    struct zip *za;
+    struct zip_cdir *cdir;
+    int i;
+    off_t len;
+
+    if (fseeko(fp, 0, SEEK_END) < 0) {
+       *zep = ZIP_ER_SEEK;
+       return NULL;
+    }
     len = ftello(fp);
 
     /* treat empty files as empty archives */
@@ -156,13 +160,13 @@ set_error(int *zep, struct zip_error *err, int ze)
    entries, or NULL if unsuccessful. */
 
 static struct zip_cdir *
-_zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
+_zip_readcdir(FILE *fp, off_t buf_offset, 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;
-    unsigned int left;
+    zip_uint32_t left;
 
     comlen = buf + buflen - eocd - EOCDLEN;
     if (comlen < 0) {
@@ -196,14 +200,24 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
     cd->comment = NULL;
     cd->comment_len = _zip_read2(&cdp);
 
+    if (((zip_uint64_t)cd->offset)+cd->size > buf_offset + (eocd-buf)) {
+       /* cdir spans past EOCD record */
+       _zip_error_set(error, ZIP_ER_INCONS, 0);
+       cd->nentry = 0;
+       _zip_cdir_free(cd);
+       return NULL;
+    }
+
     if ((comlen < cd->comment_len) || (cd->nentry != i)) {
        _zip_error_set(error, ZIP_ER_NOZIP, 0);
-       free(cd);
+       cd->nentry = 0;
+       _zip_cdir_free(cd);
        return NULL;
     }
     if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) {
        _zip_error_set(error, ZIP_ER_INCONS, 0);
-       free(cd);
+       cd->nentry = 0;
+       _zip_cdir_free(cd);
        return NULL;
     }
 
@@ -211,14 +225,15 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
        if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN,
                                             cd->comment_len, error))
            == NULL) {
-           free(cd);
+           cd->nentry = 0;
+           _zip_cdir_free(cd);
            return NULL;
        }
     }
 
-    if (cd->size < (unsigned int)(eocd-buf)) {
+    if (cd->offset >= buf_offset) {
        /* if buffer already read in, use it */
-       cdp = eocd - cd->size;
+       cdp = buf + (cd->offset - buf_offset);
        bufp = &cdp;
     }
     else {
@@ -234,20 +249,15 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
                _zip_error_set(error, ZIP_ER_SEEK, errno);
            else
                _zip_error_set(error, ZIP_ER_NOZIP, 0);
-           free(cd);
+           cd->nentry = 0;
+           _zip_cdir_free(cd);
            return NULL;
        }
     }
 
     left = cd->size;
     i=0;
-    do {
-       if (i == cd->nentry && left > 0) {
-           /* Infozip extension for more than 64k entries:
-              nentries wraps around, size indicates correct EOCD */
-           _zip_cdir_grow(cd, cd->nentry+0x10000, error);
-       }
-
+    while (i<cd->nentry && left > 0) {
        if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) {
            cd->nentry = i;
            _zip_cdir_free(cd);
@@ -255,7 +265,18 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
        }
        i++;
        
-    } while (i<cd->nentry);
+       if (i == cd->nentry && left > 0) {
+           /* Infozip extension for more than 64k entries:
+              nentries wraps around, size indicates correct EOCD */
+           if (_zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error) < 0) {
+               cd->nentry = i;
+               _zip_cdir_free(cd);
+               return NULL;
+           }
+       }
+    }
+
+    cd->nentry = i;
     
     return cd;
 }
@@ -434,12 +455,16 @@ _zip_allocate_new(const char *fn, int *zep)
        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;
+
+    if (fn == NULL)
+       za->zn = NULL;
+    else {
+       za->zn = strdup(fn);
+       if (!za->zn) {
+           _zip_free(za);
+           set_error(zep, NULL, ZIP_ER_MEMORY);
+           return NULL;
+       }
     }
     return za;
 }
@@ -481,6 +506,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
 {
     struct zip_cdir *cdir, *cdirnew;
     unsigned char *buf, *match;
+    off_t buf_offset;
     int a, best, buflen, i;
     struct zip_error zerr;
 
@@ -490,7 +516,8 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
        set_error(zep, NULL, ZIP_ER_SEEK);
        return NULL;
     }
-
+    buf_offset = ftello(fp);
+    
     /* 64k is too much for stack */
     if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) {
        set_error(zep, NULL, ZIP_ER_MEMORY);
@@ -516,7 +543,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
        /* 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,
+       if ((cdirnew=_zip_readcdir(fp, buf_offset, buf, match-1, buflen, flags,
                                   &zerr)) == NULL)
            continue;
 
index e40ab27674f61519bcb0e3bb76bece8339514d4b..6b5a0359172da7a0a86a078a372a735f07c87737 100644 (file)
 \f
 
 ZIP_EXTERN(int)
-zip_rename(struct zip *za, int idx, const char *name)
+zip_rename(struct zip *za, zip_uint64_t idx, const char *name)
 {
     const char *old_name;
     int old_is_dir, new_is_dir;
     
-    if (idx >= za->nentry || idx < 0 || name[0] == '\0') {
+    if (idx >= za->nentry || name[0] == '\0') {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
     if ((old_name=zip_get_name(za, idx, 0)) == NULL)
        return -1;
                                                                    
index ae69a86f632f1441b83f44e5c435e68090c0a74b..6dc3dd5ab508f18bafbe44c07f207ee12eb21345 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_replace.c -- replace file via callback function
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -38,9 +38,9 @@
 \f
 
 ZIP_EXTERN(int)
-zip_replace(struct zip *za, int idx, struct zip_source *source)
+zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source)
 {
-    if (idx < 0 || idx >= za->nentry || source == NULL) {
+    if (idx >= za->nentry || source == NULL) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
@@ -54,11 +54,18 @@ zip_replace(struct zip *za, int idx, struct zip_source *source)
 
 \f
 
-int
-_zip_replace(struct zip *za, int idx, const char *name,
+/* NOTE: Signed due to -1 on error.  See zip_add.c for more details. */
+
+zip_int64_t
+_zip_replace(struct zip *za, zip_uint64_t idx, const char *name,
             struct zip_source *source)
 {
-    if (idx == -1) {
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
+    if (idx == ZIP_UINT64_MAX) {
        if (_zip_entry_new(za) == NULL)
            return -1;
 
index c4bd070ddcde340078a93a2caaf4423506672750..3cd069c7577c9421d9caa048162354a41fe74f18 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_set_archive_comment.c -- set archive comment
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -50,6 +50,11 @@ zip_set_archive_comment(struct zip *za, const char *comment, int len)
        return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
     if (len > 0) {
        if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
            return -1;
index 20316e4614aa9a5a3ebf28ecac4e4b6f9cfc64e0..07bcfbe304d8591e8007f86034234222f9216d86 100644 (file)
 ZIP_EXTERN(int)
 zip_set_archive_flag(struct zip *za, int flag, int value)
 {
+    unsigned int new_flags;
+    
     if (value)
-       za->ch_flags |= flag;
+       new_flags = za->ch_flags | flag;
     else
-       za->ch_flags &= ~flag;
+       new_flags = za->ch_flags & ~flag;
+
+    if (new_flags == za->ch_flags)
+       return 0;
+
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
+    if ((flag & ZIP_AFL_RDONLY) && value
+       && (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
+       if (_zip_changed(za, NULL)) {
+           _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+           return -1;
+       }
+    }
+
+    za->ch_flags = new_flags;
 
     return 0;
 }
diff --git a/ext/zip/lib/zip_set_default_password.c b/ext/zip/lib/zip_set_default_password.c
new file mode 100644 (file)
index 0000000..c274d11
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+  zip_set_default_password.c -- set default password for decryption
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(int)
+zip_set_default_password(struct zip *za, const char *passwd)
+{
+    if (za == NULL)
+       return -1;
+
+    if (za->default_password)
+       free(za->default_password);
+    
+    if (passwd) {
+       if ((za->default_password=strdup(passwd)) == NULL) {
+           _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+           return -1;
+       }
+    }
+    else
+       za->default_password = NULL;
+
+    return 0;
+}
index 3d5dd6b5e3e68b82380c7e7a12656e7003699d32..5e63dc2730ad402461f10a7de3dfa15343e7dcb0 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_set_file_comment.c -- set comment for file in archive
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 \f
 
 ZIP_EXTERN(int)
-zip_set_file_comment(struct zip *za, int idx, const char *comment, int len)
+zip_set_file_comment(struct zip *za, zip_uint64_t idx,
+                    const char *comment, int len)
 {
     char *tmpcom;
 
-    if (idx < 0 || idx >= za->nentry
+    if (idx >= za->nentry
        || len < 0 || len > MAXCOMLEN
        || (len > 0 && comment == NULL)) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
     if (len > 0) {
        if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
            return -1;
diff --git a/ext/zip/lib/zip_set_file_extra.c b/ext/zip/lib/zip_set_file_extra.c
new file mode 100644 (file)
index 0000000..db829e2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+  zip_set_file_extra.c -- set extra field for file in archive
+  Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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 <stdlib.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN(int)
+zip_set_file_extra(struct zip *za, zip_uint64_t idx,
+                  const char *extra, int len)
+{
+    char *tmpext;
+
+    if (idx >= za->nentry
+       || len < 0 || len > MAXEXTLEN
+       || (len > 0 && extra == NULL)) {
+       _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+       return -1;
+    }
+
+    if (ZIP_IS_RDONLY(za)) {
+       _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+       return -1;
+    }
+
+    if (len > 0) {
+       if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL)
+           return -1;
+    }
+    else
+       tmpext = NULL;
+
+    free(za->entry[idx].ch_extra);
+    za->entry[idx].ch_extra = tmpext;
+    za->entry[idx].ch_extra_len = len;
+
+    return 0;
+}
index 5c7da3d7c51ff10d37517bbf47f4d3e4c962ffc4..2a90601bfec3537008dc31244a7dcf0179d3ab3d 100644 (file)
 \f
 
 int
-_zip_set_name(struct zip *za, int idx, const char *name)
+_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name)
 {
     char *s;
-    int i;
+    zip_int64_t i;
     
-    if (idx < 0 || idx >= za->nentry || name == NULL) {
+    if (idx >= za->nentry || name == NULL) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
index 867d3dfa3ed695d253d0293534b77d11fa2df20a..8c9154ce3c5ba8c59f25d1b25be961c7d8251915 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_source_buffer.c -- create zip data source from buffer
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -44,13 +44,12 @@ struct read_data {
     int freep;
 };
 
-static ssize_t read_data(void *state, void *data, size_t len,
-                        enum zip_source_cmd cmd);
+static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd);
 
 \f
 
 ZIP_EXTERN(struct zip_source *)
-zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
+zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep)
 {
     struct read_data *f;
     struct zip_source *zs;
@@ -58,7 +57,7 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
     if (za == NULL)
        return NULL;
 
-    if (len < 0 || (data == NULL && len > 0)) {
+    if (data == NULL && len > 0) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
     }
@@ -83,12 +82,12 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
 
 \f
 
-static ssize_t
-read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+static zip_int64_t
+read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
 {
     struct read_data *z;
     char *buf;
-    size_t n;
+    zip_uint64_t n;
 
     z = (struct read_data *)state;
     buf = (char *)data;
@@ -99,6 +98,8 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
        return 0;
        
     case ZIP_SOURCE_READ:
+       /* XXX: return error if (len > ZIP_INT64_MAX) */
+
        n = z->end - z->buf;
        if (n > len)
            n = len;
@@ -125,6 +126,11 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
            zip_stat_init(st);
            st->mtime = z->mtime;
            st->size = z->end - z->data;
+           st->comp_size = st->size;
+           st->comp_method = ZIP_CM_STORE;
+           st->encryption_method = ZIP_EM_NONE;
+           st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE
+               |ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
            
            return sizeof(*st);
        }
diff --git a/ext/zip/lib/zip_source_close.c b/ext/zip/lib/zip_source_close.c
new file mode 100644 (file)
index 0000000..a3bf7e5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+  zip_source_close.c -- close zip_source (stop reading)
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(void)
+zip_source_close(struct zip_source *src)
+{
+    if (!src->is_open)
+       return;
+
+    if (src->src == NULL)
+       (void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+    else {
+       (void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+       zip_source_close(src->src);
+    }
+    
+    src->is_open = 0;
+}
diff --git a/ext/zip/lib/zip_source_crc.c b/ext/zip/lib/zip_source_crc.c
new file mode 100644 (file)
index 0000000..7fd78f5
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+  zip_source_crc.c -- pass-through source that calculates CRC32 and size
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct crc {
+    int eof;
+    int validate;
+    int e[2];
+    zip_uint64_t size;
+    zip_uint32_t crc;
+};
+
+static zip_int64_t crc_read(struct zip_source *, void *, void *
+                           , zip_uint64_t, enum zip_source_cmd);
+
+\f
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_crc(struct zip *za, struct zip_source *src, int validate)
+{
+    struct crc *ctx;
+
+    if (src == NULL) {
+       _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+       return NULL;
+    }
+
+    if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
+       _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+       return NULL;
+    }
+
+    ctx->validate = validate;
+
+    return zip_source_layered(za, src, crc_read, ctx);
+}
+
+\f
+
+static zip_int64_t
+crc_read(struct zip_source *src, void *_ctx, void *data,
+        zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct crc *ctx;
+    zip_int64_t n;
+
+    ctx = (struct crc *)_ctx;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+       ctx->eof = 0;
+       ctx->crc = crc32(0, NULL, 0);
+       ctx->size = 0;
+
+       return 0;
+
+    case ZIP_SOURCE_READ:
+       if (ctx->eof || len == 0)
+           return 0;
+
+       if ((n=zip_source_read(src, data, len)) < 0)
+           return ZIP_SOURCE_ERR_LOWER;
+
+       if (n == 0) {
+           ctx->eof = 1;
+           if (ctx->validate) {
+               struct zip_stat st;
+
+               if (zip_source_stat(src, &st) < 0)
+                   return ZIP_SOURCE_ERR_LOWER;
+
+               if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
+                   ctx->e[0] = ZIP_ER_CRC;
+                   ctx->e[1] = 0;
+                   
+                   return -1;
+               }
+               if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
+                   ctx->e[0] = ZIP_ER_INCONS;
+                   ctx->e[1] = 0;
+                   
+                   return -1;
+               }
+           }
+       }
+       else {
+           ctx->size += n;
+           ctx->crc = crc32(ctx->crc, data, n);
+       }
+       return n;
+
+    case ZIP_SOURCE_CLOSE:
+       return 0;
+
+    case ZIP_SOURCE_STAT:
+       {
+           struct zip_stat *st;
+
+           st = (struct zip_stat *)data;
+
+           if (ctx->eof) {
+               /* XXX: Set comp_size, comp_method, encryption_method?
+                       After all, this only works for uncompressed data. */
+               st->size = ctx->size;
+               st->crc = ctx->crc;
+               st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC;
+           }
+       }
+       return 0;
+       
+    case ZIP_SOURCE_ERROR:
+       memcpy(data, ctx->e, sizeof(ctx->e));
+       return 0;
+
+    case ZIP_SOURCE_FREE:
+       free(ctx);
+       return 0;
+
+    default:
+       return -1;
+    }
+    
+}
diff --git a/ext/zip/lib/zip_source_deflate.c b/ext/zip/lib/zip_source_deflate.c
new file mode 100644 (file)
index 0000000..5d9c5e6
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+  zip_source_deflate.c -- deflate (de)compressoin routines
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct deflate {
+    int e[2];
+
+    int eof;
+    int mem_level;
+    zip_uint64_t size;
+    char buffer[BUFSIZE];
+    z_stream zstr;
+};
+
+static zip_int64_t compress_read(struct zip_source *, struct deflate *,
+                                void *, zip_uint64_t);
+static zip_int64_t decompress_read(struct zip_source *, struct deflate *,
+                                  void *, zip_uint64_t);
+static zip_int64_t deflate_compress(struct zip_source *, void *, void *,
+                                   zip_uint64_t, enum zip_source_cmd);
+static zip_int64_t deflate_decompress(struct zip_source *, void *, void *,
+                                     zip_uint64_t, enum zip_source_cmd);
+static void deflate_free(struct deflate *);
+
+\f
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_deflate(struct zip *za, struct zip_source *src,
+                  zip_uint16_t cm, int flags)
+{
+    struct deflate *ctx;
+    struct zip_source *s2;
+
+    if (src == NULL || cm != ZIP_CM_DEFLATE) {
+       _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+       return NULL;
+    }
+
+    if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
+       _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+       return NULL;
+    }
+
+    ctx->e[0] = ctx->e[1] = 0;
+    ctx->eof = 0;
+    if (flags & ZIP_CODEC_ENCODE) {
+       if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
+           ctx->mem_level = TORRENT_MEM_LEVEL;
+       else
+           ctx->mem_level = MAX_MEM_LEVEL;
+    }
+
+    if ((s2=zip_source_layered(za, src,
+                              ((flags & ZIP_CODEC_ENCODE)
+                               ? deflate_compress : deflate_decompress),
+                              ctx)) == NULL) {
+       deflate_free(ctx);
+       return NULL;
+    }
+
+    return s2;
+}
+
+\f
+
+static zip_int64_t
+compress_read(struct zip_source *src, struct deflate *ctx,
+             void *data, zip_uint64_t len)
+{
+    int end, ret;
+    zip_int64_t n;
+
+    if (ctx->e[0] != 0)
+       return -1;
+    
+    if (len == 0)
+       return 0;
+       
+    ctx->zstr.next_out = (Bytef *)data;
+    ctx->zstr.avail_out = len;
+
+    end = 0;
+    while (!end) {
+       ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
+
+       switch (ret) {
+       case Z_OK:
+       case Z_STREAM_END:
+           /* all ok */
+
+           if (ctx->zstr.avail_out == 0
+               || (ctx->eof && ctx->zstr.avail_in == 0))
+               end = 1;
+           break;
+
+       case Z_BUF_ERROR:
+           if (ctx->zstr.avail_in == 0) {
+               if (ctx->eof) {
+                   end = 1;
+                   break;
+               }
+
+               if ((n=zip_source_read(src, ctx->buffer,
+                                      sizeof(ctx->buffer))) < 0) {
+                   zip_source_error(src, ctx->e, ctx->e+1);
+                   end = 1;
+                   break;
+               }
+               else if (n == 0) {
+                   ctx->eof = 1;
+                   ctx->size = ctx->zstr.total_in;
+                   /* XXX: check against stat of src? */
+               }
+               else {
+                   ctx->zstr.next_in = (Bytef *)ctx->buffer;
+                   ctx->zstr.avail_in = n;
+               }
+               continue;
+           }
+           /* fallthrough */
+       case Z_NEED_DICT:
+       case Z_DATA_ERROR:
+       case Z_STREAM_ERROR:
+       case Z_MEM_ERROR:
+           ctx->e[0] = ZIP_ER_ZLIB;
+           ctx->e[1] = ret;
+
+           end = 1;
+           break;
+       }
+    }
+
+    if (ctx->zstr.avail_out < len)
+       return len - ctx->zstr.avail_out;
+
+    return (ctx->e[0] == 0) ? 0 : -1;
+}
+
+\f
+
+static zip_int64_t
+decompress_read(struct zip_source *src, struct deflate *ctx,
+               void *data, zip_uint64_t len)
+{
+    int end, ret;
+    zip_int64_t n;
+
+    if (ctx->e[0] != 0)
+       return -1;
+    
+    if (len == 0)
+       return 0;
+       
+    ctx->zstr.next_out = (Bytef *)data;
+    ctx->zstr.avail_out = len;
+
+    end = 0;
+    while (!end && ctx->zstr.avail_out) {
+       ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
+
+       switch (ret) {
+       case Z_OK:
+           break;
+           
+       case Z_STREAM_END:
+           ctx->eof = 1;
+           end = 1;
+           break;
+
+       case Z_BUF_ERROR:
+           if (ctx->zstr.avail_in == 0) {
+               if (ctx->eof) {
+                   end = 1;
+                   break;
+               }
+
+               if ((n=zip_source_read(src, ctx->buffer,
+                           sizeof(ctx->buffer))) < 0) {
+                   zip_source_error(src, ctx->e, ctx->e+1);
+                   end = 1;
+                   break;
+               }
+               else if (n == 0)
+                   ctx->eof = 1;
+               else {
+                   ctx->zstr.next_in = (Bytef *)ctx->buffer;
+                   ctx->zstr.avail_in = n;
+               }
+               continue;
+           }
+           /* fallthrough */
+       case Z_NEED_DICT:
+       case Z_DATA_ERROR:
+       case Z_STREAM_ERROR:
+       case Z_MEM_ERROR:
+           ctx->e[0] = ZIP_ER_ZLIB;
+           ctx->e[1] = ret;
+           end = 1;
+           break;
+       }
+    }
+
+    if (ctx->zstr.avail_out < len)
+       return len - ctx->zstr.avail_out;
+
+    return (ctx->e[0] == 0) ? 0 : -1;
+}
+
+\f
+
+static zip_int64_t
+deflate_compress(struct zip_source *src, void *ud, void *data,
+                zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct deflate *ctx;
+    int ret;
+
+    ctx = (struct deflate *)ud;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+       ctx->zstr.zalloc = Z_NULL;
+       ctx->zstr.zfree = Z_NULL;
+       ctx->zstr.opaque = NULL;
+       ctx->zstr.avail_in = 0;
+       ctx->zstr.next_in = NULL;
+       ctx->zstr.avail_out = 0;
+       ctx->zstr.next_out = NULL;
+
+       /* negative value to tell zlib not to write a header */
+       if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED,
+                             -MAX_WBITS, ctx->mem_level,
+                             Z_DEFAULT_STRATEGY)) != Z_OK) {
+           ctx->e[0] = ZIP_ER_ZLIB;
+           ctx->e[1] = ret;
+           return -1;
+       }
+
+       return 0;
+
+    case ZIP_SOURCE_READ:
+       return compress_read(src, ctx, data, len);
+
+    case ZIP_SOURCE_CLOSE:
+       deflateEnd(&ctx->zstr);
+       return 0;
+
+    case ZIP_SOURCE_STAT:
+       {
+           struct zip_stat *st;
+
+           st = (struct zip_stat *)data;
+
+           st->comp_method = ZIP_CM_DEFLATE;
+           st->valid |= ZIP_STAT_COMP_METHOD;
+           if (ctx->eof) {
+               st->comp_size = ctx->size;
+               st->valid |= ZIP_STAT_COMP_SIZE;
+           }
+           else
+               st->valid &= ~ZIP_STAT_COMP_SIZE;
+       }
+       return 0;
+
+    case ZIP_SOURCE_ERROR:
+       memcpy(data, ctx->e, sizeof(int)*2);
+       return sizeof(int)*2;
+
+    case ZIP_SOURCE_FREE:
+       deflate_free(ctx);
+       return 0;
+
+    default:
+       ctx->e[0] = ZIP_ER_INVAL;
+       ctx->e[1] = 0;
+       return -1;
+    }
+}
+
+\f
+
+static zip_int64_t
+deflate_decompress(struct zip_source *src, void *ud, void *data,
+                  zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct deflate *ctx;
+    zip_int64_t n;
+    int ret;
+
+    ctx = (struct deflate *)ud;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+       if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0)
+           return ZIP_SOURCE_ERR_LOWER;
+
+       ctx->zstr.zalloc = Z_NULL;
+       ctx->zstr.zfree = Z_NULL;
+       ctx->zstr.opaque = NULL;
+       ctx->zstr.next_in = (Bytef *)ctx->buffer;
+       ctx->zstr.avail_in = n;
+
+       /* negative value to tell zlib that there is no header */
+       if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
+           ctx->e[0] = ZIP_ER_ZLIB;
+           ctx->e[1] = ret;
+
+           return -1;
+       }
+       return 0;
+
+    case ZIP_SOURCE_READ:
+       return decompress_read(src, ctx, data, len);
+
+    case ZIP_SOURCE_CLOSE:
+       inflateEnd(&ctx->zstr);
+       return 0;
+
+    case ZIP_SOURCE_STAT:
+       {
+           struct zip_stat *st;
+
+           st = (struct zip_stat *)data;
+
+           st->comp_method = ZIP_CM_STORE;
+           if (st->comp_size > 0 && st->size > 0)
+               st->comp_size = st->size;
+       }
+       return 0;
+
+    case ZIP_SOURCE_ERROR:
+       if (len < sizeof(int)*2)
+           return -1;
+
+       memcpy(data, ctx->e, sizeof(int)*2);
+       return sizeof(int)*2;
+
+    case ZIP_SOURCE_FREE:
+       /* XXX: inflateEnd if close was not called */
+       free(ctx);
+       return 0;
+
+    default:
+       ctx->e[0] = ZIP_ER_INVAL;
+       ctx->e[1] = 0;
+       return -1;
+    }
+    
+}
+
+\f
+
+static void
+deflate_free(struct deflate *ctx)
+{
+    /* XXX: deflateEnd if close was not called */
+    free(ctx);
+}
diff --git a/ext/zip/lib/zip_source_error.c b/ext/zip/lib/zip_source_error.c
new file mode 100644 (file)
index 0000000..ffb4652
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+  zip_source_error.c -- get last error from zip_source
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(void)
+zip_source_error(struct zip_source *src, int *ze, int *se)
+{
+    int e[2];
+
+    if (src->src == NULL) {
+    }
+    else {
+       switch (src->error_source) {
+       case ZIP_LES_NONE:
+           if (src->src == NULL) {
+               if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
+                   e[0] = ZIP_ER_INTERNAL;
+                   e[1] = 0;
+               }
+           }
+           else
+               e[0] = e[1] = 0;
+           break;
+
+       case ZIP_LES_INVAL:
+           e[0] = ZIP_ER_INVAL;
+           e[1] = 0;
+           break;
+
+       case ZIP_LES_LOWER:
+           zip_source_error(src->src, ze, se);
+           return;
+
+       case ZIP_LES_UPPER:
+           if (src->cb.l(src->src, src->ud, e, sizeof(e),
+                         ZIP_SOURCE_ERROR) < 0) {
+               e[0] = ZIP_ER_INTERNAL;
+               e[1] = 0;
+           }
+           break;
+
+       default:
+           e[0] = ZIP_ER_INTERNAL;
+           e[1] = 0;
+       }
+    }
+
+    if (ze)
+       *ze = e[0];
+    if (se)
+       *se = e[1];
+}
index ab6466dcbd94bfbc9e92b738ef1915721b7d679f..681cc2f3ea64397f9c644f26139d78502e5cd6aa 100644 (file)
 \f
 
 ZIP_EXTERN(struct zip_source *)
-zip_source_file(struct zip *za, const char *fname, off_t start, off_t len)
+zip_source_file(struct zip *za, const char *fname, zip_uint64_t start,
+               zip_int64_t len)
 {
     if (za == NULL)
        return NULL;
 
-    if (fname == NULL || start < 0 || len < -1) {
+    if (fname == NULL || len < -1) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
     }
 
-    return _zip_source_file_or_p(za, fname, NULL, start, len);
+    return _zip_source_file_or_p(za, fname, NULL, start, len, 1, NULL);
 }
index 2a06a9f028eab018862b1b25229cded674524d80..4d896a4c01bfc081e778ae5e398d4f613deeb58c 100644 (file)
 struct read_file {
     char *fname;       /* name of file to copy from */
     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 closep;                /* close f */
+    struct zip_stat st;        /* stat information passed in */
+
+    zip_uint64_t off;  /* start offset of */
+    zip_int64_t len;   /* length of data to copy */
+    zip_int64_t remain;        /* bytes remaining to be copied */
     int e[2];          /* error codes */
 };
 
-static ssize_t read_file(void *state, void *data, size_t len,
+static zip_int64_t read_file(void *state, void *data, zip_uint64_t len,
                     enum zip_source_cmd cmd);
 
 \f
 
 ZIP_EXTERN(struct zip_source *)
-zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
+zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start,
+                zip_int64_t len)
 {
     if (za == NULL)
        return NULL;
@@ -66,14 +70,15 @@ zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
        return NULL;
     }
 
-    return _zip_source_file_or_p(za, NULL, file, start, len);
+    return _zip_source_file_or_p(za, NULL, file, start, len, 1, NULL);
 }
 
 \f
 
 struct zip_source *
 _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
-                     off_t start, off_t len)
+                     zip_uint64_t start, zip_int64_t len, int closep,
+                     const struct zip_stat *st)
 {
     struct read_file *f;
     struct zip_source *zs;
@@ -99,7 +104,12 @@ _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
     f->f = file;
     f->off = start;
     f->len = (len ? len : -1);
-    
+    f->closep = f->fname ? 1 : closep;
+    if (st)
+       memcpy(&f->st, st, sizeof(f->st));
+    else
+       zip_stat_init(&f->st);
+
     if ((zs=zip_source_function(za, read_file, f)) == NULL) {
        free(f);
        return NULL;
@@ -110,8 +120,8 @@ _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
 
 \f
 
-static ssize_t
-read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+static zip_int64_t
+read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
 {
     struct read_file *z;
     char *buf;
@@ -130,20 +140,33 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
            }
        }
 
-       if (fseeko(z->f, z->off, SEEK_SET) < 0) {
-           z->e[0] = ZIP_ER_SEEK;
-           z->e[1] = errno;
-           return -1;
+       if (z->closep) {
+           if (fseeko(z->f, (off_t)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:
+       /* XXX: return INVAL if len > size_t max */
        if (z->remain != -1)
            n = len > z->remain ? z->remain : len;
        else
            n = len;
-       
+
+       if (!z->closep) {
+           /* we might share this file with others, so let's be safe */
+           if (fseeko(z->f, (off_t)(z->off + z->len-z->remain),
+                      SEEK_SET) < 0) {
+               z->e[0] = ZIP_ER_SEEK;
+               z->e[1] = errno;
+               return -1;
+           }
+       }
+
        if ((i=fread(buf, 1, n, z->f)) < 0) {
            z->e[0] = ZIP_ER_READ;
            z->e[1] = errno;
@@ -164,34 +187,42 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
 
     case ZIP_SOURCE_STAT:
         {
-           struct zip_stat *st;
-           struct stat fst;
-           int err;
-           
-           if (len < sizeof(*st))
+           if (len < sizeof(z->st))
                return -1;
 
-           if (z->f)
-               err = fstat(fileno(z->f), &fst);
-           else
-               err = stat(z->fname, &fst);
-
-           if (err != 0) {
-               z->e[0] = ZIP_ER_READ; /* best match */
-               z->e[1] = errno;
-               return -1;
+           if (z->st.valid != 0)
+               memcpy(data, &z->st, sizeof(z->st));
+           else {
+               struct zip_stat *st;
+               struct stat fst;
+               int err;
+           
+               if (z->f)
+                   err = fstat(fileno(z->f), &fst);
+               else
+                   err = stat(z->fname, &fst);
+
+               if (err != 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;
+               st->valid |= ZIP_STAT_MTIME;
+               if (z->len != -1) {
+                   st->size = z->len;
+                   st->valid |= ZIP_STAT_SIZE;
+               }
+               else if ((fst.st_mode&S_IFMT) == S_IFREG) {
+                   st->size = fst.st_size;
+                   st->valid |= ZIP_STAT_SIZE;
+               }
            }
-
-           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);
+           return sizeof(z->st);
        }
 
     case ZIP_SOURCE_ERROR:
@@ -203,8 +234,8 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
 
     case ZIP_SOURCE_FREE:
        free(z->fname);
-       if (z->f)
-       fclose(z->f);
+       if (z->closep && z->f)
+           fclose(z->f);
        free(z);
        return 0;
 
index 293e7f7e114cdc77b2ae0e937a07273382835656..f71c71ed6c5779e166ae43bdc7b9f3632ee71ac8 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_source_free.c -- free zip data source
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 \f
 
 ZIP_EXTERN(void)
-zip_source_free(struct zip_source *source)
+zip_source_free(struct zip_source *src)
 {
-    if (source == NULL)
+    if (src == NULL)
        return;
 
-    (void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE);
+    if (src->is_open)
+       zip_source_close(src);
 
-    free(source);
+    if (src->src == NULL)
+       (void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_FREE);
+    else {
+       (void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
+       zip_source_free(src->src);
+    }
+
+    free(src);
 }
index fe3e82aa5ba29d80317c739bf944388f98480429..984b107f7baa6fecd85d8ef29f021c6eea76531f 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_source_function.c -- create zip data source from callback function
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
@@ -47,13 +47,32 @@ zip_source_function(struct zip *za, zip_source_callback zcb, void *ud)
     if (za == NULL)
        return NULL;
 
-    if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) {
-       _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+    if ((zs=_zip_source_new(za)) == NULL)
        return NULL;
-    }
 
-    zs->f = zcb;
+    zs->cb.f = zcb;
     zs->ud = ud;
     
     return zs;
 }
+
+\f
+
+struct zip_source *
+_zip_source_new(struct zip *za)
+{
+    struct zip_source *src;
+
+    if ((src=(struct zip_source *)malloc(sizeof(*src))) == NULL) {
+       _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+       return NULL;
+    }
+
+    src->src = NULL;
+    src->cb.f = NULL;
+    src->ud = NULL;
+    src->error_source = ZIP_LES_NONE;
+    src->is_open = 0;
+
+    return src;
+}
diff --git a/ext/zip/lib/zip_source_layered.c b/ext/zip/lib/zip_source_layered.c
new file mode 100644 (file)
index 0000000..86ed420
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+  zip_source_layered.c -- create layered source
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_layered(struct zip *za, struct zip_source *src,
+                  zip_source_layered_callback cb, void *ud)
+{
+    struct zip_source *zs;
+
+    if (za == NULL)
+       return NULL;
+
+    if ((zs=_zip_source_new(za)) == NULL)
+       return NULL;
+
+    zs->src = src;
+    zs->cb.l = cb;
+    zs->ud = ud;
+    
+    return zs;
+}
diff --git a/ext/zip/lib/zip_source_open.c b/ext/zip/lib/zip_source_open.c
new file mode 100644 (file)
index 0000000..2c768f7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+  zip_source_open.c -- open zip_source (prepare for reading)
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(int)
+zip_source_open(struct zip_source *src)
+{
+    zip_int64_t ret;
+
+    if (src->is_open) {
+       src->error_source = ZIP_LES_INVAL;
+       return -1;
+    }
+
+    if (src->src == NULL) {
+       if (src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_OPEN) < 0)
+           return -1;
+    }
+    else {
+       if (zip_source_open(src->src) < 0) {
+           src->error_source = ZIP_LES_LOWER;
+           return -1;
+       }
+
+       ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN);
+       
+       if (ret < 0) {
+           (void)zip_source_close(src->src);
+           
+           if (ret == ZIP_SOURCE_ERR_LOWER)
+               src->error_source = ZIP_LES_LOWER;
+           else
+               src->error_source = ZIP_LES_UPPER;
+           return -1;
+       }
+    }
+
+    src->is_open = 1;
+    
+    return 0;
+}
diff --git a/ext/zip/lib/zip_source_pkware.c b/ext/zip/lib/zip_source_pkware.c
new file mode 100644 (file)
index 0000000..83b5cc5
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+  zip_source_pkware.c -- Traditional PKWARE de/encryption routines
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct trad_pkware {
+    int e[2];
+
+    zip_uint32_t key[3];
+};
+
+#define HEADERLEN      12
+#define KEY0           305419896
+#define KEY1           591751049
+#define KEY2           878082192
+
+static const uLongf *crc = NULL;
+
+#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+\f
+
+static void decrypt(struct trad_pkware *, zip_uint8_t *,
+                   const zip_uint8_t *, zip_uint64_t, int);
+static int decrypt_header(struct zip_source *, struct trad_pkware *);
+static zip_int64_t pkware_decrypt(struct zip_source *, void *, void *,
+                                 zip_uint64_t, enum zip_source_cmd);
+static void pkware_free(struct trad_pkware *);
+
+\f
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_pkware(struct zip *za, struct zip_source *src,
+                 zip_uint16_t em, int flags, const char *password)
+{
+    struct trad_pkware *ctx;
+    struct zip_source *s2;
+
+    if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
+       _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+       return NULL;
+    }
+    if (flags & ZIP_CODEC_ENCODE) {
+       _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+       return NULL;
+    }
+
+    if (crc == NULL)
+       crc = get_crc_table();
+
+    if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
+       _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+       return NULL;
+    }
+
+    ctx->e[0] = ctx->e[1] = 0;
+
+    ctx->key[0] = KEY0;
+    ctx->key[1] = KEY1;
+    ctx->key[2] = KEY2;
+    decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
+
+    if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
+       pkware_free(ctx);
+       return NULL;
+    }
+
+    return s2;
+}
+
+\f
+
+static void
+decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
+       zip_uint64_t len, int update_only)
+{
+    zip_uint16_t tmp;
+    zip_uint64_t i;
+    Bytef b;
+
+    for (i=0; i<len; i++) {
+       b = in[i];
+
+       if (!update_only) {
+           /* decrypt next byte */
+           tmp = ctx->key[2] | 2;
+           tmp = (tmp * (tmp ^ 1)) >> 8;
+           b ^= tmp;
+       }
+
+       /* store cleartext */
+       if (out)
+           out[i] = b;
+
+       /* update keys */
+       ctx->key[0] = CRC32(ctx->key[0], b);
+       ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
+       b = ctx->key[1] >> 24;
+       ctx->key[2] = CRC32(ctx->key[2], b);
+    }
+}
+
+\f
+
+static int
+decrypt_header(struct zip_source *src, struct trad_pkware *ctx)
+{
+    zip_uint8_t header[HEADERLEN];
+    struct zip_stat st;
+    zip_int64_t n;
+    unsigned short dostime, dosdate;
+
+    if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
+       zip_source_error(src, ctx->e, ctx->e+1);
+       return -1;
+    }
+    
+    if (n != HEADERLEN) {
+       ctx->e[0] = ZIP_ER_EOF;
+       ctx->e[1] = 0;
+       return -1;
+    }
+
+    decrypt(ctx, header, header, HEADERLEN, 0);
+
+    if (zip_source_stat(src, &st) < 0) {
+       /* stat failed, skip password validation */
+       return 0;
+    }
+
+    _zip_u2d_time(st.mtime, &dostime, &dosdate);
+
+    if (header[HEADERLEN-1] != st.crc>>24
+       && header[HEADERLEN-1] != dostime>>8) {
+       ctx->e[0] = ZIP_ER_WRONGPASSWD;
+       ctx->e[1] = 0;
+       return -1;
+    }
+
+    return 0;
+}
+
+\f
+
+static zip_int64_t
+pkware_decrypt(struct zip_source *src, void *ud, void *data,
+              zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct trad_pkware *ctx;
+    zip_int64_t n;
+
+    ctx = (struct trad_pkware *)ud;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+       if (decrypt_header(src, ctx) < 0)
+           return -1;
+       return 0;
+
+    case ZIP_SOURCE_READ:
+       if ((n=zip_source_read(src, data, len)) < 0)
+           return ZIP_SOURCE_ERR_LOWER;
+
+       decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
+               0);
+       return n;
+
+    case ZIP_SOURCE_CLOSE:
+       return 0;
+
+    case ZIP_SOURCE_STAT:
+       {
+           struct zip_stat *st;
+
+           st = (struct zip_stat *)data;
+
+           st->encryption_method = ZIP_EM_NONE;
+           st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
+           /* XXX: deduce HEADERLEN from size for uncompressed */
+           if (st->valid & ZIP_STAT_COMP_SIZE)
+               st->comp_size -= HEADERLEN;
+       }
+       return 0;
+
+    case ZIP_SOURCE_ERROR:
+       memcpy(data, ctx->e, sizeof(int)*2);
+       return sizeof(int)*2;
+
+    case ZIP_SOURCE_FREE:
+       pkware_free(ctx);
+       return 0;
+
+    default:
+       ctx->e[0] = ZIP_ER_INVAL;
+       ctx->e[1] = 0;
+       return -1;
+    }
+}
+
+\f
+
+static void
+pkware_free(struct trad_pkware *ctx)
+{
+    free(ctx);
+}
diff --git a/ext/zip/lib/zip_source_pop.c b/ext/zip/lib/zip_source_pop.c
new file mode 100644 (file)
index 0000000..4060938
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+  zip_source_pop.c -- pop top layer from zip data source
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include <stdlib.h>
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(struct zip_source *)
+zip_source_pop(struct zip_source *src)
+{
+    struct zip_source *lower;
+
+    if (src == NULL)
+       return NULL;
+
+    lower = src->src;
+
+    if (lower == NULL)
+       zip_source_free(src);
+    else {
+       if (src->is_open)
+           (void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+       (void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
+       
+       free(src);
+    }
+
+    return lower;
+}
diff --git a/ext/zip/lib/zip_source_read.c b/ext/zip/lib/zip_source_read.c
new file mode 100644 (file)
index 0000000..7246f9c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+  zip_source_read.c -- read data from zip_source
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(zip_int64_t)
+zip_source_read(struct zip_source *src, void *data, zip_uint64_t len)
+{
+    zip_int64_t ret;
+
+    if (!src->is_open || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) {
+       src->error_source = ZIP_LES_INVAL;
+       return -1;
+    }
+
+    if (src->src == NULL)
+       return src->cb.f(src->ud, data, len, ZIP_SOURCE_READ);
+
+    ret = src->cb.l(src->src, src->ud, data, len, ZIP_SOURCE_READ);
+
+    if (ret < 0) {
+       if (ret == ZIP_SOURCE_ERR_LOWER)
+           src->error_source = ZIP_LES_LOWER;
+       else
+           src->error_source = ZIP_LES_UPPER;
+       return -1;
+    }
+    
+    return ret;
+}
diff --git a/ext/zip/lib/zip_source_stat.c b/ext/zip/lib/zip_source_stat.c
new file mode 100644 (file)
index 0000000..662779e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+  zip_source_stat.c -- get meta information from zip_source
+  Copyright (C) 2009 Dieter Baron and Thomas Klausner
+
+  This file is part of libzip, a library to manipulate ZIP archives.
+  The authors can be contacted at <libzip@nih.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.
+*/
+
+\f
+
+#include "zipint.h"
+
+\f
+
+ZIP_EXTERN(int)
+zip_source_stat(struct zip_source *src, struct zip_stat *st)
+{
+    zip_int64_t ret;
+
+    if (st == NULL) {
+       src->error_source = ZIP_LES_INVAL;
+       return -1;
+    }
+
+    if (src->src == NULL) {
+       if (src->cb.f(src->ud, st, sizeof(*st), ZIP_SOURCE_STAT) < 0)
+           return -1;
+       return 0;
+    }
+
+    if (zip_source_stat(src->src, st) < 0) {
+       src->error_source = ZIP_LES_LOWER;
+       return -1;
+    }
+
+    ret = src->cb.l(src->src, src->ud, st, sizeof(*st), ZIP_SOURCE_STAT);
+
+    if (ret < 0) {
+       if (ret == ZIP_SOURCE_ERR_LOWER)
+           src->error_source = ZIP_LES_LOWER;
+       else
+           src->error_source = ZIP_LES_UPPER;
+       return -1;
+    }
+    
+    return 0;
+}
index 58119dd39f34cf717627c485296c896d6a729d87..228803c717f6aeb86538f0c3625827e4d5496d1f 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_source_zip.c -- create data source from zip file
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 struct read_zip {
     struct zip_file *zf;
     struct zip_stat st;
-    off_t off, len;
+    zip_uint64_t off;
+    zip_int64_t len;
 };
 
-static ssize_t read_zip(void *st, void *data, size_t len,
+static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len,
                        enum zip_source_cmd cmd);
 
 \f
 
 ZIP_EXTERN(struct zip_source *)
-zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
-              off_t start, off_t len)
+zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx,
+              int flags, zip_uint64_t start, zip_int64_t len)
 {
     struct zip_error error;
     struct zip_source *zs;
@@ -62,7 +63,7 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
     if (za == NULL)
        return NULL;
 
-    if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
+    if (srcza == NULL || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
     }
@@ -115,12 +116,13 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
 
 \f
 
-static ssize_t
-read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+static zip_int64_t
+read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
 {
     struct read_zip *z;
     char b[8192], *buf;
-    int i, n;
+    int i;
+    zip_uint64_t n;
 
     z = (struct read_zip *)state;
     buf = (char *)data;
index 26425206ca3323b1d3b5a07d974e454c30a02b12..8faa8cc39497284e4f0ce421f3055610b545953b 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_stat_index.c -- get information about file by index
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 \f
 
 ZIP_EXTERN(int)
-zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
+zip_stat_index(struct zip *za, zip_uint64_t index, int flags,
+              struct zip_stat *st)
 {
     const char *name;
     
-    if (index < 0 || index >= za->nentry) {
+    if (index >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
@@ -53,8 +54,7 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
 
     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) {
+       if (zip_source_stat(za->entry[index].source, st) < 0) {
            _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
            return -1;
        }
@@ -64,7 +64,9 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
            _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
            return -1;
        }
-       
+
+       zip_stat_init(st);
+
        st->crc = za->cdir->entry[index].crc;
        st->size = za->cdir->entry[index].uncomp_size;
        st->mtime = za->cdir->entry[index].last_mod;
@@ -80,11 +82,13 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
        }
        else
            st->encryption_method = ZIP_EM_NONE;
-       /* st->bitflags = za->cdir->entry[index].bitflags; */
+       st->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
+           |ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
     }
 
     st->index = index;
     st->name = name;
+    st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME;
     
     return 0;
 }
index cb451dc3bcaad35d25cafa4729077cf6accb7b7d..74e1ffd0b0dceabf543e1c09368c72e4f71dbc36 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_stat_init.c -- initialize struct zip_stat.
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 ZIP_EXTERN(void)
 zip_stat_init(struct zip_stat *st)
 {
+    st->valid = 0;
     st->name = NULL;
-    st->index = -1;
+    st->index = ZIP_UINT64_MAX;
     st->crc = 0;
     st->mtime = (time_t)-1;
-    st->size = -1;
-    st->comp_size = -1;
+    st->size = 0;
+    st->comp_size = 0;
     st->comp_method = ZIP_CM_STORE;
     st->encryption_method = ZIP_EM_NONE;
 }
index 7366c9cc7164e0bcf1e38424ca8a93f0f9241fb6..550e8b99031f22153f769d35013f8e0d7c0470ec 100644 (file)
@@ -40,7 +40,7 @@
 \f
 
 ZIP_EXTERN(int)
-zip_unchange(struct zip *za, int idx)
+zip_unchange(struct zip *za, zip_uint64_t idx)
 {
     return _zip_unchange(za, idx, 0);
 }
@@ -48,11 +48,11 @@ zip_unchange(struct zip *za, int idx)
 \f
 
 int
-_zip_unchange(struct zip *za, int idx, int allow_duplicates)
+_zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates)
 {
     int i;
     
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
     }
@@ -72,6 +72,9 @@ _zip_unchange(struct zip *za, int idx, int allow_duplicates)
        za->entry[idx].ch_filename = NULL;
     }
 
+    free(za->entry[idx].ch_extra);
+    za->entry[idx].ch_extra = NULL;
+    za->entry[idx].ch_extra_len = -1;
     free(za->entry[idx].ch_comment);
     za->entry[idx].ch_comment = NULL;
     za->entry[idx].ch_comment_len = -1;
index fe30a5ad2c16bee742279ed33e54123044d539ec..ca2b67854435a065ef1a334280e7bca060b9b72d 100644 (file)
@@ -1,6 +1,6 @@
 /*
   zip_unchange_archive.c -- undo global changes to ZIP archive
-  Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
index 6fe89f4fb2b785958198834bee3da9320531e65e..7dd93b768a87aab4e7628c51145f76a83b773657 100644 (file)
@@ -43,8 +43,7 @@ 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);
+       zip_source_free(ze->source);
        ze->source = NULL;
     }
     
diff --git a/ext/zip/lib/zipconf.h b/ext/zip/lib/zipconf.h
new file mode 100644 (file)
index 0000000..b65d91e
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _HAD_ZIPCONF_H
+#define _HAD_ZIPCONF_H
+
+/*
+   zipconf.h -- platform specific include file
+
+   This file was generated automatically by ./make_zipconf.sh
+   based on ../config.h.
+ */
+
+#define LIBZIP_VERSION "0.10.1"
+#define LIBZIP_VERSION_MAJOR 0
+#define LIBZIP_VERSION_MINOR 10
+#define LIBZIP_VERSION_MICRO 0
+
+#include <inttypes.h>
+
+typedef int8_t zip_int8_t;
+#define ZIP_INT8_MIN INT8_MIN
+#define ZIP_INT8_MAX INT8_MAX
+
+typedef uint8_t zip_uint8_t;
+#define ZIP_UINT8_MAX UINT8_MAX
+
+typedef int16_t zip_int16_t;
+#define ZIP_INT16_MIN INT16_MIN
+#define ZIP_INT16_MAX INT16_MAX
+
+typedef uint16_t zip_uint16_t;
+#define ZIP_UINT16_MAX UINT16_MAX
+
+typedef int32_t zip_int32_t;
+#define ZIP_INT32_MIN INT32_MIN
+#define ZIP_INT32_MAX INT32_MAX
+
+typedef uint32_t zip_uint32_t;
+#define ZIP_UINT32_MAX UINT32_MAX
+
+typedef int64_t zip_int64_t;
+#define ZIP_INT64_MIN INT64_MIN
+#define ZIP_INT64_MAX INT64_MAX
+
+typedef uint64_t zip_uint64_t;
+#define ZIP_UINT64_MAX UINT64_MAX
+
+
+#endif /* zipconf.h */
index d72ed144d422d6364d6da4be3a8c045ace4993a8..67fae80ade57d9663c774bf72dd48c99dd0d58fd 100644 (file)
@@ -3,7 +3,7 @@
 
 /*
   zipint.h -- internal declarations.
-  Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
 
   This file is part of libzip, a library to manipulate ZIP archives.
   The authors can be contacted at <libzip@nih.at>
 
 #include "zip.h"
 
+#ifndef HAVE_FSEEKO
+#define fseeko(s, o, w)        (fseek((s), (long int)(o), (w)))
+#endif
+
+#ifndef HAVE_FTELLO
+#define ftello(s)      ((long)ftell((s)))
+#endif
+
+#ifndef HAVE_MKSTEMP
+int _zip_mkstemp(char *);
+#define mkstemp _zip_mkstemp
+#endif
+
 #ifdef PHP_WIN32
 #include <windows.h>
 #include <wchar.h>
 #define _zip_rename(s, t)                                              \
        (!MoveFileExA((s), (t),                                         \
                     MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
+
+/* for dup(), close(), etc. */
+#include <io.h>
+
+#if !defined(HAVE_OPEN)
+#if defined(HAVE__OPEN)
+#define open(a, b, c)  _open((a), (b))
+#endif
+#endif
+
 #else
 #define _zip_rename    rename
 #endif
 # define strcmpi strcasecmp 
 #endif
 
-#ifndef HAVE_FSEEKO
-#define fseeko(s, o, w)        (fseek((s), (long int)(o), (w)))
-#endif
-#ifndef HAVE_FTELLO
-#define ftello(s)      ((long)ftell((s)))
-#endif
 
 \f
 
 #define LENTRYSIZE          30
 #undef MAXCOMLEN /* defined as 19 on BSD for max command name */
 #define MAXCOMLEN        65536
+#define MAXEXTLEN        65536
 #define EOCDLEN             22
 #define CDBUFSIZE       (MAXCOMLEN+EOCDLEN)
 #define BUFSIZE                8192
 
 \f
 
+/* This section contains API that won't materialize like this.  It's
+   placed in the internal section, pending cleanup. */
+
+typedef struct zip_source *(*zip_compression_implementation)(struct zip *,
+                                                    struct zip_source *,
+                                                    zip_uint16_t, int);
+typedef struct zip_source *(*zip_encryption_implementation)(struct zip *,
+                                                   struct zip_source *,
+                                                   zip_uint16_t, int,
+                                                   const char *);
+
+ZIP_EXTERN(zip_compression_implementation) zip_get_compression_implementation(
+    zip_uint16_t);
+ZIP_EXTERN(zip_encryption_implementation) zip_get_encryption_implementation(
+    zip_uint16_t);
+
+
+\f
+
+/* This section contains API that is of limited use until support for
+   user-supplied compression/encryption implementation is finished.
+   Thus we will keep it private for now. */
+
+typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *,
+                                                  void *, zip_uint64_t,
+                                                  enum zip_source_cmd);
+
+ZIP_EXTERN(void) zip_source_close(struct zip_source *);
+ZIP_EXTERN(struct zip_source *)zip_source_crc(struct zip *, struct zip_source *,
+                                            int);
+ZIP_EXTERN(struct zip_source *)zip_source_deflate(struct zip *,
+                                                struct zip_source *,
+                                                zip_uint16_t, int);
+ZIP_EXTERN(void) zip_source_error(struct zip_source *, int *, int *);
+ZIP_EXTERN(struct zip_source *)zip_source_layered(struct zip *,
+                                                struct zip_source *,
+                                                zip_source_layered_callback,
+                                                void *);
+ZIP_EXTERN(int) zip_source_open(struct zip_source *);
+ZIP_EXTERN(struct zip_source *)zip_source_pkware(struct zip *,
+                                               struct zip_source *,
+                                               zip_uint16_t, int,
+                                               const char *);
+ZIP_EXTERN(zip_int64_t) zip_source_read(struct zip_source *, void *,
+                                      zip_uint64_t);
+ZIP_EXTERN(int) zip_source_stat(struct zip_source *, struct zip_stat *);
+
+
+/* This function will probably remain private.  It is not needed to
+   implement compression/encryption routines.  (We should probably
+   rename it to _zip_source_pop.) */
+
+ZIP_EXTERN(struct zip_source *)zip_source_pop(struct zip_source *);
+
+\f
+
 /* 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 */
+/* error source for layered sources */
 
-#define ZIP_ZF_EOF     1 /* EOF reached */
-#define ZIP_ZF_DECOMP  2 /* decompress data */
-#define ZIP_ZF_CRC     4 /* compute and compare CRC */
+enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
 
 /* directory entry: general purpose bit flags */
 
@@ -114,12 +186,14 @@ struct zip {
     unsigned int flags;                /* archive global flags */
     unsigned int ch_flags;     /* changed archive global flags */
 
+    char *default_password;    /* password used when no other supplied */
+
     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 */
+    zip_uint64_t nentry;       /* number of entries */
+    zip_uint64_t 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 */
@@ -131,18 +205,8 @@ struct zip {
 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 */
-    off_t 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;
+    int eof;
+    struct zip_source *src;    /* data source */
 };
 
 /* zip archive directory entry (central or local) */
@@ -183,8 +247,14 @@ struct zip_cdir {
 \f
 
 struct zip_source {
-    zip_source_callback f;
+    struct zip_source *src;
+    union {
+       zip_source_callback f;
+       zip_source_layered_callback l;
+    } cb;
     void *ud;
+    enum zip_les error_source;
+    int is_open;
 };
 
 /* entry in zip archive directory */
@@ -193,6 +263,8 @@ struct zip_entry {
     enum zip_state state;
     struct zip_source *source;
     char *ch_filename;
+    char *ch_extra;
+    int ch_extra_len;
     char *ch_comment;
     int ch_comment_len;
 };
@@ -209,6 +281,8 @@ extern const int _zip_err_type[];
                        ((x)->state == ZIP_ST_REPLACED  \
                         || (x)->state == ZIP_ST_ADDED)
 
+#define ZIP_IS_RDONLY(za)      ((za)->ch_flags & ZIP_AFL_RDONLY)
+
 \f
 
 int _zip_cdir_compute_crc(struct zip *, uLong *);
@@ -220,7 +294,7 @@ 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 *);
+                    zip_uint32_t *, int, struct zip_error *);
 void _zip_dirent_torrent_normalize(struct zip_dirent *);
 int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *);
 
@@ -234,6 +308,7 @@ 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);
+void _zip_error_set_from_source(struct zip_error *, struct zip_source *);
 const char *_zip_error_strerror(struct zip_error *);
 
 int _zip_file_fillbuf(void *, size_t, struct zip_file *);
@@ -241,20 +316,27 @@ unsigned int _zip_file_get_offset(struct zip *, int);
 
 int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *);
 
+struct zip *_zip_open(const char *, FILE *, int, int, int *);
+
 struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *,
-                                        off_t, off_t);
+                                        zip_uint64_t, zip_int64_t, int,
+                                        const struct zip_stat *);
+struct zip_source *_zip_source_new(struct zip *);
 
+int _zip_changed(struct zip *, int *);
 void _zip_free(struct zip *);
-const char *_zip_get_name(struct zip *, int, int, struct zip_error *);
+const char *_zip_get_name(struct zip *, zip_uint64_t, 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);
+zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *,
+                        struct zip_source *);
+int _zip_set_name(struct zip *, zip_uint64_t, const char *);
+void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
+int _zip_unchange(struct zip *, zip_uint64_t, int);
 void _zip_unchange_data(struct zip_entry *);
 
 #endif /* zipint.h */