Merge 0.10.1 into head. Bump head version to 0.10b to diffentiate bugfixed version.
diff --git a/.hgignore b/.hgignore index d9a7c49..5d80ffb 100644 --- a/.hgignore +++ b/.hgignore
@@ -22,15 +22,21 @@ ^regress/add_from_file$ ^regress/add_from_filep$ ^regress/add_from_zip$ +^regress/cp437$ +^regress/encoding$ ^regress/encrypt$ +^regress/fopen_unchanged$ ^regress/fread$ ^regress/get_comment$ +^regress/modify$ ^regress/name_locate$ -^regress/open$ +^regress/rename$ ^regress/set_comment_all$ ^regress/set_comment_localonly$ ^regress/set_comment_removeglobal$ ^regress/set_comment_revert$ +^regress/set_compression$ +^regress/stat_index$ ^regress/tryopen$ ^src/zipcmp$ ^src/zipmerge$
diff --git a/.hgtags b/.hgtags index 86c1fde..32284a2 100644 --- a/.hgtags +++ b/.hgtags
@@ -3,3 +3,4 @@ 305c067cba3a04d11e95c7cd1e0ae55d662620ee rel-0-9-1 a523a1da577163bb4255d0f670444964bbf9d43e rel-0-9-2 a3023e707845ef0d87b9cb33cb3c330afbb5a3c3 rel-0-9-3 +70e00fa4feefae33235b72c072c30c90f76b8204 rel-0-10
diff --git a/CMakeLists.txt b/CMakeLists.txt index 50bc082..980eb77 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -20,7 +20,7 @@ SET(PACKAGE_NAME ${PACKAGE}) SET(PACKAGE_VERSION_MAJOR "0") SET(PACKAGE_VERSION_MINOR "10") -SET(PACKAGE_VERSION_PATCH "1") +SET(PACKAGE_VERSION_PATCH "b") SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH}") SET(PACKAGE_VERSION ${VERSION}) SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") @@ -45,12 +45,16 @@ CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H_LIBZIP) CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H_LIBZIP) CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H_LIBZIP) +CHECK_TYPE_SIZE(__int8 __INT8_LIBZIP) CHECK_TYPE_SIZE(int8_t INT8_T_LIBZIP) CHECK_TYPE_SIZE(uint8_t UINT8_T_LIBZIP) +CHECK_TYPE_SIZE(__int16 __INT16_LIBZIP) CHECK_TYPE_SIZE(int16_t INT16_T_LIBZIP) CHECK_TYPE_SIZE(uint16_t UINT16_T_LIBZIP) +CHECK_TYPE_SIZE(__int32 __INT32_LIBZIP) CHECK_TYPE_SIZE(int32_t INT32_T_LIBZIP) CHECK_TYPE_SIZE(uint32_t UINT32_T_LIBZIP) +CHECK_TYPE_SIZE(__int64 __INT64_LIBZIP) CHECK_TYPE_SIZE(int64_t INT64_T_LIBZIP) CHECK_TYPE_SIZE(uint64_t UINT64_T_LIBZIP) CHECK_TYPE_SIZE("short" SHORT_LIBZIP) @@ -66,6 +70,10 @@ MESSAGE(FATAL_ERROR "-- ZLIB version too old, please install at least v1.1.2") ENDIF(NOT HAVE_ZEXPORT) +IF(MSVC) +ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNING") +ENDIF(MSVC) + # Targets ADD_SUBDIRECTORY(lib) ADD_SUBDIRECTORY(man)
diff --git a/NEWS b/NEWS index 02081c6..c9923a9 100644 --- a/NEWS +++ b/NEWS
@@ -1,5 +1,15 @@ -0.10.1 [2012/03/20] +0.xx [20xx/xx/xx] +* Add UTF-8 support for file names, file comments, and archive comments +* Added zip_discard() +* Added ZIP_TRUNCATE for zip_open() +* Added zip_set_compression() +* Added zip_get_file_extra()/zip_set_file_extra() +* Use gcc4's visibility __attribute__ +* More changes for Windows support +* Additional test cases + +0.10.1 [2012/03/20] * Fixed CVE-2012-1162 * Fixed CVE-2012-1163
diff --git a/THANKS b/THANKS index 601d3cf..3cd6610 100644 --- a/THANKS +++ b/THANKS
@@ -4,13 +4,16 @@ Thanks to these people for suggestions, testing, and bug reports: Alexander Galanin <al@galanin.nnov.ru> +Alexandr Shadchin <alexandr.shadchin@gmail.com> Andrew Brampton <brampton@gmail.com> +François Simon <AT.GFI.Francois.SIMON@sesam-vitale.fr> Heiko Hund <heiko@ist.eigentlich.net> Joel Ebrahimi <joel.ebrahimi@gmail.com> Jono Spiro <jono.spiro@gmail.com> Mikhail Gusarov <dottedmag@dottedmag.net>. Oliver Kaiser <under.northern.sky@googlemail.com> Patrick Spendrin <ps_ml@gmx.de> +Paul Sheppard <shepsoft@googlemail.com> Pierre Joye <pierre.php@gmail.com> Rick Carback <carback1@umbc.edu> Roberto Tirabassi <rtirabassi@3di.it> @@ -18,3 +21,5 @@ Stephen Bryant <steve@bawue.de> Tarmo Pikaro <tapika@yahoo.com> Timo Warns <warns@pre-sense.de> +Tom Callaway <tcallawa@redhat.com> +Vassili Courzakis <vcoxvco@googlemail.com>
diff --git a/TODO b/TODO index add2bf5..75ce36d 100644 --- a/TODO +++ b/TODO
@@ -1,76 +1,97 @@ -! [doc] zip_source_function: mention that stat is called after close -! [cleanup] get rid of zip_get_{compression,encryption}_implementation -! [compat] test calls against old API -+ [portability] use _setmode(_fileno(fp), _O_BINARY); where present -+ [bug] fix permissions of new file to match old one -+ [bug] _zip_checkcons return value can overflow -+ [bug] _zip_u2d_time: handle localtime(3) failure -+ [bug] missing -Wl,-R in pkg-config file -+ [cleanup] use zip_*int*_t internally -+ [cleanup] don't make zip_source_zip go through zip_fread -+ [bug] set "version of encoding software" to 2.0 -+ [bug?] keep extended local headers when copying? -- [cleanup] remove now useless check of fseek -- [consistency check] check that local headers come before central dir -- [consistency] check arguments for every entry point into libzip -- [bug] zip_open: consistency check: check data descriptor -- [bug] do not compress if storing is smaller -- [bug] zip_open: check whether file can be created and fail if not -- [bug] check for limits imposed by format (central dir size, file size, ...) -- [feature] handle zip_open/zip_close "race" for new files -- [feature] support streaming output (creating new archive to e.g. stdout) -- [feature] add functions to: - . set compression method for new/changed entry - . set last modification time for entry - . read/set EAs - . parse/create some EAs? - . read/set ASCII file flag -+ [test] run regression tests also from CMake framework -- [test] rename deleted (fails) -- [test] rename file to dir/ and vice versa (fails) ------------------------------------------------- API issues -- character encoding in file names and comments (ZIP_AFL_UTF8, see mail) -- parameters for compression/crypt implementations (extra function) - ZIP_CM_DEFLATE/ZIP_CM_BZIP2: compression level - memlevel? -* compression/crypt implementations: how to set error code on failure -+ compression/crypt error messages a la ZIP_ER_ZLIB (no detailed info passing) -* I/O methods ------------------------------------------------- API ideas +API Plans +========= + +Compression +----------- +int zip_set_file_compression(struct zip *archive, zip_uint64_t idx, + zip_uint16_t method, zip_uint32_t flags); + flags: 0-15: compression ratio (0: fast, 15: best) + 16: default + higher bits: method specific + +Encryption +---------- struct zip *zip_open_encrypted(const char *path, int flags, const char *password, int *errorp); -int zip_set_file_compression(struct zip *archive, zip_uint64_t idx, - zip_uint16_t method, zip_uint32_t flags); - flags: 0-15: compression ratio (0: fast, 15: best) - 16: default - higher bits: method specific int zip_set_encryption(struct zip *archive, zip_uint64_t idx, zip_uint16_t method, const char *password); void zip_set_archive_encryption(struct zip *archive, zip_uint16_t method, const char *password); -struct zip_source *zip_source_writable(struct zip *archive); -zip_source_write(struct zip_source *, const void *data, size_t len); -zip_source_printf(struct zip_source *, const char *fmt, ...); -/* maybe -zip_source_vprintf(struct zip_source *, const char *fmt, va_list ap); -*/ ------------------------------------------------- others -* regression tests (duplicate file names, unchange, .{200}) -* zip_commit -* zip_replace_zip: allow rewinding -* API for parsing extra fields? -* API for setting/getting extra fields in cdir? -* zipcmp: add option for file content comparison -* support for zip64 (large file) +Extra Fields +------------ +zip_uint32_t zip_get_extra_field_num(struct zip *archive, zip_uint64_t idx); +int zip_get_extra_field_index(struct zip *archive, zip_uint64_t idx, + zip_uint32_t ef_idx, zip_uint16_t *ID, + zip_uint16_t *len, void **content); +int zip_get_extra_field_id(struct zip *archive, zip_uint64_t idx, + zip_uint16_t ID, zip_uint16_t *len, void **content); +int zip_set_extra_field_id(struct zip *archive, zip_uint64_t idx, + zip_uint16_t ID, zip_uint16_t len, void *content); -* append to files (for self-extracting files) + +API Issues +========== +* character encoding in file names and comments (see mail) +* compression/crypt implementations: how to set error code on failure +* compression/crypt error messages a la ZIP_ER_ZLIB (no detailed info passing) + + +Features +======== +* I/O methods +* do not compress if storing is smaller +* support streaming output (creating new archive to e.g. stdout) +* add functions to: + . set last modification time for entry + . read/set ASCII file flag? (wiz: more general options?) + . get/set "version made by" and "external file attributes" + (can be used to decide if an entry is a directory, if the + archive was created on DOS) +* zip_commit (to finish changes without closing archive) +* support for zip64 (large file) * add custom compression function support -* zip_replace_zip: remember compression method, recompress if different speced -* close even if error... +* close even if error? * support for old compression methods????? ------------------------------------------------- regression tests +* zip_replace_zip: allow rewinding +* zip_replace_zip: remember compression method, recompress if different speced +* zipcmp: add option for file content comparison +* append to files (for self-extracting files) + + +Bugs +==== +* check for limits imposed by format (central dir size, file size, ...) +* set "version of encoding software" to proper value (2.0?) +* _zip_checkcons return value can overflow +* _zip_u2d_time: handle localtime(3) failure +* missing -Wl,-R in pkg-config file +* zip_open: consistency check: check data descriptor +* POSIX: zip_open: check whether file can be created and fail if not +* POSIX: fix permissions of new file to match old one +* fix inconsistent usage of valid flags (not checked in many places) + +Cleanup +======= +* get rid of zip_get_{compression,encryption}_implementation +* use zip_*int*_t internally +* completely get rid of off_t + + +Consistency +=========== +* check arguments for every entry point into libzip +* check that local headers come before central dir + + +Test Case Issues +================ +* test calls against old API +* run regression tests also from CMake framework +* rename file to dir/ and vice versa (fails) +* fix comment test to be newline insensitive + * (add, replace) add to empty zip add to existing zip @@ -86,7 +107,6 @@ close zipcmp copy expected remove copy -* (delete) * (error_get) * (error_get_sys_type) * (error_to_str) @@ -96,7 +116,6 @@ * (fopen_index) illegal index * (get_name) -* (get_num_files) * (rename) * (replace) * (source_buffer)
diff --git a/cmake-zipconf.h.in b/cmake-zipconf.h.in index f7b08ae..70c8f2b 100644 --- a/cmake-zipconf.h.in +++ b/cmake-zipconf.h.in
@@ -11,12 +11,16 @@ #cmakedefine HAVE_INTTYPES_H_LIBZIP #cmakedefine HAVE_STDINT_H_LIBZIP #cmakedefine HAVE_SYS_TYPES_H_LIBZIP +#cmakedefine HAVE___INT8_LIBZIP #cmakedefine HAVE_INT8_T_LIBZIP #cmakedefine HAVE_UINT8_T_LIBZIP +#cmakedefine HAVE___INT16_LIBZIP #cmakedefine HAVE_INT16_T_LIBZIP #cmakedefine HAVE_UINT16_T_LIBZIP +#cmakedefine HAVE___INT32_LIBZIP #cmakedefine HAVE_INT32_T_LIBZIP #cmakedefine HAVE_UINT32_T_LIBZIP +#cmakedefine HAVE___INT64_LIBZIP #cmakedefine HAVE_INT64_T_LIBZIP #cmakedefine HAVE_UINT64_T_LIBZIP #cmakedefine SHORT_LIBZIP ${SHORT_LIBZIP} @@ -34,26 +38,36 @@ #if defined(HAVE_INT8_T_LIBZIP) typedef int8_t zip_int8_t; +#elif defined(HAVE___INT8_LIBZIP_) +typedef __int8 zip_int8_t; #else typedef signed char zip_int8_t; #endif #if defined(HAVE_UINT8_T_LIBZIP) typedef uint8_t zip_uint8_t; +#elif defined(HAVE___INT8_LIBZIP_) +typedef unsigned __int8 zip_uint8_t; #else typedef unsigned char zip_uint8_t; #endif #if defined(HAVE_INT16_T_LIBZIP) typedef int16_t zip_int16_t; +#elif defined(HAVE___INT16_LIBZIP_) +typedef __int16 zip_int16_t; #elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 typedef signed short zip_int16_t; #endif #if defined(HAVE_UINT16_T_LIBZIP) typedef uint16_t zip_uint16_t; +#elif defined(HAVE___INT16_LIBZIP_) +typedef unsigned __int16 zip_uint16_t; #elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 typedef unsigned short zip_uint16_t; #endif #if defined(HAVE_INT32_T_LIBZIP) typedef int32_t zip_int32_t; +#elif defined(HAVE___INT32_LIBZIP_) +typedef __int32 zip_int32_t; #elif defined(INT_LIBZIP) && INT_LIBZIP == 4 typedef signed int zip_int32_t; #elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 @@ -61,6 +75,8 @@ #endif #if defined(HAVE_UINT32_T_LIBZIP) typedef uint32_t zip_uint32_t; +#elif defined(HAVE___INT32_LIBZIP_) +typedef unsigned __int32 zip_uint32_t; #elif defined(INT_LIBZIP) && INT_LIBZIP == 4 typedef unsigned int zip_uint32_t; #elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 @@ -68,6 +84,8 @@ #endif #if defined(HAVE_INT64_T_LIBZIP) typedef int64_t zip_int64_t; +#elif defined(HAVE___INT64_LIBZIP_) +typedef __int64 zip_int64_t; #elif defined(LONG_LIBZIP) && LONG_LIBZIP == 8 typedef signed long zip_int64_t; #elif defined(LONGLONG_LIBZIP) && LONGLONG_LIBZIP == 8 @@ -75,6 +93,8 @@ #endif #if defined(HAVE_UINT64_T_LIBZIP) typedef uint64_t zip_uint64_t; +#elif defined(HAVE___INT64_LIBZIP_) +typedef unsigned __int64 zip_uint64_t; #elif defined(LONG_LIBZIP) && LONGLONG_LIBZIP == 8 typedef unsigned long zip_uint64_t; #elif defined(LONGLONG_LIBZIP) && LONGLONG_LIBZIP == 8
diff --git a/configure.ac b/configure.ac index 793c1ca..6e72ecb 100644 --- a/configure.ac +++ b/configure.ac
@@ -1,5 +1,5 @@ AC_PREREQ(2.57) -AC_INIT([libzip],[0.10.1],[libzip-discuss@nih.at]) +AC_INIT([libzip],[0.10b],[libzip-discuss@nih.at]) AC_CONFIG_SRCDIR([lib/zip_add.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4])
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index af09a39..99c4014 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt
@@ -58,6 +58,7 @@ zip_close.c zip_delete.c zip_dirent.c + zip_discard.c zip_entry_free.c zip_entry_new.c zip_err_str.c @@ -69,6 +70,7 @@ zip_error_to_str.c zip_fclose.c zip_fdopen.c + zip_set_file_compression.c zip_file_error_clear.c zip_file_error_get.c zip_file_get_offset.c @@ -79,7 +81,6 @@ zip_fopen_index.c zip_fopen_index_encrypted.c zip_fread.c - zip_free.c zip_get_archive_comment.c zip_get_archive_flag.c zip_get_compression_implementation.c @@ -87,6 +88,7 @@ zip_get_file_comment.c zip_get_file_extra.c zip_get_name.c + zip_get_num_entries.c zip_get_num_files.c zip_memdup.c zip_name_locate.c @@ -115,7 +117,9 @@ zip_source_pop.c zip_source_read.c zip_source_stat.c + zip_source_window.c zip_source_zip.c + zip_source_zip_new.c zip_stat.c zip_stat_index.c zip_stat_init.c @@ -124,6 +128,7 @@ zip_unchange_all.c zip_unchange_archive.c zip_unchange_data.c + zip_utf-8.c ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/lib/Makefile.am b/lib/Makefile.am index 9f7be38..9a1c28d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am
@@ -15,6 +15,7 @@ zip_close.c \ zip_delete.c \ zip_dirent.c \ + zip_discard.c \ zip_entry_free.c \ zip_entry_new.c \ zip_err_str.c \ @@ -36,7 +37,6 @@ zip_fopen_index.c \ zip_fopen_index_encrypted.c \ zip_fread.c \ - zip_free.c \ zip_get_archive_comment.c \ zip_get_archive_flag.c \ zip_get_compression_implementation.c \ @@ -56,6 +56,7 @@ zip_set_archive_flag.c \ zip_set_default_password.c \ zip_set_file_comment.c \ + zip_set_file_compression.c \ zip_set_file_extra.c \ zip_source_buffer.c \ zip_source_close.c \ @@ -72,7 +73,9 @@ zip_source_pop.c \ zip_source_read.c \ zip_source_stat.c \ + zip_source_window.c \ zip_source_zip.c \ + zip_source_zip_new.c \ zip_set_name.c \ zip_stat.c \ zip_stat_index.c \ @@ -81,9 +84,10 @@ zip_unchange.c \ zip_unchange_all.c \ zip_unchange_archive.c \ - zip_unchange_data.c + zip_unchange_data.c \ + zip_utf-8.c -BUILT_SOURCES=zip_err_str.c zipconf.h +BUILT_SOURCES=zipconf.h CLEANFILES= ${BUILT_SOURCES} EXTRA_DIST= CMakeLists.txt \
diff --git a/lib/make_zipconf.sh b/lib/make_zipconf.sh index 5623cd0..12e7b0a 100644 --- a/lib/make_zipconf.sh +++ b/lib/make_zipconf.sh
@@ -44,13 +44,13 @@ bits=`expr $bytes '*' 8` type="${short}int${bits}" - TYPE=`echo $type | tr a-z A-Z` + TYPE=`echo $type | tr '[a-z]' '[A-Z]'` if grep "define HAVE_${TYPE}_T" "$infile" > /dev/null then echo "typedef ${type}_t zip_${type}_t;" >> "$outfile" LTYPE="$TYPE" else - SHORT=`echo $short | tr a-z A-Z` + SHORT=`echo $short | tr '[a-z]' '[A-Z]'` if [ -z "$SHORT" ] then SHORT='S' @@ -65,7 +65,7 @@ LTYPE="${SHORT}CHAR" else ctype=`sed -n "s/.define SIZEOF_\([A-Z_]*\) $bytes/\1/p" "$infile" \ - | head -1 | tr A-Z_ 'a-z '` + | head -1 | tr '[A-Z_]' '[a-z ]'` if [ -z "$ctype" ] then echo "$0: no $bits bit type found" >&2
diff --git a/lib/zip.h b/lib/zip.h index f8b55ac..10e2f36 100644 --- a/lib/zip.h +++ b/lib/zip.h
@@ -3,7 +3,7 @@ /* zip.h -- exported declarations. - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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> @@ -39,6 +39,8 @@ #ifndef ZIP_EXTERN #ifdef _WIN32 #define ZIP_EXTERN __declspec(dllimport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ZIP_EXTERN __attribute__ ((visibility ("default"))) #else #define ZIP_EXTERN #endif @@ -59,6 +61,7 @@ #define ZIP_CREATE 1 #define ZIP_EXCL 2 #define ZIP_CHECKCONS 4 +#define ZIP_TRUNCATE 8 /* flags for zip_name_locate, zip_fopen, zip_stat, ... */ @@ -70,6 +73,9 @@ #define ZIP_FL_RECOMPRESS 16 /* force recompression of data */ #define ZIP_FL_ENCRYPTED 32 /* read encrypted data (implies ZIP_FL_COMPRESSED) */ +#define ZIP_FL_NAME_GUESS 0 /* guess name encoding (is default) */ +#define ZIP_FL_NAME_RAW 64 /* get unmodified name */ +#define ZIP_FL_NAME_STRICT 128 /* follow specification strictly */ /* archive global flags flags */ @@ -79,6 +85,7 @@ /* flags for compression and encryption sources */ +#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ #define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ @@ -112,6 +119,7 @@ #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 */ +#define ZIP_ER_ENCMISMATCH 28 /* N Encoding of name and comment do not match */ /* type of system error value */ @@ -208,6 +216,7 @@ 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 void zip_discard(struct zip *); 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 *); @@ -244,6 +253,8 @@ 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_compression(struct zip *, zip_uint64_t, + zip_int32_t, zip_uint32_t); 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 *,
diff --git a/lib/zip_close.c b/lib/zip_close.c index f4ae2a4..4d8e178 100644 --- a/lib/zip_close.c +++ b/lib/zip_close.c
@@ -1,6 +1,6 @@ /* zip_close.c -- close zip archive and update changes - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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> @@ -82,29 +82,33 @@ struct filelist *filelist; int reopen_on_error; int new_torrentzip; + enum zip_encoding_type com_enc, enc; + int changed; reopen_on_error = 0; if (za == NULL) return -1; - if (!_zip_changed(za, &survivors)) { - _zip_free(za); - return 0; - } + changed = _zip_changed(za, &survivors); /* don't create zip files with no entries */ if (survivors == 0) { - if (za->zn && za->zp) { + if (za->zn && ((za->open_flags & ZIP_TRUNCATE) || (changed && za->zp))) { if (remove(za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); return -1; } } - _zip_free(za); + zip_discard(za); return 0; } + if (!changed) { + zip_discard(za); + return 0; + } + if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) == NULL) return -1; @@ -162,32 +166,33 @@ ZIP_FL_UNCHANGED) == 0); error = 0; for (j=0; j<survivors; j++) { + int new_data; + i = filelist[j].idx; + new_data = (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip || (za->entry[i].changes.valid & ZIP_DIRENT_COMP_METHOD)); + /* create new local directory entry */ - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { + if (new_data) { _zip_dirent_init(&de); if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) _zip_dirent_torrent_normalize(&de); + if (za->entry[i].changes.valid & ZIP_DIRENT_COMP_METHOD) { + de.settable.comp_method = za->entry[i].changes.comp_method; + de.settable.valid |= ZIP_DIRENT_COMP_METHOD; + } + /* use it as central directory entry */ memcpy(cd->entry+j, &de, sizeof(cd->entry[j])); /* set/update file name */ - if (za->entry[i].ch_filename == NULL) { - if (za->entry[i].state == ZIP_ST_ADDED) { - de.filename = strdup("-"); - de.filename_len = 1; - cd->entry[j].filename = "-"; - cd->entry[j].filename_len = 1; - } - else { - de.filename = strdup(za->cdir->entry[i].filename); - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->cdir->entry[i].filename; - cd->entry[j].filename_len = de.filename_len; - } + if ((za->entry[i].changes.valid & ZIP_DIRENT_FILENAME) == 0) { + de.settable.filename = strdup(za->cdir->entry[i].settable.filename); + cd->entry[j].settable.filename = za->cdir->entry[i].settable.filename; + de.settable.valid |= ZIP_DIRENT_FILENAME; + cd->entry[j].settable.valid |= ZIP_DIRENT_FILENAME; } } else { @@ -212,49 +217,61 @@ } } - if (za->entry[i].ch_filename) { - free(de.filename); - if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) { + if (za->entry[i].changes.valid & ZIP_DIRENT_FILENAME) { + free(de.settable.filename); + if ((de.settable.filename=strdup(za->entry[i].changes.filename)) == NULL) { error = 1; break; } - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->entry[i].ch_filename; - cd->entry[j].filename_len = de.filename_len; + cd->entry[j].settable.filename = za->entry[i].changes.filename; } - 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; + if (za->entry[i].changes.valid & ZIP_DIRENT_EXTRAFIELD) { + free(de.settable.extrafield); + if (za->entry[i].changes.extrafield_len > 0) { + if ((de.settable.extrafield=malloc(za->entry[i].changes.extrafield_len)) == NULL) { + error = 1; + break; + } + memcpy(de.settable.extrafield, za->entry[i].changes.extrafield, za->entry[i].changes.extrafield_len); + } + else + de.settable.extrafield = NULL; + de.settable.extrafield_len = za->entry[i].changes.extrafield_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; + cd->entry[j].settable.extrafield = za->entry[i].changes.extrafield; + cd->entry[j].settable.extrafield_len = za->entry[i].changes.extrafield_len; */ } if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0 - && za->entry[i].ch_comment_len != -1) { + && za->entry[i].changes.valid & ZIP_DIRENT_COMMENT) { /* as the rest of cd entries, its malloc/free is done by za */ - cd->entry[j].comment = za->entry[i].ch_comment; - cd->entry[j].comment_len = za->entry[i].ch_comment_len; + cd->entry[j].settable.comment = za->entry[i].changes.comment; + cd->entry[j].settable.comment_len = za->entry[i].changes.comment_len; } + /* set general purpose bit flag for file name/comment encoding */ + enc = _zip_guess_encoding(de.settable.filename, strlen(de.settable.filename)); + com_enc = _zip_guess_encoding(cd->entry[i].settable.comment, cd->entry[i].settable.comment_len); + if ((enc == ZIP_ENCODING_UTF8 && com_enc == ZIP_ENCODING_ASCII) || + (enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8 ) || + (enc == ZIP_ENCODING_UTF8 && com_enc == ZIP_ENCODING_UTF8 )) + de.bitflags |= ZIP_GPBF_ENCODING_UTF_8; + else + de.bitflags &= ~ZIP_GPBF_ENCODING_UTF_8; + cd->entry[i].bitflags = de.bitflags; + cd->entry[j].offset = ftello(out); - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { + if (new_data) { struct zip_source *zs; zs = NULL; if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { - if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) - == NULL) { + if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, -1, NULL)) == NULL) { error = 1; break; } @@ -270,7 +287,7 @@ zip_source_free(zs); cd->entry[j].last_mod = de.last_mod; - cd->entry[j].comp_method = de.comp_method; + cd->entry[j].settable.comp_method = de.settable.comp_method; cd->entry[j].comp_size = de.comp_size; cd->entry[j].uncomp_size = de.uncomp_size; cd->entry[j].crc = de.crc; @@ -338,7 +355,7 @@ chmod(za->zn, 0666&~mask); #endif - _zip_free(za); + zip_discard(za); free(temp); return 0; @@ -353,7 +370,6 @@ off_t offstart, offdata, offend; struct zip_stat st; struct zip_source *s2; - zip_compression_implementation comp_impl; int ret; if (zip_source_stat(src, &st) < 0) { @@ -366,28 +382,57 @@ if (_zip_dirent_write(de, ft, 1, &za->error) < 0) return -1; - if ((s2=zip_source_crc(za, src, 0)) == NULL) { - zip_source_pop(s2); - return -1; + if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { + st.valid |= ZIP_STAT_COMP_METHOD; + st.comp_method = ZIP_CM_STORE; } - - /* 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); + + if ((de->settable.valid & ZIP_DIRENT_COMP_METHOD) == 0 || de->settable.comp_method == ZIP_CM_DEFAULT) { + de->settable.valid |= ZIP_DIRENT_COMP_METHOD; + de->settable.comp_method = ZIP_CM_DEFLATE; + } + + if (st.comp_method != de->settable.comp_method) { + struct zip_source *s_store, *s_crc; + zip_compression_implementation comp_impl; + + 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 -1; + } + if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) { + /* error set by comp_impl */ + return -1; + } + } + else + s_store = src; + + if ((s_crc=zip_source_crc(za, s_store, 0)) == NULL) { + if (s_store != src) + zip_source_pop(s_store); return -1; } - if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE)) - == NULL) { - /* XXX: set error? */ - zip_source_pop(s2); - return -1; + + /* XXX: deflate 0-byte files for torrentzip? */ + if (de->settable.comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) { + if ((comp_impl=zip_get_compression_implementation(de->settable.comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + zip_source_pop(s_crc); + if (s_store != src) + zip_source_pop(s_store); + return -1; + } + if ((s2=comp_impl(za, s_crc, de->settable.comp_method, ZIP_CODEC_ENCODE)) == NULL) { + zip_source_pop(s_crc); + if (s_store != src) + zip_source_pop(s_store); + return -1; + } } + else + s2 = s_crc; } else s2 = src; @@ -418,7 +463,7 @@ } de->last_mod = st.mtime; - de->comp_method = st.comp_method; + de->settable.comp_method = st.comp_method; de->crc = st.crc; de->uncomp_size = st.size; de->comp_size = offend - offdata; @@ -548,13 +593,18 @@ _zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src) { if (src->ch_comment_len != -1) { - dest->comment = _zip_memdup(src->ch_comment, - src->ch_comment_len, &src->error); - if (dest->comment == NULL) - return -1; dest->comment_len = src->ch_comment_len; - } else { - if (src->cdir && src->cdir->comment) { + if (src->ch_comment_len == 0) + dest->comment = NULL; + else { + dest->comment = _zip_memdup(src->ch_comment, + src->ch_comment_len, &src->error); + if (dest->comment == NULL) + return -1; + } + } + else { + if (src->cdir && src->cdir->comment_len > 0) { dest->comment = _zip_memdup(src->cdir->comment, src->cdir->comment_len, &src->error); if (dest->comment == NULL) @@ -580,9 +630,7 @@ changed = 1; 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)) + if (za->entry[i].state != ZIP_ST_UNCHANGED || za->entry[i].changes.valid != 0) changed = 1; if (za->entry[i].state != ZIP_ST_DELETED) survivors++;
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c index b5b9d27..4006a5b 100644 --- a/lib/zip_dirent.c +++ b/lib/zip_dirent.c
@@ -1,6 +1,6 @@ /* zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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> @@ -61,6 +61,7 @@ for (i=0; i<cd->nentry; i++) _zip_dirent_finalize(cd->entry+i); free(cd->comment); + free(cd->comment_converted); free(cd->entry); free(cd); } @@ -77,6 +78,9 @@ return -1; } + if (nentry == cd->nentry) + return 0; + if ((entry=((struct zip_dirent *) realloc(cd->entry, sizeof(*(cd->entry))*nentry))) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -101,7 +105,9 @@ return NULL; } - if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry)) + if (nentry == 0) + cd->entry = NULL; + else if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry)) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); free(cd); @@ -114,6 +120,8 @@ cd->size = cd->offset = 0; cd->comment = NULL; cd->comment_len = 0; + cd->comment_type = ZIP_ENCODING_UNKNOWN; + cd->comment_converted = NULL; return cd; } @@ -157,12 +165,16 @@ void _zip_dirent_finalize(struct zip_dirent *zde) { - free(zde->filename); - zde->filename = NULL; - free(zde->extrafield); - zde->extrafield = NULL; - free(zde->comment); - zde->comment = NULL; + free(zde->filename_converted); + zde->filename_converted = NULL; + free(zde->comment_converted); + zde->comment_converted = NULL; + free(zde->settable.filename); + zde->settable.filename = NULL; + free(zde->settable.extrafield); + zde->settable.extrafield = NULL; + free(zde->settable.comment); + zde->settable.comment = NULL; } @@ -170,24 +182,28 @@ void _zip_dirent_init(struct zip_dirent *de) { + de->settable.valid = 0; + de->settable.comp_method = 0; + de->settable.filename = NULL; + de->settable.extrafield = NULL; + de->settable.extrafield_len = 0; + de->settable.comment = NULL; + de->settable.comment_len = 0; de->version_madeby = 0; de->version_needed = 20; /* 2.0 */ de->bitflags = 0; - de->comp_method = 0; de->last_mod = 0; de->crc = 0; de->comp_size = 0; de->uncomp_size = 0; - de->filename = NULL; - de->filename_len = 0; - de->extrafield = NULL; - de->extrafield_len = 0; - de->comment = NULL; - de->comment_len = 0; de->disk_number = 0; de->int_attrib = 0; de->ext_attrib = 0; de->offset = 0; + de->fn_type = ZIP_ENCODING_UNKNOWN; + de->filename_converted = NULL; + de->fc_type = ZIP_ENCODING_UNKNOWN; + de->comment_converted = NULL; } @@ -219,6 +235,7 @@ unsigned char *cur; unsigned short dostime, dosdate; zip_uint32_t size; + zip_uint16_t filename_len; if (local) size = LENTRYSIZE; @@ -249,16 +266,18 @@ } cur += 4; - + /* convert buffercontents to zip_dirent */ - + + _zip_dirent_init(zde); if (!local) zde->version_madeby = _zip_read2(&cur); else zde->version_madeby = 0; zde->version_needed = _zip_read2(&cur); zde->bitflags = _zip_read2(&cur); - zde->comp_method = _zip_read2(&cur); + zde->settable.comp_method = _zip_read2(&cur); + zde->settable.valid |= ZIP_DIRENT_COMP_METHOD; /* convert to time_t */ dostime = _zip_read2(&cur); @@ -269,28 +288,28 @@ zde->comp_size = _zip_read4(&cur); zde->uncomp_size = _zip_read4(&cur); - zde->filename_len = _zip_read2(&cur); - zde->extrafield_len = _zip_read2(&cur); + filename_len = _zip_read2(&cur); + zde->settable.extrafield_len = _zip_read2(&cur); if (local) { - zde->comment_len = 0; + zde->settable.comment_len = 0; zde->disk_number = 0; zde->int_attrib = 0; zde->ext_attrib = 0; zde->offset = 0; } else { - zde->comment_len = _zip_read2(&cur); + zde->settable.comment_len = _zip_read2(&cur); zde->disk_number = _zip_read2(&cur); zde->int_attrib = _zip_read2(&cur); zde->ext_attrib = _zip_read4(&cur); zde->offset = _zip_read4(&cur); } - zde->filename = NULL; - zde->extrafield = NULL; - zde->comment = NULL; + zde->settable.filename = NULL; + zde->settable.extrafield = NULL; + zde->settable.comment = NULL; - size += zde->filename_len+zde->extrafield_len+zde->comment_len; + size += filename_len+zde->settable.extrafield_len+zde->settable.comment_len; if (leftp && (*leftp < size)) { _zip_error_set(error, ZIP_ER_NOZIP, 0); @@ -298,46 +317,59 @@ } if (bufp) { - if (zde->filename_len) { - zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error); - if (!zde->filename) + if (filename_len) { + zde->settable.filename = _zip_readstr(&cur, filename_len, 1, error); + if (!zde->settable.filename) return -1; } - if (zde->extrafield_len) { - zde->extrafield = _zip_readstr(&cur, zde->extrafield_len, 0, + if (zde->settable.extrafield_len) { + zde->settable.extrafield = _zip_readstr(&cur, zde->settable.extrafield_len, 0, error); - if (!zde->extrafield) + if (!zde->settable.extrafield) return -1; } - if (zde->comment_len) { - zde->comment = _zip_readstr(&cur, zde->comment_len, 0, error); - if (!zde->comment) + if (zde->settable.comment_len) { + zde->settable.comment = _zip_readstr(&cur, zde->settable.comment_len, 0, error); + if (!zde->settable.comment) return -1; } } else { - if (zde->filename_len) { - zde->filename = _zip_readfpstr(fp, zde->filename_len, 1, error); - if (!zde->filename) + if (filename_len) { + zde->settable.filename = _zip_readfpstr(fp, filename_len, 1, error); + if (!zde->settable.filename) return -1; } - if (zde->extrafield_len) { - zde->extrafield = _zip_readfpstr(fp, zde->extrafield_len, 0, + if (zde->settable.extrafield_len) { + zde->settable.extrafield = _zip_readfpstr(fp, zde->settable.extrafield_len, 0, error); - if (!zde->extrafield) + if (!zde->settable.extrafield) return -1; } - if (zde->comment_len) { - zde->comment = _zip_readfpstr(fp, zde->comment_len, 0, error); - if (!zde->comment) + if (zde->settable.comment_len) { + zde->settable.comment = _zip_readfpstr(fp, zde->settable.comment_len, 0, error); + if (!zde->settable.comment) return -1; } } + if (filename_len == 0) { + if ((zde->settable.filename=strdup("")) == NULL) + return -1; + } + if (strlen(zde->settable.filename) != filename_len) + return -1; + zde->settable.valid |= ZIP_DIRENT_FILENAME; + + if (zde->settable.comment_len) + zde->settable.valid |= ZIP_DIRENT_COMMENT; + if (zde->settable.extrafield_len) + zde->settable.valid |= ZIP_DIRENT_EXTRAFIELD; + if (bufp) *bufp = cur; if (leftp) @@ -387,7 +419,8 @@ de->version_madeby = 0; de->version_needed = 20; /* 2.0 */ de->bitflags = 2; /* maximum compression */ - de->comp_method = ZIP_CM_DEFLATE; + de->settable.comp_method = ZIP_CM_DEFLATE; + de->settable.valid |= ZIP_DIRENT_COMP_METHOD; de->last_mod = last_mod; de->disk_number = 0; @@ -395,12 +428,13 @@ de->ext_attrib = 0; de->offset = 0; - free(de->extrafield); - de->extrafield = NULL; - de->extrafield_len = 0; - free(de->comment); - de->comment = NULL; - de->comment_len = 0; + free(de->settable.extrafield); + de->settable.extrafield = NULL; + de->settable.extrafield_len = 0; + free(de->settable.comment); + de->settable.comment = NULL; + de->settable.comment_len = 0; + de->settable.valid &= ~(ZIP_DIRENT_COMMENT|ZIP_DIRENT_EXTRAFIELD); } @@ -420,6 +454,9 @@ struct zip_error *error) { unsigned short dostime, dosdate; + zip_uint16_t filename_len; + + filename_len = strlen(zde->settable.filename); fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); @@ -427,7 +464,7 @@ _zip_write2(zde->version_madeby, fp); _zip_write2(zde->version_needed, fp); _zip_write2(zde->bitflags, fp); - _zip_write2(zde->comp_method, fp); + _zip_write2(zde->settable.comp_method, fp); _zip_u2d_time(zde->last_mod, &dostime, &dosdate); _zip_write2(dostime, fp); @@ -437,26 +474,26 @@ _zip_write4(zde->comp_size, fp); _zip_write4(zde->uncomp_size, fp); - _zip_write2(zde->filename_len, fp); - _zip_write2(zde->extrafield_len, fp); + _zip_write2(filename_len, fp); + _zip_write2(zde->settable.extrafield_len, fp); if (!localp) { - _zip_write2(zde->comment_len, fp); + _zip_write2(zde->settable.comment_len, fp); _zip_write2(zde->disk_number, fp); _zip_write2(zde->int_attrib, fp); _zip_write4(zde->ext_attrib, fp); _zip_write4(zde->offset, fp); } - if (zde->filename_len) - fwrite(zde->filename, 1, zde->filename_len, fp); + if (filename_len > 0) + fwrite(zde->settable.filename, 1, filename_len, fp); - if (zde->extrafield_len) - fwrite(zde->extrafield, 1, zde->extrafield_len, fp); + if (zde->settable.extrafield_len) + fwrite(zde->settable.extrafield, 1, zde->settable.extrafield_len, fp); if (!localp) { - if (zde->comment_len) - fwrite(zde->comment, 1, zde->comment_len, fp); + if (zde->settable.comment_len) + fwrite(zde->settable.comment, 1, zde->settable.comment_len, fp); } if (ferror(fp)) { @@ -523,6 +560,9 @@ { char *r, *o; + if (len == 0 && nulp == 0) + return NULL; + r = (char *)malloc(nulp ? len+1 : len); if (!r) { _zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -553,6 +593,9 @@ { char *r, *o; + if (len == 0 && nulp == 0) + return NULL; + r = (char *)malloc(nulp ? len+1 : len); if (!r) { _zip_error_set(error, ZIP_ER_MEMORY, 0);
diff --git a/lib/zip_free.c b/lib/zip_discard.c similarity index 93% rename from lib/zip_free.c rename to lib/zip_discard.c index 9932c14..16cc3d8 100644 --- a/lib/zip_free.c +++ b/lib/zip_discard.c
@@ -1,6 +1,6 @@ /* - zip_free.c -- free struct zip - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + zip_discard.c -- discard and free struct zip + Copyright (C) 1999-2012 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> @@ -39,12 +39,12 @@ -/* _zip_free: +/* zip_discard: frees the space allocated to a zipfile struct, and closes the corresponding file. */ void -_zip_free(struct zip *za) +zip_discard(struct zip *za) { int i;
diff --git a/lib/zip_entry_free.c b/lib/zip_entry_free.c index e8a7770..f801855 100644 --- a/lib/zip_entry_free.c +++ b/lib/zip_entry_free.c
@@ -42,14 +42,13 @@ void _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; + if (ze->changes.valid & ZIP_DIRENT_FILENAME) + free(ze->changes.filename); + if (ze->changes.valid & ZIP_DIRENT_EXTRAFIELD) + free(ze->changes.extrafield); + if (ze->changes.valid & ZIP_DIRENT_COMMENT) + free(ze->changes.comment); + ze->changes.valid = 0; _zip_unchange_data(ze); }
diff --git a/lib/zip_entry_new.c b/lib/zip_entry_new.c index ad5d599..b8ab272 100644 --- a/lib/zip_entry_new.c +++ b/lib/zip_entry_new.c
@@ -1,6 +1,6 @@ /* zip_entry_new.c -- create and init struct zip_entry - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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,9 +45,8 @@ struct zip_entry *ze; if (!za) { ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); - if (!ze) { + if (!ze) return NULL; - } } else { if (za->nentry+1 >= za->nentry_alloc) { @@ -66,13 +65,8 @@ } 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; + ze->changes.valid = 0; if (za) za->nentry++;
diff --git a/lib/zip_err_str.c b/lib/zip_err_str.c index 8fb6003..7cf9b42 100644 --- a/lib/zip_err_str.c +++ b/lib/zip_err_str.c
@@ -36,6 +36,7 @@ "Read-only archive", "No password provided", "Wrong password provided", + "Encoding of name and comment do not match", }; const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); @@ -73,4 +74,5 @@ N, N, N, + N, };
diff --git a/lib/zip_error.c b/lib/zip_error.c index b8d907a..d82875a 100644 --- a/lib/zip_error.c +++ b/lib/zip_error.c
@@ -42,6 +42,9 @@ void _zip_error_clear(struct zip_error *err) { + if (err == NULL) + return; + err->zip_err = ZIP_ER_OK; err->sys_err = 0; }
diff --git a/lib/zip_error_clear.c b/lib/zip_error_clear.c index 364383e..b4ff103 100644 --- a/lib/zip_error_clear.c +++ b/lib/zip_error_clear.c
@@ -40,5 +40,8 @@ ZIP_EXTERN void zip_error_clear(struct zip *za) { + if (za == NULL) + return; + _zip_error_clear(&za->error); }
diff --git a/lib/zip_fdopen.c b/lib/zip_fdopen.c index fec9d0c..46f078f 100644 --- a/lib/zip_fdopen.c +++ b/lib/zip_fdopen.c
@@ -43,6 +43,11 @@ int fd; FILE *fp; + if (flags & ZIP_TRUNCATE) { + *zep = ZIP_ER_INVAL; + return NULL; + } + /* We dup() here to avoid messing with the passed in fd. We could not restore it to the original state in case of error. */
diff --git a/lib/zip_file_error_clear.c b/lib/zip_file_error_clear.c index ef6fa10..ce8b6cb 100644 --- a/lib/zip_file_error_clear.c +++ b/lib/zip_file_error_clear.c
@@ -40,5 +40,8 @@ ZIP_EXTERN void zip_file_error_clear(struct zip_file *zf) { + if (zf == NULL) + return; + _zip_error_clear(&zf->error); }
diff --git a/lib/zip_file_get_offset.c b/lib/zip_file_get_offset.c index b96fd5e..17a47b8 100644 --- a/lib/zip_file_get_offset.c +++ b/lib/zip_file_get_offset.c
@@ -51,7 +51,7 @@ */ unsigned int -_zip_file_get_offset(struct zip *za, int idx) +_zip_file_get_offset(struct zip *za, int idx, struct zip_error *ze) { struct zip_dirent de; unsigned int offset; @@ -59,14 +59,14 @@ offset = za->cdir->entry[idx].offset; if (fseeko(za->zp, offset, SEEK_SET) != 0) { - _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + _zip_error_set(ze, ZIP_ER_SEEK, errno); return 0; } - if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, &za->error) != 0) + if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, ze) != 0) return 0; - offset += LENTRYSIZE + de.filename_len + de.extrafield_len; + offset += LENTRYSIZE + strlen(de.settable.filename) + de.settable.extrafield_len; _zip_dirent_finalize(&de);
diff --git a/lib/zip_fopen_index_encrypted.c b/lib/zip_fopen_index_encrypted.c index 2e617bf..657ed01 100644 --- a/lib/zip_fopen_index_encrypted.c +++ b/lib/zip_fopen_index_encrypted.c
@@ -48,98 +48,10 @@ 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; + struct zip_source *src; - if (fileno >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + if ((src=_zip_source_zip_new(za, za, fileno, flags, 0, 0, password)) == NULL) 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); @@ -147,7 +59,10 @@ return NULL; } - zf = _zip_file_new(za); + if ((zf=_zip_file_new(za)) == NULL) { + zip_source_free(src); + return NULL; + } zf->src = src;
diff --git a/lib/zip_get_archive_comment.c b/lib/zip_get_archive_comment.c index 669eb70..0a3589b 100644 --- a/lib/zip_get_archive_comment.c +++ b/lib/zip_get_archive_comment.c
@@ -1,6 +1,6 @@ /* zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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> @@ -33,6 +33,8 @@ +#include <string.h> + #include "zipint.h" @@ -40,12 +42,32 @@ ZIP_EXTERN const char * zip_get_archive_comment(struct zip *za, int *lenp, int flags) { + const char *ret; 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; + ret = za->cdir->comment; + + if (flags & ZIP_FL_NAME_RAW) + return ret; + + /* start guessing */ + if (za->cdir->comment_type == ZIP_ENCODING_UNKNOWN) + za->cdir->comment_type = _zip_guess_encoding(ret, za->cdir->comment_len); + + if (((flags & ZIP_FL_NAME_STRICT) && (za->cdir->comment_type != ZIP_ENCODING_ASCII)) + || (za->cdir->comment_type == ZIP_ENCODING_CP437)) { + if (za->cdir->comment_converted == NULL) + za->cdir->comment_converted = _zip_cp437_to_utf8(ret, za->cdir->comment_len, + &za->cdir->comment_converted_len, &za->error); + ret = za->cdir->comment_converted; + if (lenp != NULL) + *lenp = za->cdir->comment_converted_len; + } + + return ret; } else { if (lenp != NULL) @@ -53,7 +75,8 @@ return NULL; } } - + + /* already UTF-8, no conversion needed */ if (lenp != NULL) *lenp = za->ch_comment_len; return za->ch_comment;
diff --git a/lib/zip_get_file_comment.c b/lib/zip_get_file_comment.c index b9dacbe..ee71609 100644 --- a/lib/zip_get_file_comment.c +++ b/lib/zip_get_file_comment.c
@@ -1,6 +1,6 @@ /* zip_get_file_comment.c -- get file comment - Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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> @@ -33,6 +33,8 @@ +#include <string.h> + #include "zipint.h" @@ -40,19 +42,53 @@ ZIP_EXTERN const char * zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags) { + const char *ret; + if (idx >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } - if ((flags & ZIP_FL_UNCHANGED) - || (za->entry[idx].ch_comment_len == -1)) { + if ((flags & ZIP_FL_UNCHANGED) || (za->entry[idx].changes.valid & ZIP_DIRENT_COMMENT) == 0) { + if (za->cdir == NULL) { + _zip_error_set(&za->error, ZIP_ER_NOENT, 0); + return NULL; + } + if (idx >= za->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + if (lenp != NULL) - *lenp = za->cdir->entry[idx].comment_len; - return za->cdir->entry[idx].comment; + *lenp = za->cdir->entry[idx].settable.comment_len; + ret = za->cdir->entry[idx].settable.comment; + + if (flags & ZIP_FL_NAME_RAW) + return ret; + + /* file comment already is UTF-8? */ + if (za->cdir->entry[idx].bitflags & ZIP_GPBF_ENCODING_UTF_8) + return ret; + + /* undeclared, start guessing */ + if (za->cdir->entry[idx].fc_type == ZIP_ENCODING_UNKNOWN) + za->cdir->entry[idx].fc_type = _zip_guess_encoding(ret, za->cdir->entry[idx].settable.comment_len); + + if (((flags & ZIP_FL_NAME_STRICT) && (za->cdir->entry[idx].fc_type != ZIP_ENCODING_ASCII)) + || (za->cdir->entry[idx].fc_type == ZIP_ENCODING_CP437)) { + if (za->cdir->entry[idx].comment_converted == NULL) + za->cdir->entry[idx].comment_converted = _zip_cp437_to_utf8(ret, za->cdir->entry[idx].settable.comment_len, + &za->cdir->entry[idx].comment_converted_len, &za->error); + ret = za->cdir->entry[idx].comment_converted; + if (lenp != NULL) + *lenp = za->cdir->entry[idx].comment_converted_len; + } + + return ret; } - + + /* already UTF-8, no conversion necessary */ if (lenp != NULL) - *lenp = za->entry[idx].ch_comment_len; - return za->entry[idx].ch_comment; + *lenp = za->entry[idx].changes.comment_len; + return za->entry[idx].changes.comment; }
diff --git a/lib/zip_get_file_extra.c b/lib/zip_get_file_extra.c index afa507b..cb3d2b5 100644 --- a/lib/zip_get_file_extra.c +++ b/lib/zip_get_file_extra.c
@@ -45,14 +45,18 @@ return NULL; } - if ((flags & ZIP_FL_UNCHANGED) - || (za->entry[idx].ch_extra_len == -1)) { + if ((flags & ZIP_FL_UNCHANGED) || (za->entry[idx].changes.valid & ZIP_DIRENT_EXTRAFIELD) == 0) { + if (idx >= za->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + if (lenp != NULL) - *lenp = za->cdir->entry[idx].extrafield_len; - return za->cdir->entry[idx].extrafield; + *lenp = za->cdir->entry[idx].settable.extrafield_len; + return za->cdir->entry[idx].settable.extrafield; } if (lenp != NULL) - *lenp = za->entry[idx].ch_extra_len; - return za->entry[idx].ch_extra; + *lenp = za->entry[idx].changes.extrafield_len; + return za->entry[idx].changes.extrafield; }
diff --git a/lib/zip_get_name.c b/lib/zip_get_name.c index 531af50..7c3f7b9 100644 --- a/lib/zip_get_name.c +++ b/lib/zip_get_name.c
@@ -1,6 +1,6 @@ /* zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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> @@ -33,6 +33,8 @@ +#include <string.h> + #include "zipint.h" @@ -49,6 +51,10 @@ _zip_get_name(struct zip *za, zip_uint64_t idx, int flags, struct zip_error *error) { + enum zip_encoding_type enc; + const char *ret; + + ret = NULL; if (idx >= za->nentry) { _zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; @@ -59,14 +65,34 @@ _zip_error_set(error, ZIP_ER_DELETED, 0); return NULL; } - if (za->entry[idx].ch_filename) - return za->entry[idx].ch_filename; + if (za->entry[idx].changes.valid & ZIP_DIRENT_FILENAME) + return za->entry[idx].changes.filename; /* must be UTF-8 */ } + /* XXX: read Infozip UTF-8 Extension 0x7075 file name? */ if (za->cdir == NULL || idx >= za->cdir->nentry) { _zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } - - return za->cdir->entry[idx].filename; + ret = za->cdir->entry[idx].settable.filename; + + if (flags & ZIP_FL_NAME_RAW) + return ret; + + /* file name already is UTF-8? */ + if (za->cdir->entry[idx].bitflags & ZIP_GPBF_ENCODING_UTF_8) + return ret; + + /* undeclared, start guessing */ + if (za->cdir->entry[idx].fn_type == ZIP_ENCODING_UNKNOWN) + za->cdir->entry[idx].fn_type = _zip_guess_encoding(ret, strlen(ret)); + + if (((flags & ZIP_FL_NAME_STRICT) && (za->cdir->entry[idx].fn_type != ZIP_ENCODING_ASCII)) + || (za->cdir->entry[idx].fn_type == ZIP_ENCODING_CP437)) { + if (za->cdir->entry[idx].filename_converted == NULL) + za->cdir->entry[idx].filename_converted = _zip_cp437_to_utf8(ret, strlen(ret), NULL, error); + ret = za->cdir->entry[idx].filename_converted; + } + + return ret; }
diff --git a/lib/zip_memdup.c b/lib/zip_memdup.c index 641125e..06af2da 100644 --- a/lib/zip_memdup.c +++ b/lib/zip_memdup.c
@@ -1,6 +1,6 @@ /* zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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,6 +43,9 @@ { void *ret; + if (len == 0) + return NULL; + ret = malloc(len); if (!ret) { _zip_error_set(error, ZIP_ER_MEMORY, 0);
diff --git a/lib/zip_name_locate.c b/lib/zip_name_locate.c index 1f7081b..44e3c85 100644 --- a/lib/zip_name_locate.c +++ b/lib/zip_name_locate.c
@@ -72,12 +72,9 @@ n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; for (i=0; i<n; i++) { - if (flags & ZIP_FL_UNCHANGED) - fn = za->cdir->entry[i].filename; - else - fn = _zip_get_name(za, i, flags, error); + fn = _zip_get_name(za, i, flags, error); - /* newly added (partially filled) entry */ + /* newly added (partially filled) entry or error */ if (fn == NULL) continue; @@ -87,8 +84,10 @@ fn = p+1; } - if (cmp(fname, fn) == 0) + if (cmp(fname, fn) == 0) { + _zip_error_clear(error); return i; + } } _zip_error_set(error, ZIP_ER_NOENT, 0);
diff --git a/lib/zip_open.c b/lib/zip_open.c index e9dfa3a..7aebdd3 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -1,6 +1,6 @@ /* zip_open.c -- open zip archive by name - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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 @@ #include "zipint.h" static void set_error(int *, struct zip_error *, int); -static struct zip *_zip_allocate_new(const char *, int *); +static struct zip *_zip_allocate_new(const char *, int, int *); static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); static void _zip_check_torrentzip(struct zip *); static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); @@ -66,8 +66,18 @@ case -1: return NULL; case 0: - return _zip_allocate_new(fn, zep); + return _zip_allocate_new(fn, flags, zep); default: + if (flags & ZIP_TRUNCATE) { + FILE *f; + + if ((f = fopen(fn, "rb")) == NULL) { + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + fclose(f); + return _zip_allocate_new(fn, flags, zep); + } break; } @@ -97,7 +107,7 @@ /* treat empty files as empty archives */ if (len == 0) { - if ((za=_zip_allocate_new(fn, zep)) == NULL) + if ((za=_zip_allocate_new(fn, flags, zep)) == NULL) fclose(fp); else za->zp = fp; @@ -110,7 +120,7 @@ return NULL; } - if ((za=_zip_allocate_new(fn, zep)) == NULL) { + if ((za=_zip_allocate_new(fn, flags, zep)) == NULL) { _zip_cdir_free(cdir); fclose(fp); return NULL; @@ -119,10 +129,12 @@ za->cdir = cdir; za->zp = fp; - if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) - * cdir->nentry)) == NULL) { + if (cdir->nentry == 0) + za->entry = NULL; + else if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) + * cdir->nentry)) == NULL) { set_error(zep, NULL, ZIP_ER_MEMORY); - _zip_free(za); + zip_discard(za); return NULL; } for (i=0; i<cdir->nentry; i++) @@ -275,7 +287,6 @@ } } } - cd->nentry = i; return cd; @@ -312,7 +323,7 @@ } j = cd->entry[i].offset + cd->entry[i].comp_size - + cd->entry[i].filename_len + LENTRYSIZE; + + strlen(cd->entry[i].settable.filename) + LENTRYSIZE; if (j > max) max = j; if (max > cd->offset) { @@ -391,11 +402,9 @@ and global headers for the bitflags */ || (h1->bitflags != h2->bitflags) #endif - || (h1->comp_method != h2->comp_method) + || (h1->settable.comp_method != h2->settable.comp_method) || (h1->last_mod != h2->last_mod) - || (h1->filename_len != h2->filename_len) - || !h1->filename || !h2->filename - || strcmp(h1->filename, h2->filename)) + || strcmp(h1->settable.filename, h2->settable.filename)) return -1; /* check that CRC and sizes are zero if data descriptor is used */ @@ -420,10 +429,10 @@ } if ((local1p == local2p) - && ((h1->extrafield_len != h2->extrafield_len) - || (h1->extrafield_len && h2->extrafield - && memcmp(h1->extrafield, h2->extrafield, - h1->extrafield_len)))) + && ((h1->settable.extrafield_len != h2->settable.extrafield_len) + || (h1->settable.extrafield_len && h2->settable.extrafield + && memcmp(h1->settable.extrafield, h2->settable.extrafield, + h1->settable.extrafield_len)))) return -1; /* if either is local, nothing more to check */ @@ -435,9 +444,9 @@ || (h1->int_attrib != h2->int_attrib) || (h1->ext_attrib != h2->ext_attrib) || (h1->offset != h2->offset) - || (h1->comment_len != h2->comment_len) - || (h1->comment_len && h2->comment - && memcmp(h1->comment, h2->comment, h1->comment_len))) + || (h1->settable.comment_len != h2->settable.comment_len) + || (h1->settable.comment_len && h2->settable.comment + && memcmp(h1->settable.comment, h2->settable.comment, h1->settable.comment_len))) return -1; return 0; @@ -446,7 +455,7 @@ static struct zip * -_zip_allocate_new(const char *fn, int *zep) +_zip_allocate_new(const char *fn, int flags, int *zep) { struct zip *za; struct zip_error error; @@ -461,11 +470,12 @@ else { za->zn = strdup(fn); if (!za->zn) { - _zip_free(za); + zip_discard(za); set_error(zep, NULL, ZIP_ER_MEMORY); return NULL; } } + za->open_flags = flags; return za; }
diff --git a/lib/zip_rename.c b/lib/zip_rename.c index d78bbe8..ea2e676 100644 --- a/lib/zip_rename.c +++ b/lib/zip_rename.c
@@ -45,7 +45,7 @@ const char *old_name; int old_is_dir, new_is_dir; - if (idx >= za->nentry || name[0] == '\0') { + if (idx >= za->nentry || name == NULL || strlen(name) > ZIP_UINT16_MAX) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; }
diff --git a/lib/zip_replace.c b/lib/zip_replace.c index c444e78..e8249f9 100644 --- a/lib/zip_replace.c +++ b/lib/zip_replace.c
@@ -60,23 +60,31 @@ _zip_replace(struct zip *za, zip_uint64_t idx, const char *name, struct zip_source *source) { + zip_uint64_t za_nentry_prev; if (ZIP_IS_RDONLY(za)) { _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + za_nentry_prev = za->nentry; if (idx == ZIP_UINT64_MAX) { if (_zip_entry_new(za) == NULL) return -1; - + idx = za->nentry - 1; + za->entry[idx].changes.valid |= ZIP_DIRENT_COMP_METHOD; + za->entry[idx].changes.comp_method = ZIP_CM_DEFLATE; /* XXX: default */ } + if (name && _zip_set_name(za, idx, name) != 0) { + za->nentry = za_nentry_prev; + return -1; + } + + /* does not change any name related data, so we can do it here; + * needed for a double add of the same file name */ _zip_unchange_data(za->entry+idx); - if (name && _zip_set_name(za, idx, name) != 0) - return -1; - za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry) ? ZIP_ST_ADDED : ZIP_ST_REPLACED); za->entry[idx].source = source;
diff --git a/lib/zip_set_archive_comment.c b/lib/zip_set_archive_comment.c index 3bb85d1..bbb9a73 100644 --- a/lib/zip_set_archive_comment.c +++ b/lib/zip_set_archive_comment.c
@@ -1,6 +1,6 @@ /* zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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> @@ -55,6 +55,11 @@ return -1; } + if (_zip_guess_encoding(comment, len) == ZIP_ENCODING_CP437) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + if (len > 0) { if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) return -1;
diff --git a/lib/zip_set_file_comment.c b/lib/zip_set_file_comment.c index 6ae76a0..bccad10 100644 --- a/lib/zip_set_file_comment.c +++ b/lib/zip_set_file_comment.c
@@ -1,6 +1,6 @@ /* zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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> @@ -34,6 +34,7 @@ #include <stdlib.h> +#include <string.h> #include "zipint.h" @@ -44,6 +45,8 @@ const char *comment, int len) { char *tmpcom; + const char *name; + enum zip_encoding_type com_enc, enc; if (idx >= za->nentry || len < 0 || len > MAXCOMLEN @@ -57,6 +60,20 @@ return -1; } + if ((com_enc=_zip_guess_encoding(comment, len)) == ZIP_ENCODING_CP437) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((name=zip_get_name(za, idx, ZIP_FL_NAME_RAW)) == NULL) + return -1; + enc = _zip_guess_encoding(name, strlen(name)); + + if (enc == ZIP_ENCODING_CP437 && com_enc == ZIP_ENCODING_UTF8) { + _zip_error_set(&za->error, ZIP_ER_ENCMISMATCH, 0); + return -1; + } + if (len > 0) { if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) return -1; @@ -64,9 +81,11 @@ else tmpcom = NULL; - free(za->entry[idx].ch_comment); - za->entry[idx].ch_comment = tmpcom; - za->entry[idx].ch_comment_len = len; + if (za->entry[idx].changes.valid & ZIP_DIRENT_COMMENT) + free(za->entry[idx].changes.comment); + za->entry[idx].changes.comment = tmpcom; + za->entry[idx].changes.comment_len = len; + za->entry[idx].changes.valid |= ZIP_DIRENT_COMMENT; return 0; }
diff --git a/lib/zip_free.c b/lib/zip_set_file_compression.c similarity index 60% copy from lib/zip_free.c copy to lib/zip_set_file_compression.c index 9932c14..25cb5a0 100644 --- a/lib/zip_free.c +++ b/lib/zip_set_file_compression.c
@@ -1,6 +1,6 @@ /* - zip_free.c -- free struct zip - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + zip_set_file_compression.c -- set compression for file in archive + Copyright (C) 2012 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> @@ -33,51 +33,41 @@ -#include <stdlib.h> - #include "zipint.h" -/* _zip_free: - frees the space allocated to a zipfile struct, and closes the - corresponding file. */ - -void -_zip_free(struct zip *za) +ZIP_EXTERN int +zip_set_file_compression(struct zip *za, zip_uint64_t idx, + zip_int32_t method, zip_uint32_t flags) { - int i; - - if (za == NULL) - return; - - if (za->zn) - free(za->zn); - - 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++) { - _zip_entry_free(za->entry+i); - } - free(za->entry); + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } - for (i=0; i<za->nfile; i++) { - if (za->file[i]->error.zip_err == ZIP_ER_OK) { - _zip_error_set(&za->file[i]->error, ZIP_ER_ZIPCLOSED, 0); - za->file[i]->za = NULL; - } + if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return -1; } - free(za->file); + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + /* XXX: needs support for better of deflate/store + * update man page when fixing this */ + if (method == ZIP_CM_DEFAULT) + method = ZIP_CM_DEFLATE; + + if (za->cdir != NULL && idx < za->cdir->nentry && + method == za->cdir->entry[idx].settable.comp_method) + za->entry[idx].changes.valid &= ~ZIP_DIRENT_COMP_METHOD; + else { + za->entry[idx].changes.valid |= ZIP_DIRENT_COMP_METHOD; + za->entry[idx].changes.comp_method = method; + } - free(za); - - return; + return 0; }
diff --git a/lib/zip_set_file_extra.c b/lib/zip_set_file_extra.c index 9b80bde..1a85bff 100644 --- a/lib/zip_set_file_extra.c +++ b/lib/zip_set_file_extra.c
@@ -64,9 +64,11 @@ else tmpext = NULL; - free(za->entry[idx].ch_extra); - za->entry[idx].ch_extra = tmpext; - za->entry[idx].ch_extra_len = len; + if (za->entry[idx].changes.valid & ZIP_DIRENT_EXTRAFIELD) + free(za->entry[idx].changes.extrafield); + za->entry[idx].changes.extrafield = tmpext; + za->entry[idx].changes.extrafield_len = len; + za->entry[idx].changes.valid |= ZIP_DIRENT_EXTRAFIELD; return 0; }
diff --git a/lib/zip_set_name.c b/lib/zip_set_name.c index 2a90601..7b43131 100644 --- a/lib/zip_set_name.c +++ b/lib/zip_set_name.c
@@ -1,6 +1,6 @@ /* zip_set_name.c -- rename helper function - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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,21 @@ _zip_set_name(struct zip *za, zip_uint64_t idx, const char *name) { char *s; + const char *com; + int comlen; zip_int64_t i; + enum zip_encoding_type enc, com_enc; if (idx >= za->nentry || name == NULL) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } + if ((enc=_zip_guess_encoding(name, strlen(name))) == ZIP_ENCODING_CP437) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) { _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); return -1; @@ -59,7 +67,17 @@ /* no effective name change */ if (i == idx) return 0; - + + com = zip_get_file_comment(za, idx, &comlen, ZIP_FL_NAME_RAW); + if (com == NULL) + com_enc = ZIP_ENCODING_ASCII; + else + com_enc = _zip_guess_encoding(com, comlen); + if (com_enc == ZIP_ENCODING_CP437 && enc == ZIP_ENCODING_UTF8) { + _zip_error_set(&za->error, ZIP_ER_ENCMISMATCH, 0); + return -1; + } + if ((s=strdup(name)) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; @@ -68,8 +86,10 @@ if (za->entry[idx].state == ZIP_ST_UNCHANGED) za->entry[idx].state = ZIP_ST_RENAMED; - free(za->entry[idx].ch_filename); - za->entry[idx].ch_filename = s; + if (za->entry[idx].changes.valid & ZIP_DIRENT_FILENAME) + free(za->entry[idx].changes.filename); + za->entry[idx].changes.filename = s; + za->entry[idx].changes.valid |= ZIP_DIRENT_FILENAME; return 0; }
diff --git a/lib/zip_source_filep.c b/lib/zip_source_filep.c index 7e26ff6..8c75c7b 100644 --- a/lib/zip_source_filep.c +++ b/lib/zip_source_filep.c
@@ -65,7 +65,7 @@ if (za == NULL) return NULL; - if (file == NULL || start < 0 || len < -1) { + if (file == NULL || len < -1) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; }
diff --git a/lib/zip_source_window.c b/lib/zip_source_window.c new file mode 100644 index 0000000..0f8f1a9 --- /dev/null +++ b/lib/zip_source_window.c
@@ -0,0 +1,149 @@ +/* + zip_source_window.c -- return part of lower source + Copyright (C) 2012 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 <string.h> + +#include "zipint.h" + +struct window { + zip_uint64_t skip; + zip_uint64_t len; + zip_uint64_t left; + int e[2]; +}; + +static zip_int64_t window_read(struct zip_source *, void *, void *, + zip_uint64_t, enum zip_source_cmd); + + + +ZIP_EXTERN struct zip_source * +zip_source_window(struct zip *za, struct zip_source *src, zip_uint64_t start, zip_uint64_t len) +{ + struct window *ctx; + + if (src == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((ctx=(struct window *)malloc(sizeof(*ctx))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + ctx->skip = start; + ctx->len = len; + ctx->left = len; + + return zip_source_layered(za, src, window_read, ctx); +} + + + +static zip_int64_t +window_read(struct zip_source *src, void *_ctx, void *data, + zip_uint64_t len, enum zip_source_cmd cmd) +{ + struct window *ctx; + zip_int64_t i, n; + char b[8192]; + + ctx = (struct window *)_ctx; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + for (n=0; n<ctx->skip; n+=i) { + i = (ctx->skip-n > sizeof(b) ? sizeof(b) : ctx->skip-n); + if ((i=zip_source_read(src, b, i)) < 0) + return ZIP_SOURCE_ERR_LOWER; + if (i==0) { + ctx->e[0] = ZIP_ER_EOF; + ctx->e[1] = 0; + return -1; + } + } + return 0; + + case ZIP_SOURCE_READ: + if (len > ctx->left) + len = ctx->left; + + if (len <= 0) + return 0; + + if ((n=zip_source_read(src, data, len)) < 0) + return ZIP_SOURCE_ERR_LOWER; + + ctx->left -= n; + + if (n == 0) { + if (ctx->left > 0) { + ctx->e[0] = ZIP_ER_EOF; + ctx->e[1] = 0; + return -1; + } + } + return n; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + + st = (struct zip_stat *)data; + + st->size = ctx->len; + st->valid |= ZIP_STAT_SIZE; + st->valid &= ~(ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE); + } + 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/lib/zip_source_zip.c b/lib/zip_source_zip.c index 2b9061f..7426c4b 100644 --- a/lib/zip_source_zip.c +++ b/lib/zip_source_zip.c
@@ -38,153 +38,19 @@ #include "zipint.h" -struct read_zip { - struct zip_file *zf; - struct zip_stat st; - zip_uint64_t off; - zip_int64_t len; -}; - -static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len, - enum zip_source_cmd cmd); - ZIP_EXTERN struct zip_source * 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; - struct read_zip *p; - - /* XXX: ZIP_FL_RECOMPRESS */ - - if (za == NULL) - return NULL; - - if (srcza == NULL || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((flags & ZIP_FL_UNCHANGED) == 0 - && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) { - _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return NULL; - } - if (len == 0) len = -1; - if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0) + if (start == 0 && len == -1) flags |= ZIP_FL_COMPRESSED; else flags &= ~ZIP_FL_COMPRESSED; - if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - _zip_error_copy(&error, &srcza->error); - - if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0 - || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) { - free(p); - _zip_error_copy(&za->error, &srcza->error); - _zip_error_copy(&srcza->error, &error); - - return NULL; - } - p->off = start; - p->len = len; - - if ((flags & ZIP_FL_COMPRESSED) == 0) { - p->st.size = p->st.comp_size = len; - p->st.comp_method = ZIP_CM_STORE; - p->st.crc = 0; - } - - if ((zs=zip_source_function(za, read_zip, p)) == NULL) { - free(p); - return NULL; - } - - return zs; -} - - - -static 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; - zip_uint64_t n; - - z = (struct read_zip *)state; - buf = (char *)data; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - for (n=0; n<z->off; n+= i) { - i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n); - if ((i=zip_fread(z->zf, b, i)) < 0) { - zip_fclose(z->zf); - z->zf = NULL; - return -1; - } - } - return 0; - - case ZIP_SOURCE_READ: - if (z->len != -1) - n = len > z->len ? z->len : len; - else - n = len; - - - if ((i=zip_fread(z->zf, buf, n)) < 0) - return -1; - - if (z->len != -1) - z->len -= i; - - return i; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: - if (len < sizeof(z->st)) - return -1; - len = sizeof(z->st); - - memcpy(data, &z->st, len); - return len; - - case ZIP_SOURCE_ERROR: - { - int *e; - - if (len < sizeof(int)*2) - return -1; - - e = (int *)data; - zip_file_error_get(z->zf, e, e+1); - } - return sizeof(int)*2; - - case ZIP_SOURCE_FREE: - zip_fclose(z->zf); - free(z); - return 0; - - default: - ; - } - - return -1; + return _zip_source_zip_new(za, srcza, srcidx, flags, start, len, NULL); }
diff --git a/lib/zip_source_zip_new.c b/lib/zip_source_zip_new.c new file mode 100644 index 0000000..b5364a1 --- /dev/null +++ b/lib/zip_source_zip_new.c
@@ -0,0 +1,175 @@ +/* + zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip + Copyright (C) 2012 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" + + + +struct zip_source * +_zip_source_zip_new(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, int flags, + zip_uint64_t start, zip_int64_t len, const char *password) +{ + zip_compression_implementation comp_impl; + zip_encryption_implementation enc_impl; + struct zip_source *src, *s2; + zip_uint64_t offset; + struct zip_stat st; + + if (za == NULL) + return NULL; + + if (srcza == NULL || len < -1 || srcidx >= srcza->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && (ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx) || srcza->entry[srcidx].state == ZIP_ST_DELETED)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (srcza->cdir == NULL || srcidx >= srcza->cdir->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if (flags & ZIP_FL_ENCRYPTED) + flags |= ZIP_FL_COMPRESSED; + + if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if (zip_stat_index(srcza, srcidx, flags, &st) < 0) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return NULL; + } + + if (len == -1) + len = 0; + + /* overflow or past end of file */ + if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + enc_impl = NULL; + if (((flags & ZIP_FL_ENCRYPTED) == 0) && (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 ((offset=_zip_file_get_offset(srcza, srcidx, &za->error)) == 0) + return NULL; + + if (st.comp_size == 0) { + if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL) + return NULL; + } + else { + if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) { + if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset+start, + len ? len : st.size-start, + 0, &st)) == NULL) + return NULL; + } + else { + if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset, st.comp_size, + 0, &st)) == NULL) + return NULL; + } + + if (enc_impl) { + if ((s2=enc_impl(za, src, st.encryption_method, 0, password)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + if (comp_impl) { + if ((s2=comp_impl(za, src, st.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) + && (len == 0 || start+len == st.comp_size)) { + /* when reading the whole file, check for crc errors */ + if ((s2=zip_source_crc(za, src, 1)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + + if (start+len > 0 && (comp_impl || enc_impl)) { + if ((s2=zip_source_window(za, src, start, len ? len : st.size-start)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) (why?) */ + return NULL; + } + src = s2; + } + } + + return src; +}
diff --git a/lib/zip_stat_index.c b/lib/zip_stat_index.c index 0e15b55..771c686 100644 --- a/lib/zip_stat_index.c +++ b/lib/zip_stat_index.c
@@ -71,7 +71,10 @@ st->size = za->cdir->entry[index].uncomp_size; st->mtime = za->cdir->entry[index].last_mod; st->comp_size = za->cdir->entry[index].comp_size; - st->comp_method = za->cdir->entry[index].comp_method; + if ((flags & ZIP_FL_UNCHANGED) == 0 && (za->entry[index].changes.valid & ZIP_DIRENT_COMP_METHOD)) + st->comp_method = za->entry[index].changes.comp_method; + else + st->comp_method = za->cdir->entry[index].settable.comp_method; if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) { if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { /* XXX */
diff --git a/lib/zip_unchange.c b/lib/zip_unchange.c index e64186e..61adf50 100644 --- a/lib/zip_unchange.c +++ b/lib/zip_unchange.c
@@ -57,7 +57,7 @@ return -1; } - if (za->entry[idx].ch_filename) { + if (za->entry[idx].changes.valid & ZIP_DIRENT_FILENAME) { if (!allow_duplicates) { i = _zip_name_locate(za, _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), @@ -68,16 +68,14 @@ } } - free(za->entry[idx].ch_filename); - za->entry[idx].ch_filename = NULL; + free(za->entry[idx].changes.filename); } - 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; + if (za->entry[idx].changes.valid & ZIP_DIRENT_EXTRAFIELD) + free(za->entry[idx].changes.extrafield); + if (za->entry[idx].changes.valid & ZIP_DIRENT_COMMENT) + free(za->entry[idx].changes.comment); + za->entry[idx].changes.valid = 0; _zip_unchange_data(za->entry+idx);
diff --git a/lib/zip_unchange_data.c b/lib/zip_unchange_data.c index 431f2d0..fab51de 100644 --- a/lib/zip_unchange_data.c +++ b/lib/zip_unchange_data.c
@@ -45,6 +45,6 @@ ze->source = NULL; } - ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED; + ze->state = (ze->changes.valid & ZIP_DIRENT_FILENAME) ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED; }
diff --git a/lib/zip_utf-8.c b/lib/zip_utf-8.c new file mode 100644 index 0000000..ab49169 --- /dev/null +++ b/lib/zip_utf-8.c
@@ -0,0 +1,229 @@ +/* + zip_utf-8.c -- UTF-8 support functions for libzip + Copyright (C) 2011-2012 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 "zip.h" +#include "zipint.h" + +#include <stdlib.h> + + + +static const zip_uint16_t _cp437_to_unicode[256] = { + /* 0x00 - 0x0F */ + 0x2007, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + + /* 0x10 - 0x1F */ + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + + /* 0x20 - 0x2F */ + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + + /* 0x30 - 0x3F */ + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + + /* 0x40 - 0x4F */ + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + + /* 0x50 - 0x5F */ + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + + /* 0x60 - 0x6F */ + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + + /* 0x70 - 0x7F */ + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302, + + /* 0x80 - 0x8F */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + + /* 0x90 - 0x9F */ + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + + /* 0xA0 - 0xAF */ + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + + /* 0xB0 - 0xBF */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + + /* 0xC0 - 0xCF */ + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + + /* 0xD0 - 0xDF */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + + /* 0xE0 - 0xEF */ + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + + /* 0xF0 - 0xFF */ + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#define UTF_8_LEN_2_MASK 0xe0 +#define UTF_8_LEN_2_MATCH 0xc0 +#define UTF_8_LEN_3_MASK 0xf0 +#define UTF_8_LEN_3_MATCH 0xe0 +#define UTF_8_LEN_4_MASK 0xf8 +#define UTF_8_LEN_4_MATCH 0xf0 +#define UTF_8_CONTINUE_MASK 0xc0 +#define UTF_8_CONTINUE_MATCH 0x80 + + + +enum zip_encoding_type +_zip_guess_encoding(const zip_uint8_t * const name, zip_uint32_t len) +{ + zip_uint32_t i; + int ret; + int j, ulen; + + ret = ZIP_ENCODING_ASCII; + for (i=0; i<len; i++) { + if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t') + continue; + + ret = ZIP_ENCODING_UTF8; + if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH) + ulen = 1; + else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH) + ulen = 2; + else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH) + ulen = 3; + else + return ZIP_ENCODING_CP437; + + if (i + ulen >= len) + return ZIP_ENCODING_CP437; + + for (j=1; j<=ulen; j++) { + if ((name[i+j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) + return ZIP_ENCODING_CP437; + } + i += ulen; + } + + return ret; +} + + + +static zip_uint32_t +_zip_unicode_to_utf8_len(zip_uint32_t codepoint) +{ + if (codepoint < 0x0080) + return 1; + if (codepoint < 0x0800) + return 2; + if (codepoint < 0x10000) + return 3; + return 4; +} + + + +static zip_uint32_t +_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) +{ + if (codepoint < 0x0080) { + buf[0] = codepoint & 0xff; + return 1; + } + if (codepoint < 0x0800) { + buf[0] = UTF_8_LEN_2_MATCH | ((codepoint >> 6) & 0x1f); + buf[1] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 2; + } + if (codepoint < 0x10000) { + buf[0] = UTF_8_LEN_3_MATCH | ((codepoint >> 12) & 0x0f); + buf[1] = UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f); + buf[2] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 3; + } + buf[0] = UTF_8_LEN_4_MATCH | ((codepoint >> 18) & 0x07); + buf[1] = UTF_8_CONTINUE_MATCH | ((codepoint >> 12) & 0x3f); + buf[2] = UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f); + buf[3] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 4; +} + + + +zip_uint8_t * +_zip_cp437_to_utf8(const zip_uint8_t * const cp437buf, zip_uint32_t len, + zip_uint32_t *utf8_lenp, struct zip_error *error) +{ + zip_uint8_t *utf8buf; + zip_uint32_t buflen, i, offset; + + if (len == 0) { + if (utf8_lenp) + *utf8_lenp = 0; + return NULL; + } + + buflen = 1; + for (i=0; i<len; i++) + buflen += _zip_unicode_to_utf8_len(_cp437_to_unicode[cp437buf[i]]); + + if ((utf8buf=(zip_uint8_t*)malloc(buflen)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + offset = 0; + for (i=0; i<len; i++) + offset += _zip_unicode_to_utf8(_cp437_to_unicode[cp437buf[i]], + utf8buf+offset); + + utf8buf[buflen-1] = 0; + if (utf8_lenp) + *utf8_lenp = buflen-1; + return utf8buf; +}
diff --git a/lib/zipint.h b/lib/zipint.h index 2f748bd..895fbbf 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -3,7 +3,7 @@ /* zipint.h -- internal declarations. - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 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> @@ -160,6 +160,8 @@ 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 *); +ZIP_EXTERN struct zip_source *zip_source_window(struct zip *, struct zip_source *, + zip_uint64_t, zip_uint64_t); /* This function will probably remain private. It is not needed to @@ -184,6 +186,15 @@ #define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ #define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ #define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ +#define ZIP_GPBF_ENCODING_UTF_8 0x0800 /* file name encoding is UTF-8 */ + +/* encoding type */ +enum zip_encoding_type { + ZIP_ENCODING_UNKNOWN, /* not yet analyzed */ + ZIP_ENCODING_ASCII, /* plain ASCII */ + ZIP_ENCODING_UTF8, /* possibly UTF-8 */ + ZIP_ENCODING_CP437 /* Code Page 437 */ +}; /* error information */ @@ -198,6 +209,7 @@ struct zip { char *zn; /* file name */ FILE *zp; /* file */ + int open_flags; /* flags passed to zip_open */ struct zip_error error; /* error information */ unsigned int flags; /* archive global flags */ @@ -228,37 +240,55 @@ /* zip archive directory entry (central or local) */ +#define ZIP_DIRENT_COMP_METHOD 0x0001 +#define ZIP_DIRENT_FILENAME 0x0002 +#define ZIP_DIRENT_COMMENT 0x0004 +#define ZIP_DIRENT_EXTRAFIELD 0x0008 +#define ZIP_DIRENT_ALL 0xffff + +struct zip_dirent_settable { + zip_uint32_t valid; + zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */ + char *filename; /* (cl) file name (NUL-terminated) */ + char *comment; /* (c) file comment */ + zip_uint16_t comment_len; /* (c) length of file comment */ + char *extrafield; /* (cl) extra field */ + zip_uint16_t extrafield_len; /* (cl) length of extra field */ +}; + struct zip_dirent { unsigned short version_madeby; /* (c) version of creator */ unsigned short version_needed; /* (cl) version needed to extract */ unsigned short bitflags; /* (cl) general purpose bit flag */ - unsigned short comp_method; /* (cl) compression method used */ time_t last_mod; /* (cl) time of last modification */ unsigned int crc; /* (cl) CRC-32 of uncompressed data */ - unsigned int comp_size; /* (cl) size of commpressed data */ - unsigned int uncomp_size; /* (cl) size of uncommpressed data */ - char *filename; /* (cl) file name (NUL-terminated) */ - unsigned short filename_len; /* (cl) length of filename (w/o NUL) */ - char *extrafield; /* (cl) extra field */ - unsigned short extrafield_len; /* (cl) length of extra field */ - char *comment; /* (c) file comment */ - unsigned short comment_len; /* (c) length of file comment */ + unsigned int comp_size; /* (cl) size of compressed data */ + unsigned int uncomp_size; /* (cl) size of uncompressed data */ unsigned short disk_number; /* (c) disk number start */ unsigned short int_attrib; /* (c) internal file attributes */ unsigned int ext_attrib; /* (c) external file attributes */ - unsigned int offset; /* (c) offset of local header */ + unsigned int offset; /* (c) offset of local header */ + unsigned short fn_type; /* file name encoding (autorecognition) */ + char *filename_converted; /* file name (autoconverted) */ + unsigned short fc_type; /* file comment encoding (autorecognition) */ + char *comment_converted; /* file comment (autoconverted) */ + zip_uint32_t comment_converted_len; /* file comment length (autoconverted) */ + struct zip_dirent_settable settable; }; /* zip archive central directory */ struct zip_cdir { - struct zip_dirent *entry; /* directory entries */ - int nentry; /* number of entries */ + struct zip_dirent *entry; /* directory entries */ + int nentry; /* number of entries */ - unsigned int size; /* size of central direcotry */ - unsigned int offset; /* offset of central directory in file */ - char *comment; /* zip archive comment */ - unsigned short comment_len; /* length of zip archive comment */ + unsigned int size; /* size of central direcotry */ + unsigned int offset; /* offset of central directory in file */ + char *comment; /* zip archive comment */ + unsigned short comment_len; /* length of zip archive comment */ + unsigned short comment_type; /* archive comment encoding (autorecognition) */ + char *comment_converted; /* archive comment (autoconverted) */ + zip_uint32_t comment_converted_len; /* archive comment length (autoconverted) */ }; @@ -279,11 +309,7 @@ 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; + struct zip_dirent_settable changes; }; @@ -329,19 +355,25 @@ const char *_zip_error_strerror(struct zip_error *); int _zip_file_fillbuf(void *, size_t, struct zip_file *); -unsigned int _zip_file_get_offset(struct zip *, int); +unsigned int _zip_file_get_offset(struct zip *, int, struct zip_error *); int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *); +enum zip_encoding_type _zip_guess_encoding(const zip_uint8_t * const, + zip_uint32_t); +zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t * const, zip_uint32_t, + zip_uint32_t *, struct zip_error *error); + struct zip *_zip_open(const char *, FILE *, int, int, int *); struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, zip_uint64_t, zip_int64_t, int, const struct zip_stat *); struct zip_source *_zip_source_new(struct zip *); +struct zip_source *_zip_source_zip_new(struct zip *, struct zip *, zip_uint64_t, int, + zip_uint64_t, zip_int64_t, const char *); int _zip_changed(struct zip *, int *); -void _zip_free(struct zip *); 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 *);
diff --git a/libzip.pc.in b/libzip.pc.in index f1301be..7ab8986 100644 --- a/libzip.pc.in +++ b/libzip.pc.in
@@ -2,7 +2,7 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ -libincludedir=@libdir@/libzip/include +libincludedir=@libdir@/@PACKAGE@/include zipcmp=@prefix@/bin/zipcmp
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 19c0eaa..53d114b 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt
@@ -4,6 +4,7 @@ zip_add_dir.mdoc zip_close.mdoc zip_delete.mdoc + zip_discard.mdoc zip_error_clear.mdoc zip_error_get.mdoc zip_error_get_sys_type.mdoc @@ -29,6 +30,7 @@ zip_set_archive_flag.mdoc zip_set_default_password.mdoc zip_set_file_comment.mdoc + zip_set_file_compression.mdoc zip_set_file_extra.mdoc zip_source_buffer.mdoc zip_source_file.mdoc
diff --git a/man/Makefile.am b/man/Makefile.am index a4e5a69..9e83698 100644 --- a/man/Makefile.am +++ b/man/Makefile.am
@@ -11,6 +11,7 @@ zip_add_dir.mdoc \ zip_close.mdoc \ zip_delete.mdoc \ + zip_discard.mdoc \ zip_error_clear.mdoc \ zip_error_get.mdoc \ zip_error_get_sys_type.mdoc \ @@ -36,6 +37,7 @@ zip_set_archive_flag.mdoc \ zip_set_default_password.mdoc \ zip_set_file_comment.mdoc \ + zip_set_file_compression.mdoc \ zip_set_file_extra.mdoc \ zip_source_buffer.mdoc \ zip_source_file.mdoc \
diff --git a/man/libzip.man b/man/libzip.man index 68678a9..fef5c4e 100644 --- a/man/libzip.man +++ b/man/libzip.man
@@ -1,5 +1,5 @@ .\" libzip.mdoc \-- general overview of available functions -.\" Copyright (C) 2005-2011 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2005-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH LIBZIP 3 "February 14, 2011" NiH +.TH LIBZIP 3 "February 13, 2012" NiH .SH "NAME" libzip \- library for manipulating zip archives .SH "LIBRARY" @@ -57,6 +57,7 @@ zip_fclose(3) .SS "close archive" zip_close(3) +zip_discard(3) .SS "miscellaneous" zip_stat(3) zip_get_archive_comment(3) @@ -73,6 +74,7 @@ zip_add_dir(3) zip_replace(3) zip_set_file_comment(3) +zip_set_file_compression(3) zip_source_buffer(3) zip_source_file(3) zip_source_filep(3) @@ -87,6 +89,9 @@ zip_unchange(3) zip_unchange_all(3) zip_unchange_archive(3) +.SS "modify extra fields" +zip_get_file_extra(3) +zip_set_file_extra(3) .SS "close archive" zip_close(3) .SS "miscellaneous"
diff --git a/man/libzip.mdoc b/man/libzip.mdoc index 9647f1c..c3e598f 100644 --- a/man/libzip.mdoc +++ b/man/libzip.mdoc
@@ -1,5 +1,5 @@ .\" libzip.mdoc -- general overview of available functions -.\" Copyright (C) 2005-2011 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2005-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 14, 2011 +.Dd February 13, 2012 .Dt LIBZIP 3 .Os .Sh NAME @@ -60,6 +60,7 @@ .Xr zip_fclose 3 .Ss close archive .Xr zip_close 3 +.Xr zip_discard 3 .Ss miscellaneous .Xr zip_stat 3 .Xr zip_get_archive_comment 3 @@ -76,6 +77,7 @@ .Xr zip_add_dir 3 .Xr zip_replace 3 .Xr zip_set_file_comment 3 +.Xr zip_set_file_compression 3 .Xr zip_source_buffer 3 .Xr zip_source_file 3 .Xr zip_source_filep 3 @@ -90,6 +92,9 @@ .Xr zip_unchange 3 .Xr zip_unchange_all 3 .Xr zip_unchange_archive 3 +.Ss modify extra fields +.Xr zip_get_file_extra 3 +.Xr zip_set_file_extra 3 .Ss close archive .Xr zip_close 3 .Ss miscellaneous
diff --git a/man/zip_add.man b/man/zip_add.man index dcf6d31..914f161 100644 --- a/man/zip_add.man +++ b/man/zip_add.man
@@ -1,5 +1,5 @@ .\" zip_add.mdoc \-- add files to zip archive -.\" Copyright (C) 2004-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2004-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_ADD 3 "March 10, 2009" NiH +.TH ZIP_ADD 3 "February 18, 2012" NiH .SH "NAME" zip_add , \- .Nm zip_replace add file to zip archive or replace file in zip archive @@ -110,6 +110,9 @@ or \fBindex\fR is invalid. +This error is also returned when +\fBname\fR +is not a valid UTF-8 encoded string. .TP 4 [ZIP_ER_MEMORY] Required memory could not be allocated.
diff --git a/man/zip_add.mdoc b/man/zip_add.mdoc index bc5c204..b4dfd44 100644 --- a/man/zip_add.mdoc +++ b/man/zip_add.mdoc
@@ -1,5 +1,5 @@ .\" zip_add.mdoc -- add files to zip archive -.\" Copyright (C) 2004-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2004-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 10, 2009 +.Dd February 20, 2012 .Dt ZIP_ADD 3 .Os .Sh NAME @@ -62,6 +62,8 @@ .Ar index specifies which file should be replaced (for .Fn zip_replace ) . +.Ar name +must be encoded in ASCII or UTF-8. The data is obtained from the .Ar source argument. @@ -109,6 +111,9 @@ or .Ar index is invalid. +This error is also returned when +.Ar name +is not a valid UTF-8 encoded string. .It Bq Er ZIP_ER_MEMORY Required memory could not be allocated. .El
diff --git a/man/zip_close.man b/man/zip_close.man index 3fc9a2a..6e599f3 100644 --- a/man/zip_close.man +++ b/man/zip_close.man
@@ -1,5 +1,5 @@ .\" zip_close.mdoc \-- close zip archive -.\" Copyright (C) 2003-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_CLOSE 3 "February 15, 2009" NiH +.TH ZIP_CLOSE 3 "February 13, 2012" NiH .SH "NAME" zip_close \- close zip archive .SH "LIBRARY" @@ -56,6 +56,9 @@ \fBarchive\fR contains no files, the file is completely removed (no empty archive is written). +.PP +To close a zip file without saving changes, use +zip_discard(3). .SH "RETURN VALUES" Upon successful completion 0 is returned. Otherwise, \-1 is returned and the error code in @@ -108,6 +111,7 @@ for added or replaced files will be passed back. .SH "SEE ALSO" libzip(3), +zip_discard(3), zip_error_get(3), zip_fdopen(3), zip_open(3),
diff --git a/man/zip_close.mdoc b/man/zip_close.mdoc index 0db9bb6..3896038 100644 --- a/man/zip_close.mdoc +++ b/man/zip_close.mdoc
@@ -1,5 +1,5 @@ .\" zip_close.mdoc -- close zip archive -.\" Copyright (C) 2003-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 15, 2009 +.Dd February 13, 2012 .Dt ZIP_CLOSE 3 .Os .Sh NAME @@ -58,6 +58,9 @@ .Ar archive contains no files, the file is completely removed (no empty archive is written). +.Pp +To close a zip file without saving changes, use +.Xr zip_discard 3 . .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, \-1 is returned and the error code in @@ -99,6 +102,7 @@ for added or replaced files will be passed back. .Sh SEE ALSO .Xr libzip 3 , +.Xr zip_discard 3 , .Xr zip_error_get 3 , .Xr zip_fdopen 3 , .Xr zip_open 3 ,
diff --git a/man/zip_discard.man b/man/zip_discard.man new file mode 100644 index 0000000..1f2b2b5 --- /dev/null +++ b/man/zip_discard.man
@@ -0,0 +1,56 @@ +.\" zip_discard.mdoc \-- close zip archive and discard changes +.\" Copyright (C) 2012 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. +.\" +.TH ZIP_DISCARD 3 "February 13, 2012" NiH +.SH "NAME" +zip_discard \- close zip archive and discard changes +.SH "LIBRARY" +libzip (-lzip) +.SH "SYNOPSIS" +#include <zip.h> +.PP +void +zip_discard(struct zip *archive); +.SH "DESCRIPTION" +The +zip_discard +function closes +\fBarchive\fR +and frees the memory allocated for it. +Any changes to the archive are not written to disk and discarded. +.SH "SEE ALSO" +libzip(3), +zip_close(3) +.SH "AUTHORS" + +Dieter Baron <dillo@giga.or.at> +and +Thomas Klausner <tk@giga.or.at>
diff --git a/man/zip_discard.mdoc b/man/zip_discard.mdoc new file mode 100644 index 0000000..8512ea7 --- /dev/null +++ b/man/zip_discard.mdoc
@@ -0,0 +1,58 @@ +.\" zip_discard.mdoc -- close zip archive and discard changes +.\" Copyright (C) 2012 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. +.\" +.Dd February 13, 2012 +.Dt ZIP_DISCARD 3 +.Os +.Sh NAME +.Nm zip_discard +.Nd close zip archive and discard changes +.Sh LIBRARY +libzip (-lzip) +.Sh SYNOPSIS +.In zip.h +.Ft void +.Fn zip_discard "struct zip *archive" +.Sh DESCRIPTION +The +.Fn zip_discard +function closes +.Ar archive +and frees the memory allocated for it. +Any changes to the archive are not written to disk and discarded. +.Sh SEE ALSO +.Xr libzip 3 , +.Xr zip_close 3 +.Sh AUTHORS +.An -nosplit +.An Dieter Baron Aq dillo@giga.or.at +and +.An Thomas Klausner Aq tk@giga.or.at
diff --git a/man/zip_fdopen.man b/man/zip_fdopen.man index e08e806..5cccd98 100644 --- a/man/zip_fdopen.man +++ b/man/zip_fdopen.man
@@ -1,5 +1,5 @@ .\" zip_fdopen.mdoc \-- open zip archive using existing file descriptor -.\" Copyright (C) 2009-2010 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2009-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_FDOPEN 3 "February 1, 2010" NiH +.TH ZIP_FDOPEN 3 "February 13, 2012" NiH .SH "NAME" zip_fdopen \- open zip archive using open file descriptor .SH "LIBRARY" @@ -63,8 +63,8 @@ .RS .TP 15 \fBZIP_CHECKCONS\fR -Perform additional consistency checks on the archive, and error if -they fail. +Perform additional stricter consistency checks on the archive, and +error if they fail. .RE .PP If an error occurs and @@ -100,10 +100,10 @@ .TP 4 [ZIP_ER_INCONS] Inconsistencies were found in the file specified by -\fBpath\fR -and +\fBpath.\fR +This error is often caused by specifying \fBZIP_CHECKCONS\fR -was specified. +but can also happen without it. .TP 4 [ZIP_ER_INVAL] The
diff --git a/man/zip_fdopen.mdoc b/man/zip_fdopen.mdoc index 86fdaa3..e070dfc 100644 --- a/man/zip_fdopen.mdoc +++ b/man/zip_fdopen.mdoc
@@ -1,5 +1,5 @@ .\" zip_fdopen.mdoc -- open zip archive using existing file descriptor -.\" Copyright (C) 2009-2010 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2009-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 1, 2010 +.Dd February 13, 2012 .Dt ZIP_FDOPEN 3 .Os .Sh NAME @@ -63,8 +63,8 @@ the following values, or 0 for none of them. .Bl -tag -offset indent -width ZIP_CHECKCONS .It Dv ZIP_CHECKCONS -Perform additional consistency checks on the archive, and error if -they fail. +Perform additional stricter consistency checks on the archive, and +error if they fail. .El .Pp If an error occurs and @@ -98,10 +98,10 @@ .Bl -tag -width Er .It Bq Er ZIP_ER_INCONS Inconsistencies were found in the file specified by -.Ar path -and +.Ar path . +This error is often caused by specifying .Dv ZIP_CHECKCONS -was specified. +but can also happen without it. .It Bq Er ZIP_ER_INVAL The .Ar flags
diff --git a/man/zip_get_archive_comment.mdoc b/man/zip_get_archive_comment.mdoc index dee3317..7f2b3f6 100644 --- a/man/zip_get_archive_comment.mdoc +++ b/man/zip_get_archive_comment.mdoc
@@ -1,5 +1,5 @@ .\" zip_get_archive_comment.mdoc -- get zip archive comment -.\" Copyright (C) 2006 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2006-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd April 23, 2006 +.Dd February 20, 2012 .Dt ZIP_GET_ARCHIVE_COMMENT 3 .Os .Sh NAME @@ -45,8 +45,14 @@ The .Fn zip_get_archive_comment function returns the comment for the entire zip archive. +The name is in UTF-8 encoding unless +.Dv ZIP_FL_NAME_RAW +was specified (see below). This pointer should not be modified or -.Xr free 3 Ap d . +.Xr free 3 Ap d , +and becomes invalid when +.Ar archive +is closed. If .Ar lenp is not @@ -58,6 +64,21 @@ is set to .Dv ZIP_FL_UNCHANGED , the original unchanged comment is returned. +.Pp +Additionally, the following flags are supported: +.Bl -tag -width ZIP_FL_NAME_STRICTXX -offset indent +.It Dv ZIP_FL_NAME_RAW +Return the unmodified archive comment as it is in the ZIP archive. +.It Dv ZIP_FL_NAME_GUESS +(Default.) +Guess the encoding of the archive comment in the ZIP archive and convert it +to UTF-8, if necessary. +.It Dv ZIP_FL_NAME_STRICT +Follow the ZIP specification for file names and extend it to the archive comment, +thus also expecting it in CP-437 encoding. +(ASCII is a subset of CP-437.) +Convert it to UTF-8. +.El .Sh RETURN VALUES Upon successful completion, a pointer to the comment is returned, or
diff --git a/man/zip_get_file_comment.man b/man/zip_get_file_comment.man index aa6b762..0280b9e 100644 --- a/man/zip_get_file_comment.man +++ b/man/zip_get_file_comment.man
@@ -78,6 +78,7 @@ \fBindex\fR is not a valid file index in \fBarchive.\fR +.RE .SH "SEE ALSO" libzip(3), zip_get_archive_comment(3)
diff --git a/man/zip_get_file_comment.mdoc b/man/zip_get_file_comment.mdoc index 780db5f..8e19d76 100644 --- a/man/zip_get_file_comment.mdoc +++ b/man/zip_get_file_comment.mdoc
@@ -1,5 +1,5 @@ .\" zip_get_file_comment.mdoc -- get comment for file in zip -.\" Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner .\" .\" This file is part of libzip, a library to manipulate ZIP files. .\" The authors can be contacted at <libzip@nih.at> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 10, 2009 +.Dd February 20, 2012 .Dt ZIP_GET_FILE_COMMENT 3 .Os .Sh NAME @@ -47,8 +47,14 @@ function returns the comment for the file at position .Ar index in the zip archive. +The name is in UTF-8 encoding unless +.Dv ZIP_FL_NAME_RAW +was specified (see below). This pointer should not be modified or -.Xr free 3 Ap d . +.Xr free 3 Ap d , +and becomes invalid when +.Ar archive +is closed. If .Ar lenp is not @@ -60,6 +66,21 @@ is set to .Dv ZIP_FL_UNCHANGED , the original unchanged comment is returned. +.Pp +Additionally, the following flags are supported: +.Bl -tag -width ZIP_FL_NAME_STRICTXX -offset indent +.It Dv ZIP_FL_NAME_RAW +Return the unmodified comment as it is in the ZIP archive. +.It Dv ZIP_FL_NAME_GUESS +(Default.) +Guess the encoding of the comment in the ZIP archive and convert it +to UTF-8, if necessary. +.It Dv ZIP_FL_NAME_STRICT +Follow the ZIP specification for file names and extend it to file comments, +expecting them to be encoded in CP-437 in the ZIP archive. +(ASCII is a subset of CP-437.) +Convert it to UTF-8. +.El .Sh RETURN VALUES Upon successful completion, a pointer to the comment is returned, or @@ -78,6 +99,7 @@ .Ar index is not a valid file index in .Ar archive . +.El .Sh SEE ALSO .Xr libzip 3 , .Xr zip_get_archive_comment 3
diff --git a/man/zip_get_name.man b/man/zip_get_name.man index 66b7340..65a16b8 100644 --- a/man/zip_get_name.man +++ b/man/zip_get_name.man
@@ -1,5 +1,5 @@ .\" zip_get_name.mdoc \-- get name of file by index -.\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_GET_NAME 3 "January 20, 2005" NiH +.TH ZIP_GET_NAME 3 "February 15, 2012" NiH .SH "NAME" zip_get_name \- get name of file by index .SH "LIBRARY" @@ -46,6 +46,11 @@ \fBindex\fR in \fBarchive.\fR +The name is in UTF-8 encoding unless +\fBZIP_FL_NAME_RAW\fR +was specified (see below). +(ASCII is a subset of UTF-8.) +.PP If \fBflags\fR is set to @@ -54,6 +59,24 @@ The returned string must not be modified or freed, and becomes invalid when \fBarchive\fR is closed. +.PP +Additionally, the following flags are supported: +.RS +.TP 22 +\fBZIP_FL_NAME_RAW\fR +Return the unmodified names as it is in the ZIP archive. +.TP 22 +\fBZIP_FL_NAME_GUESS\fR +(Default.) +Guess the encoding of the name in the ZIP archive and convert it +to UTF-8, if necessary. +.TP 22 +\fBZIP_FL_NAME_STRICT\fR +Follow the ZIP specification and expect CP-437 encoded names in +the ZIP archive. +(ASCII is a subset of CP-437.) +Convert it to UTF-8. +.RE .SH "RETURN VALUES" Upon successful completion, a pointer to the name is returned. Otherwise, @@ -82,6 +105,10 @@ points to an added file and \fBZIP_FL_UNCHANGED\fR is set. +.TP 4 +[ZIP_ER_MEMORY] +Required memory could not be allocated. +.RE .SH "SEE ALSO" libzip(3), zip_name_locate(3)
diff --git a/man/zip_get_name.mdoc b/man/zip_get_name.mdoc index 743f117..15ba09f 100644 --- a/man/zip_get_name.mdoc +++ b/man/zip_get_name.mdoc
@@ -1,5 +1,5 @@ .\" zip_get_name.mdoc -- get name of file by index -.\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 20, 2005 +.Dd February 15, 2012 .Dt ZIP_GET_NAME 3 .Os .Sh NAME @@ -48,6 +48,11 @@ .Ar index in .Ar archive . +The name is in UTF-8 encoding unless +.Dv ZIP_FL_NAME_RAW +was specified (see below). +(ASCII is a subset of UTF-8.) +.Pp If .Ar flags is set to @@ -56,6 +61,21 @@ The returned string must not be modified or freed, and becomes invalid when .Ar archive is closed. +.Pp +Additionally, the following flags are supported: +.Bl -tag -width ZIP_FL_NAME_STRICTXX -offset indent +.It Dv ZIP_FL_NAME_RAW +Return the unmodified names as it is in the ZIP archive. +.It Dv ZIP_FL_NAME_GUESS +(Default.) +Guess the encoding of the name in the ZIP archive and convert it +to UTF-8, if necessary. +.It Dv ZIP_FL_NAME_STRICT +Follow the ZIP specification and expect CP-437 encoded names in +the ZIP archive. +(ASCII is a subset of CP-437.) +Convert it to UTF-8. +.El .Sh RETURN VALUES Upon successful completion, a pointer to the name is returned. Otherwise, @@ -81,6 +101,9 @@ points to an added file and .Dv ZIP_FL_UNCHANGED is set. +.It Bq Er ZIP_ER_MEMORY +Required memory could not be allocated. +.El .Sh SEE ALSO .Xr libzip 3 , .Xr zip_name_locate 3
diff --git a/man/zip_name_locate.man b/man/zip_name_locate.man index e3702df..5c3901a 100644 --- a/man/zip_name_locate.man +++ b/man/zip_name_locate.man
@@ -1,5 +1,5 @@ .\" zip_name_locate.mdoc \-- get index of file by name -.\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_NAME_LOCATE 3 "October 4, 2006" NiH +.TH ZIP_NAME_LOCATE 3 "February 15, 2012" NiH .SH "NAME" zip_name_locate \- get index of file by name .SH "LIBRARY" @@ -58,9 +58,25 @@ .TP 15 \fBZIP_FL_NOCASE\fR Ignore case distinctions. +(Will only work well if the file names are ASCII.) .TP 15 \fBZIP_FL_NODIR\fR Ignore directory part of file name in archive. +.TP 15 +\fBZIP_FL_NAME_RAW\fR +Compare against the unmodified names as it is in the ZIP archive. +.TP 15 +\fBZIP_FL_NAME_GUESS\fR +(Default.) +Guess the encoding of the name in the ZIP archive and convert it +to UTF-8, if necessary, before comparing. +.TP 15 +\fBZIP_FL_NAME_STRICT\fR +Follow the ZIP specification and expect CP-437 encoded names in +the ZIP archive. +(ASCII is a subset of CP-437.) +Convert it to UTF-8 before comparing. +.RE .RE .SH "RETURN VALUES" zip_name_locate @@ -70,15 +86,21 @@ \fBarchive\fR does not contain an entry of that name. .SH "ERRORS" -The zip_name_locate -function fails and sets the error information to -ZIP_ER_NOENT -if no entry of the name +fails if: +.RS +.TP 4 +[ZIP_ER_NOENT] +No entry of the name \fBfname\fR is found in the archive. -If one of the arguments is invalid, the error information is set to -ZIP_ER_INVAL. +.TP 4 +[ZIP_ER_INVAL] +One of the arguments is invalid. +.TP 4 +[ZIP_ER_MEMORY] +Required memory could not be allocated. +.RE .SH "SEE ALSO" libzip(3), zip_get_name(3)
diff --git a/man/zip_name_locate.mdoc b/man/zip_name_locate.mdoc index eeac3ed..e73deac 100644 --- a/man/zip_name_locate.mdoc +++ b/man/zip_name_locate.mdoc
@@ -1,5 +1,5 @@ .\" zip_name_locate.mdoc -- get index of file by name -.\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 4, 2006 +.Dd February 15, 2012 .Dt ZIP_NAME_LOCATE 3 .Os .Sh NAME @@ -59,8 +59,21 @@ .Bl -tag -offset indent -width ZIP_FL_NOCASE .It Dv ZIP_FL_NOCASE Ignore case distinctions. +(Will only work well if the file names are ASCII.) .It Dv ZIP_FL_NODIR Ignore directory part of file name in archive. +.It Dv ZIP_FL_NAME_RAW +Compare against the unmodified names as it is in the ZIP archive. +.It Dv ZIP_FL_NAME_GUESS +(Default.) +Guess the encoding of the name in the ZIP archive and convert it +to UTF-8, if necessary, before comparing. +.It Dv ZIP_FL_NAME_STRICT +Follow the ZIP specification and expect CP-437 encoded names in +the ZIP archive. +(ASCII is a subset of CP-437.) +Convert it to UTF-8 before comparing. +.El .El .Sh RETURN VALUES .Fn zip_name_locate @@ -70,15 +83,18 @@ .Ar archive does not contain an entry of that name. .Sh ERRORS -The .Fn zip_name_locate -function fails and sets the error information to -.Er ZIP_ER_NOENT -if no entry of the name +fails if: +.Bl -tag -width Er +.It Bq Er ZIP_ER_NOENT +No entry of the name .Ar fname is found in the archive. -If one of the arguments is invalid, the error information is set to -.Er ZIP_ER_INVAL . +.It Bq Er ZIP_ER_INVAL +One of the arguments is invalid. +.It Bq Er ZIP_ER_MEMORY +Required memory could not be allocated. +.El .Sh SEE ALSO .Xr libzip 3 , .Xr zip_get_name 3
diff --git a/man/zip_open.man b/man/zip_open.man index 0efd895..08f9bc4 100644 --- a/man/zip_open.man +++ b/man/zip_open.man
@@ -1,5 +1,5 @@ .\" zip_open.mdoc \-- open zip archive -.\" Copyright (C) 2003-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_OPEN 3 "February 15, 2009" NiH +.TH ZIP_OPEN 3 "February 13, 2012" NiH .SH "NAME" zip_open \- open zip archive .SH "LIBRARY" @@ -53,15 +53,19 @@ the following values, or 0 for none of them. .RS .TP 15 +\fBZIP_CHECKCONS\fR +Perform additional stricter consistency checks on the archive, and +error if they fail. +.TP 15 \fBZIP_CREATE\fR Create the archive if it does not exist. .TP 15 \fBZIP_EXCL\fR Error if archive already exists. .TP 15 -\fBZIP_CHECKCONS\fR -Perform additional consistency checks on the archive, and error if -they fail. +\fBZIP_TRUNCATE\fR +If archive exists, ignore its current contents. +In other words, handle it the same way as an empty archive. .RE .PP If an error occurs and @@ -94,10 +98,10 @@ .TP 4 [ZIP_ER_INCONS] Inconsistencies were found in the file specified by -\fBpath\fR -and +\fBpath.\fR +This error is often caused by specifying \fBZIP_CHECKCONS\fR -was specified. +but can also happen without it. .TP 4 [ZIP_ER_INVAL] The
diff --git a/man/zip_open.mdoc b/man/zip_open.mdoc index 1f1a556..0602499 100644 --- a/man/zip_open.mdoc +++ b/man/zip_open.mdoc
@@ -1,5 +1,5 @@ .\" zip_open.mdoc -- open zip archive -.\" Copyright (C) 2003-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 15, 2009 +.Dd February 13, 2012 .Dt ZIP_OPEN 3 .Os .Sh NAME @@ -53,13 +53,16 @@ .Em or Ns No 'ing the following values, or 0 for none of them. .Bl -tag -offset indent -width ZIP_CHECKCONS +.It Dv ZIP_CHECKCONS +Perform additional stricter consistency checks on the archive, and +error if they fail. .It Dv ZIP_CREATE Create the archive if it does not exist. .It Dv ZIP_EXCL Error if archive already exists. -.It Dv ZIP_CHECKCONS -Perform additional consistency checks on the archive, and error if -they fail. +.It Dv ZIP_TRUNCATE +If archive exists, ignore its current contents. +In other words, handle it the same way as an empty archive. .El .Pp If an error occurs and @@ -89,10 +92,10 @@ is set. .It Bq Er ZIP_ER_INCONS Inconsistencies were found in the file specified by -.Ar path -and +.Ar path . +This error is often caused by specifying .Dv ZIP_CHECKCONS -was specified. +but can also happen without it. .It Bq Er ZIP_ER_INVAL The .Ar path
diff --git a/man/zip_rename.man b/man/zip_rename.man index 38c5a02..d0b79e0 100644 --- a/man/zip_rename.man +++ b/man/zip_rename.man
@@ -1,5 +1,5 @@ .\" zip_rename.mdoc \-- rename file in zip archive -.\" Copyright (C) 2003-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_RENAME 3 "March 10, 2009" NiH +.TH ZIP_RENAME 3 "February 18, 2012" NiH .SH "NAME" zip_rename \- rename file in zip archive .SH "LIBRARY" @@ -69,8 +69,8 @@ is not a valid file index in \fBarchive,\fR \fBname is\fR -\fBNULL\fR -or the empty string. +\fBNULL,\fR +the empty string, or not a valid UTF-8 encoded string. Also a file cannot be renamed to a directory or vice versa. Directories are denoted by a trailing slash. .RE
diff --git a/man/zip_rename.mdoc b/man/zip_rename.mdoc index 9c80a1b..c7dbacf 100644 --- a/man/zip_rename.mdoc +++ b/man/zip_rename.mdoc
@@ -1,5 +1,5 @@ .\" zip_rename.mdoc -- rename file in zip archive -.\" Copyright (C) 2003-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2003-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 10, 2009 +.Dd February 20, 2012 .Dt ZIP_RENAME 3 .Os .Sh NAME @@ -48,6 +48,8 @@ .Ar archive is renamed to .Ar name . +.Ar name +must be encoded in ASCII or UTF-8. .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, \-1 is returned and the error code in @@ -59,6 +61,23 @@ .Bl -tag -width Er .It Bq Er ZIP_ER_DELETED The file to be renamed has been deleted from the archive. +.It Bq Er ZIP_ER_ENCMISMATCH +The file comment is encoded in CP437 and the file name is in UTF-8. +Workaround: read out the file comment with +.Xr zip_get_file_comment 3 +and the +.Dv ZIP_FL_GUESS +flag (optionally verify it), then delete it with +.Xr zip_set_file_comment 3 +and a +.Dv NULL +argument. +Finally, set the file name with +.Nm +and reinstate the file comment with +.Xr zip_set_file_comment 3 +using the result from the previous call of +.Xr zip_get_file_comment 3 . .It Bq Er ZIP_ER_EXISTS There is already a file called .Ar name @@ -68,8 +87,8 @@ is not a valid file index in .Ar archive , .Ar name is -.Dv NULL -or the empty string. +.Dv NULL , +the empty string, or not a valid UTF-8 encoded string. Also a file cannot be renamed to a directory or vice versa. Directories are denoted by a trailing slash. .El
diff --git a/man/zip_set_archive_comment.mdoc b/man/zip_set_archive_comment.mdoc index 1e1b602..38a6b38 100644 --- a/man/zip_set_archive_comment.mdoc +++ b/man/zip_set_archive_comment.mdoc
@@ -1,5 +1,5 @@ .\" zip_set_archive_comment.mdoc -- set zip archive comment -.\" Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2006-2012 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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 26, 2007 +.Dd February 20, 2012 .Dt ZIP_SET_ARCHIVE_COMMENT 3 .Os .Sh NAME @@ -53,6 +53,8 @@ and .Ar len is 0, the archive comment will be removed. +.Ar comment +must be encoded in ASCII or UTF-8. .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, \-1 is returned and the error information in @@ -65,7 +67,9 @@ .It Bq Er ZIP_ER_INVAL .Ar len is less than 0 or longer than the maximum comment length in a zip file -(65535). +(65535), or +.Ar comment +is not a valid UTF-8 encoded string. .It Bq Er ZIP_ER_MEMORY Required memory could not be allocated. .El
diff --git a/man/zip_set_file_comment.mdoc b/man/zip_set_file_comment.mdoc index 068304f..62d3c16 100644 --- a/man/zip_set_file_comment.mdoc +++ b/man/zip_set_file_comment.mdoc
@@ -1,5 +1,5 @@ .\" zip_set_file_comment.mdoc -- set comment for file in zip -.\" Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner .\" .\" This file is part of libzip, a library to manipulate ZIP files. .\" The authors can be contacted at <libzip@nih.at> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 10, 2009 +.Dd February 20, 2012 .Dt ZIP_SET_FILE_COMMENT 3 .Os .Sh NAME @@ -58,6 +58,8 @@ and .Ar len is 0, the file comment will be removed. +.Ar comment +must be encoded in ASCII or UTF-8. .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, \-1 is returned and the error information in @@ -67,6 +69,10 @@ .Fn zip_set_file_comment fails if: .Bl -tag -width Er +.It Bq Er ZIP_ER_ENCMISMATCH +The file name is encoded in CP437 and the file comment is in UTF-8. +Workaround: see +.Xr zip_rename 3 . .It Bq Er ZIP_ER_INVAL .Ar index is not a valid file index in @@ -74,7 +80,9 @@ or .Ar len is less than 0 or longer than the maximum comment length in a zip file -(65535). +(65535), or +.Ar comment +is not a valid UTF-8 encoded string. .It Bq Er ZIP_ER_MEMORY Required memory could not be allocated. .El
diff --git a/man/zip_set_file_compression.man b/man/zip_set_file_compression.man new file mode 100644 index 0000000..0571dd2 --- /dev/null +++ b/man/zip_set_file_compression.man
@@ -0,0 +1,114 @@ +.\" zip_set_file_compression.mdoc \-- set compression method and its flags +.\" Copyright (C) 2012 Dieter Baron and Thomas Klausner +.\" +.\" This file is part of libzip, a library to manipulate ZIP files. +.\" 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. +.\" +.TH ZIP_SET_FILE_COMPRESSION 3 "February 27, 2012" NiH +.SH "NAME" +zip_set_file_compression \- set compression method for file in zip +.SH "LIBRARY" +libzip (-lzip) +.SH "SYNOPSIS" +#include <zip.h> +.PP +int +zip_set_file_compression(struct zip *archive, zip_uint64_t index); \ +"zip_int32_t comp" "zip_uint32_t comp_flags" +.SH "DESCRIPTION" +The +zip_set_file_compression +function sets the compression method for the file at position +\fBindex\fR +in the zip archive to +\fBcomp\fR +with the compression method specific +\fBflags.\fR +The +\fBcomp\fR +is the same as returned by +zip_stat(3). +For the +\fBcomp\fR +argument, currently only the following values are supported: +.RS +.TP 19 +\fBZIP_CM_DEFAULT\fR +default compression; currently the same as +\fBZIP_CM_DEFLATE.\fR +.TP 19 +\fBZIP_CM_STORE\fR +Store the file uncompressed. +.TP 19 +\fBZIP_CM_DEFLATE\fR +Deflate the file with the +zlib(3) +algorithm and default options +.RE +.PP +The flags argument is currently ignored. +.\" For the flags argument, the lower 4 bits define the compression +.\" level. +.\" 0 is fastest compression, 15 is highest compression +.\" \fBZIP_COMP_FL_DEFAULT\fR +.\" can be used to specify that the default shall be used. +.\" Further compression method specific flags will be added over time. +.PP +The current compression method for a file in a zip archive can be +determined using +zip_stat(3). +.SH "RETURN VALUES" +Upon successful completion 0 is returned. +Otherwise, \-1 is returned and the error information in +\fBarchive\fR +is set to indicate the error. +.SH "ERRORS" +zip_set_file_compression +fails if: +.RS +.TP 4 +[ZIP_ER_INVAL] +\fBindex\fR +is not a valid file index in +\fBarchive,\fR +or the argument combination is invalid. +.TP 4 +[ZIP_ER_COMPNOTSUPP] +Unsupported compression method requested. +.TP 4 +[ZIP_ER_RDONLY] +Read-only zip file, no changes allowed. +.RE +.SH "SEE ALSO" +libzip(3), +zip_stat(3) +.SH "AUTHORS" + +Dieter Baron <dillo@giga.or.at> +and +Thomas Klausner <tk@giga.or.at>
diff --git a/man/zip_set_file_compression.mdoc b/man/zip_set_file_compression.mdoc index 0036a1a..6cf2f99 100644 --- a/man/zip_set_file_compression.mdoc +++ b/man/zip_set_file_compression.mdoc
@@ -1,5 +1,5 @@ .\" zip_set_file_compression.mdoc -- set compression method and its flags -.\" Copyright (C) 2011 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2012 Dieter Baron and Thomas Klausner .\" .\" This file is part of libzip, a library to manipulate ZIP files. .\" The authors can be contacted at <libzip@nih.at> @@ -29,19 +29,19 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 17, 2011 +.Dd February 27, 2012 .Dt ZIP_SET_FILE_COMPRESSION 3 .Os .Sh NAME .Nm zip_set_file_compression -.Nd set compression method and corresponding options for file in zip +.Nd set compression method for file in zip .Sh LIBRARY libzip (-lzip) .Sh SYNOPSIS .In zip.h .Ft int .Fn zip_set_file_compression "struct zip *archive" "zip_uint64_t index" \ -"zip_uint16_t comp" "zip_uint32_t comp_flags" +"zip_int32_t comp" "zip_uint32_t comp_flags" .Sh DESCRIPTION The .Fn zip_set_file_compression @@ -57,19 +57,30 @@ .Xr zip_stat 3 . For the .Ar comp -argument, currently only the -.\" XXX: adapt to real defines -.Dv DEFLATE -and -.Dv STORE -methods are supported. +argument, currently only the following values are supported: +.Bl -tag -width ZIP_CM_DEFLATE_XX +.It Dv ZIP_CM_DEFAULT +default compression; currently the same as +.Dv ZIP_CM_DEFLATE . +.It Dv ZIP_CM_STORE +Store the file uncompressed. +.It Dv ZIP_CM_DEFLATE +Deflate the file with the +.Xr zlib 3 +algorithm and default options +.El .Pp -For the flags argument, the lower 4 bits define the compression -level. -0 is fastest compression, 15 is highest compression -.Dv ZIP_COMP_FL_DEFAULT -can be used to specify that the default shall be used. -Further compression method specific flags will be added over time. +The flags argument is currently ignored. +.\" For the flags argument, the lower 4 bits define the compression +.\" level. +.\" 0 is fastest compression, 15 is highest compression +.\" .Dv ZIP_COMP_FL_DEFAULT +.\" can be used to specify that the default shall be used. +.\" Further compression method specific flags will be added over time. +.Pp +The current compression method for a file in a zip archive can be +determined using +.Xr zip_stat 3 . .Sh RETURN VALUES Upon successful completion 0 is returned. Otherwise, \-1 is returned and the error information in @@ -84,8 +95,10 @@ is not a valid file index in .Ar archive , or the argument combination is invalid. -.\" .It Bq Er ZIP_ER_MEMORY -.\" Required memory could not be allocated. +.It Bq Er ZIP_ER_COMPNOTSUPP +Unsupported compression method requested. +.It Bq Er ZIP_ER_RDONLY +Read-only zip file, no changes allowed. .El .Sh SEE ALSO .Xr libzip 3 ,
diff --git a/man/zip_source_function.man b/man/zip_source_function.man index 1b7a19b..4a5686b 100644 --- a/man/zip_source_function.man +++ b/man/zip_source_function.man
@@ -1,5 +1,5 @@ .\" zip_source_function.mdoc \-- create data source from function -.\" Copyright (C) 2004-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2004-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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.TH ZIP_SOURCE_FUNCTION 3 "March 30, 2009" NiH +.TH ZIP_SOURCE_FUNCTION 3 "March 22, 2011" NiH .SH "NAME" zip_source_function \- create data source from function .SH "LIBRARY" @@ -94,6 +94,10 @@ Information only available after the source has been read (e.g. size) can be omitted in an earlier call. Return sizeof(struct zip_stat) on success, \-1 on error. +.I NOTE : +zip_source_function +may be called with this argument even after being called with +\fBZIP_SOURCE_CLOSE.\fR .TP 21 \fBZIP_SOURCE_ERROR\fR Get error information.
diff --git a/man/zip_source_function.mdoc b/man/zip_source_function.mdoc index 5fbfef8..4cf7ba6 100644 --- a/man/zip_source_function.mdoc +++ b/man/zip_source_function.mdoc
@@ -1,5 +1,5 @@ .\" zip_source_function.mdoc -- create data source from function -.\" Copyright (C) 2004-2009 Dieter Baron and Thomas Klausner +.\" Copyright (C) 2004-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> @@ -29,7 +29,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 30, 2009 +.Dd March 22, 2011 .Dt ZIP_SOURCE_FUNCTION 3 .Os .Sh NAME @@ -92,6 +92,10 @@ Information only available after the source has been read (e.g. size) can be omitted in an earlier call. Return sizeof(struct zip_stat) on success, \-1 on error. +.Em NOTE : +.Fn zip_source_function +may be called with this argument even after being called with +.Dv ZIP_SOURCE_CLOSE . .It Dv ZIP_SOURCE_ERROR Get error information. .Ar data
diff --git a/man/zip_stat.man b/man/zip_stat.man index ff5cf99..5b93286 100644 --- a/man/zip_stat.man +++ b/man/zip_stat.man
@@ -102,31 +102,31 @@ before accessing the fields: .RS .TP 30 -ZIP_STAT_NAME +\fBZIP_STAT_NAME\fR \fBname\fR .TP 30 -ZIP_STAT_INDEX +\fBZIP_STAT_INDEX\fR \fBindex\fR .TP 30 -ZIP_STAT_SIZE +\fBZIP_STAT_SIZE\fR \fBsize\fR .TP 30 -ZIP_STAT_COMP_SIZE +\fBZIP_STAT_COMP_SIZE\fR \fBcomp_size\fR .TP 30 -ZIP_STAT_MTIME +\fBZIP_STAT_MTIME\fR \fBmtime\fR .TP 30 -ZIP_STAT_CRC +\fBZIP_STAT_CRC\fR \fBcrc\fR .TP 30 -ZIP_STAT_COMP_METHOD +\fBZIP_STAT_COMP_METHOD\fR \fBcomp_method\fR .TP 30 -ZIP_STAT_ENCRYPTION_METHOD +\fBZIP_STAT_ENCRYPTION_METHOD\fR \fBencryption_method\fR .TP 30 -ZIP_STAT_FLAGS +\fBZIP_STAT_FLAGS\fR \fBflags\fR .RE .SH "RETURN VALUES"
diff --git a/man/zip_stat.mdoc b/man/zip_stat.mdoc index 3d4db87..052e690 100644 --- a/man/zip_stat.mdoc +++ b/man/zip_stat.mdoc
@@ -101,23 +101,23 @@ .Ar valid before accessing the fields: .Bl -tag -width ZIP_STAT_ENCRYPTION_METHODXX -compact -offset indent -.It ZIP_STAT_NAME +.It Dv ZIP_STAT_NAME .Ar name -.It ZIP_STAT_INDEX +.It Dv ZIP_STAT_INDEX .Ar index -.It ZIP_STAT_SIZE +.It Dv ZIP_STAT_SIZE .Ar size -.It ZIP_STAT_COMP_SIZE +.It Dv ZIP_STAT_COMP_SIZE .Ar comp_size -.It ZIP_STAT_MTIME +.It Dv ZIP_STAT_MTIME .Ar mtime -.It ZIP_STAT_CRC +.It Dv ZIP_STAT_CRC .Ar crc -.It ZIP_STAT_COMP_METHOD +.It Dv ZIP_STAT_COMP_METHOD .Ar comp_method -.It ZIP_STAT_ENCRYPTION_METHOD +.It Dv ZIP_STAT_ENCRYPTION_METHOD .Ar encryption_method -.It ZIP_STAT_FLAGS +.It Dv ZIP_STAT_FLAGS .Ar flags .El .Sh RETURN VALUES
diff --git a/regress/CMakeLists.txt b/regress/CMakeLists.txt index bf62886..cb5873c 100644 --- a/regress/CMakeLists.txt +++ b/regress/CMakeLists.txt
@@ -6,6 +6,7 @@ add_from_filep add_from_zip encrypt + fopen_unchanged fread get_comment name_locate @@ -16,15 +17,49 @@ ) SET(HELPER_TEST_PROGRAMS + modify + rename + set_compression + stat_index tryopen ) SET(EXTRA_TESTS + delete_add_same.test + delete_invalid.test + delete_last.test + delete_multiple_last.test + delete_multiple_partial.test + delete_renamed_rename.test + file_comment_encmismatch.test + open_cons_extrabytes.test + open_empty.test + open_empty_2.test + open_extrabytes.test open_new_but_exists.test open_new_ok.test open_nonarchive.test open_nosuchfile.test open_ok.test + open_truncate.test + rename_ascii.test + rename_cp437.test + rename_deleted.test + rename_fail.test + rename_ok.test + rename_utf8.test + rename_utf8_encmismatch.test + set_compression_deflate_to_deflate.test + set_compression_deflate_to_store.test + set_compression_store_to_deflate.test + set_compression_store_to_store.test + set_compression_unknown.test + stat_index_cp437_guess.test + stat_index_cp437_raw.test + stat_index_cp437_strict.test + stat_index_utf8_guess.test + stat_index_utf8_raw.test + stat_index_utf8_strict.test ) SET(ENV{srcdir} ${CMAKE_CURRENT_SOURCE_DIR}) @@ -44,4 +79,5 @@ ENDFOREACH(CASE ${EXTRA_TESTS}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../lib + ${CMAKE_CURRENT_SOURCE_DIR}/../src ${CMAKE_CURRENT_BINARY_DIR}/..)
diff --git a/regress/Makefile.am b/regress/Makefile.am index 0f9ef05..58cbcb0 100644 --- a/regress/Makefile.am +++ b/regress/Makefile.am
@@ -5,17 +5,20 @@ add_from_filep \ add_from_zip \ encrypt \ + fopen_unchanged \ fread \ get_comment \ + modify \ name_locate \ + rename \ set_comment_all \ set_comment_localonly \ set_comment_removeglobal \ set_comment_revert \ + set_compression \ + stat_index \ tryopen -EXTRA_PROGRAMS=deltest ziptest - EXTRA_DIST= \ CMakeLists.txt \ runtest \ @@ -23,13 +26,23 @@ broken.zip \ encrypt.zip \ manyfiles.zip \ + rename_ok.zip \ test.zip \ + test2.zip \ + test-cp437.zip \ + test-cp437-fc.zip \ + test-utf8.zip \ + test-utf8-unmarked.zip \ testbuffer.zip \ testdir.zip \ testchanged.zip \ testchangedlocal.zip \ testcomment.zip \ + testcomment13.zip \ testcommentremoved.zip \ + testdeflated.zip \ + testempty.zip \ + testextrabytes.zip \ testfile.txt \ testfile.zip \ testnottorrent.zip \ @@ -42,27 +55,64 @@ add_dir.test \ add_from_buffer.test \ add_from_file.test \ + add_from_file_duplicate.test \ + add_from_file_twice_duplicate.test \ add_from_filep.test \ add_from_zip.test \ + delete_add_same.test \ + delete_invalid.test \ + delete_last.test \ + delete_multiple_last.test \ + delete_multiple_partial.test \ + delete_renamed_rename.test \ encrypt.test \ + file_comment_encmismatch.test \ + fopen_unchanged.test \ fread.test \ get_comment.test \ name_locate.test \ + open_cons_extrabytes.test \ + open_empty.test \ + open_empty_2.test \ + open_extrabytes.test \ open_many_ok.test \ open_new_but_exists.test \ open_new_ok.test \ open_nonarchive.test \ open_nosuchfile.test \ open_ok.test \ + open_truncate.test \ + rename_ascii.test \ + rename_cp437.test \ + rename_deleted.test \ + rename_fail.test \ + rename_ok.test \ + rename_utf8.test \ + rename_utf8_encmismatch.test \ set_comment_all.test \ set_comment_localonly.test \ set_comment_removeglobal.test \ set_comment_revert.test \ + set_compression_deflate_to_deflate.test \ + set_compression_deflate_to_store.test \ + set_compression_store_to_deflate.test \ + set_compression_store_to_store.test \ + set_compression_unknown.test \ + stat_index_cp437_guess.test \ + stat_index_cp437_raw.test \ + stat_index_cp437_strict.test \ + stat_index_utf8_guess.test \ + stat_index_utf8_raw.test \ + stat_index_utf8_strict.test \ + stat_index_utf8_unmarked_strict.test \ torrent-already.test \ torrent-new.test -# problems with comparing stderr output -NOTYET= \ - add_from_file_duplicate.test -AM_CPPFLAGS=-I${top_srcdir}/lib +DISABLED_TESTS= \ + encoding-ascii.test \ + encoding-cp437.test \ + encoding-cp437-all.test \ + encoding-utf-8.test + +AM_CPPFLAGS=-I${top_srcdir}/lib -I../lib -I${top_srcdir}/src LDADD=${top_builddir}/lib/libzip.la
diff --git a/regress/add_dir.c b/regress/add_dir.c index ddd6758..6294d97 100644 --- a/regress/add_dir.c +++ b/regress/add_dir.c
@@ -67,7 +67,7 @@ if ((za=zip_open(archive, ZIP_CREATE, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); - fprintf(stderr, "%s: can't open zip archive %s: %s\n", prg, + fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, archive, buf); return 1; } @@ -81,8 +81,8 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive %s\n", prg, - archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(za)); return 1; }
diff --git a/regress/add_from_buffer.c b/regress/add_from_buffer.c index 40efd21..f3fa7e9 100644 --- a/regress/add_from_buffer.c +++ b/regress/add_from_buffer.c
@@ -64,7 +64,7 @@ if ((za=zip_open(archive, ZIP_CREATE, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); - fprintf(stderr, "%s: can't open zip archive %s: %s\n", prg, + fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, archive, buf); return 1; } @@ -83,8 +83,8 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive %s\n", prg, - archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(za)); return 1; }
diff --git a/regress/add_from_file.c b/regress/add_from_file.c index cbcf5d9..d4decbd 100644 --- a/regress/add_from_file.c +++ b/regress/add_from_file.c
@@ -52,45 +52,50 @@ struct zip_source *zs; char buf[100]; int err; + int i; + int ret = 0; prg = argv[0]; - if (argc != 3) { - fprintf(stderr, "usage: %s archive file\n", prg); + if (argc < 3) { + fprintf(stderr, "usage: %s archive file [file ...]\n", prg); return 1; } archive = argv[1]; - file = argv[2]; - if ((za=zip_open(archive, ZIP_CREATE, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); - fprintf(stderr, "%s: can't open zip archive %s: %s\n", prg, + fprintf(stderr, "can't open zip archive `%s': %s\n", archive, buf); return 1; } - if ((zs=zip_source_file(za, file, 0, -1)) == NULL) { - fprintf(stderr, "%s: error creating file source for `%s': %s\n", prg, - file, zip_strerror(za)); - return 1; - } + for (i=2; i<argc; i++) { + file = argv[i]; + + if ((zs=zip_source_file(za, file, 0, -1)) == NULL) { + fprintf(stderr, "error creating file source for `%s': %s\n", + file, zip_strerror(za)); + ret = 1; + continue; + } - if ((name=strrchr(file, '/')) == NULL) - name = file; + if ((name=strrchr(file, '/')) == NULL) + name = file; - if (zip_add(za, name, zs) == -1) { - zip_source_free(zs); - fprintf(stderr, "%s: can't add file `%s': %s\n", prg, - file, zip_strerror(za)); - return 1; + if (zip_add(za, name, zs) == -1) { + zip_source_free(zs); + fprintf(stderr, "can't add file `%s': %s\n", + file, zip_strerror(za)); + ret = 1; + } } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, - archive); + fprintf(stderr, "can't close zip archive `%s': %s\n", + archive, zip_strerror(za)); return 1; } - return 0; + return ret; }
diff --git a/regress/add_from_file_twice_duplicate.test b/regress/add_from_file_twice_duplicate.test new file mode 100644 index 0000000..287624c --- /dev/null +++ b/regress/add_from_file_twice_duplicate.test
@@ -0,0 +1,7 @@ +# add file to zip twice, making duplicate names +program add_from_file +return 1 +args testfile.zip testfile.txt testfile.txt +file testfile.txt testfile.txt testfile.txt +file-new testfile.zip testfile.zip +stderr can't add file `testfile.txt': File already exists
diff --git a/regress/add_from_filep.c b/regress/add_from_filep.c index 059e957..e4edb35 100644 --- a/regress/add_from_filep.c +++ b/regress/add_from_filep.c
@@ -66,7 +66,7 @@ if ((za=zip_open(archive, ZIP_CREATE, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); - fprintf(stderr, "%s: can't open zip archive %s: %s\n", prg, + fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, archive, buf); return 1; } @@ -94,8 +94,8 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, - archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(za)); return 1; }
diff --git a/regress/add_from_zip.c b/regress/add_from_zip.c index f509fb7..bdea8c5 100644 --- a/regress/add_from_zip.c +++ b/regress/add_from_zip.c
@@ -68,7 +68,7 @@ if ((z_in=zip_open(source, ZIP_CHECKCONS, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); - fprintf(stderr, "%s: can't open source zip archive %s: %s\n", prg, + fprintf(stderr, "%s: can't open source zip archive `%s': %s\n", prg, source, buf); return 1; } @@ -101,8 +101,8 @@ } if (zip_close(z_out) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, - archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(z_out)); return 1; }
diff --git a/regress/add_from_zip.test b/regress/add_from_zip.test index 53dcfd7..0a20c2e 100644 --- a/regress/add_from_zip.test +++ b/regress/add_from_zip.test
@@ -1,6 +1,6 @@ # add file from zip to zip program add_from_zip return 0 -args teststored.zip testfile.zip empty.txt +args teststored.zip testfile.zip abac-repeat.txt file teststored.zip teststored.zip teststored.zip file-new testfile.zip teststored.zip
diff --git a/regress/add_invalid.c b/regress/add_invalid.c deleted file mode 100644 index 01b2e27..0000000 --- a/regress/add_invalid.c +++ /dev/null
@@ -1,46 +0,0 @@ -#include "zip.h" -#include "error.h" - -char *prg; -#define BUFSIZE 65536 - -int -main(int argc, char *argv[]) -{ - struct zip *za, *destza; - - prg = argv[0]; - - if (argc != 3) { - myerror(ERRDEF, "call with two options: src dest\n"); - return 1; - } - - seterrinfo(NULL, argv[1]); - if ((za=zip_open(argv[1], 0))==NULL) { - myerror(ERRZIPSTR, "can't open file: %s", zip_err_str[zip_err]); - return 1; - } - - seterrinfo(NULL, argv[2]); - if ((destza=zip_open(argv[2], ZIP_CREATE))==NULL) { - myerror(ERRZIPSTR, "can't open file: %s", zip_err_str[zip_err]); - return 1; - } - - if (zip_add_zip(destza, NULL, NULL, za, 1, 0, 0) == -1) - myerror(ERRZIPSTR, "can't add file to zip-file: %s", zip_err_str[zip_err]); - - if (zip_close(destza)!=0) { - myerror(ERRZIPSTR, "can't close file: %s", zip_err_str[zip_err]); - return 1; - } - - seterrinfo(NULL, argv[1]); - if (zip_close(za)!=0) { - myerror(ERRZIPSTR, "can't close file %s", zip_err_str[zip_err]); - return 1; - } - - return 0; -}
diff --git a/regress/mkname.c b/regress/cp437.c similarity index 69% rename from regress/mkname.c rename to regress/cp437.c index 647e836..8ead593 100644 --- a/regress/mkname.c +++ b/regress/cp437.c
@@ -1,6 +1,6 @@ /* - mkname.c -- add srcdir to name - Copyright (C) 2005 Dieter Baron and Thomas Klausner + cp437.c -- tool for CP437 decoding tests + Copyright (C) 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> @@ -31,49 +31,32 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - - #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "mkname.h" +#include "zip.h" +#include "zipint.h" - - -const char * -mkname(const char *name) +int +main(int argc, char *argv[]) { - static const char *srcdir; - static char *fullname; - static int len = 0; - static int srcdir_done = 0; + unsigned char in[256]; + unsigned char *out; + int i; + struct zip_error err; - int nlen; - - if (!srcdir_done) { - srcdir = getenv("SRCDIR"); - srcdir_done = 1; +#if 0 + if (argc != 1) { + fprintf(stderr, "usage: %s\n", argv[0]); + exit(1); } +#endif + for (i=0; i<256; i++) + in[i] = i+1; - if (!srcdir) - return name; + out = _zip_cp437_to_utf8(in, 256, &err); + printf("UTF-8 version: %s\n", out ? (char *)out : "(conversion error)"); - nlen = strlen(srcdir) + strlen(name) + 2; - - if (nlen > len) { - if (len == 0) - fullname = malloc(nlen); - else - fullname = realloc(fullname, nlen); - - if (fullname == NULL) { - fprintf(stderr, "malloc failure\n"); - exit(2); - } - } - - sprintf(fullname, "%s/%s", srcdir, name); - - return fullname; + exit(0); }
diff --git a/regress/delete_add_same.test b/regress/delete_add_same.test new file mode 100644 index 0000000..7974d89 --- /dev/null +++ b/regress/delete_add_same.test
@@ -0,0 +1,5 @@ +# delete entry in zip archive then add file of same name +program modify +return 0 +args testfile.zip delete 0 add testfile.txt test +file testfile.zip testfile.zip test2.zip
diff --git a/regress/delete_invalid.test b/regress/delete_invalid.test new file mode 100644 index 0000000..82e9bcf --- /dev/null +++ b/regress/delete_invalid.test
@@ -0,0 +1,6 @@ +# delete last entry in zip archive +program modify +return 0 +args testfile.zip delete 5 +file testfile.zip testfile.zip testfile.zip +stderr can't delete file at index `5': Invalid argument
diff --git a/regress/delete_last.test b/regress/delete_last.test new file mode 100644 index 0000000..cd2ab6b --- /dev/null +++ b/regress/delete_last.test
@@ -0,0 +1,5 @@ +# delete last entry in zip archive +program modify +return 0 +args testfile.zip delete 0 +file-del testfile.zip testfile.zip
diff --git a/regress/delete_multiple_last.test b/regress/delete_multiple_last.test new file mode 100644 index 0000000..441a9b3 --- /dev/null +++ b/regress/delete_multiple_last.test
@@ -0,0 +1,5 @@ +# delete multiple entries in zip archive, emptying it +program modify +return 0 +args testfile.zip delete 0 delete 1 delete 2 delete 3 +file-del testfile.zip testcomment.zip
diff --git a/regress/delete_multiple_partial.test b/regress/delete_multiple_partial.test new file mode 100644 index 0000000..9e6dcc5 --- /dev/null +++ b/regress/delete_multiple_partial.test
@@ -0,0 +1,5 @@ +# delete some entries in zip archive +program modify +return 0 +args testfile.zip delete 1 delete 3 +file testfile.zip testcomment.zip testcomment13.zip
diff --git a/regress/delete_renamed_rename.test b/regress/delete_renamed_rename.test new file mode 100644 index 0000000..f60895b --- /dev/null +++ b/regress/delete_renamed_rename.test
@@ -0,0 +1,5 @@ +# delete renamed entry in zip archive then rename file to same name +program modify +return 0 +args testfile.zip rename 0 something add test test delete 0 rename 1 testfile.txt +file testfile.zip testfile.zip test2.zip
diff --git a/regress/deltest.c b/regress/deltest.c deleted file mode 100644 index 87991e5..0000000 --- a/regress/deltest.c +++ /dev/null
@@ -1,37 +0,0 @@ -#include "zip.h" -#include "error.h" - -char *prg; -#define BUFSIZE 65536 - -int -main(int argc, char *argv[]) -{ - struct zip *za; - - if (argc != 2) { - fprintf(stderr, "%s: call with one option: zip-file. First file" - " in zip-file will be deleted\n", argv[0]); - return 1; - } - - if ((za=zip_open(argv[1], ZIP_CHECKCONS))==NULL) { - fprintf(stderr, "%s: can't open '%s': %s\n", argv[0], argv[1], - zip_err_str[zip_err]); - return 1; - } - - if (zip_delete(za, 0)< 0) { - fprintf(stderr, "%s: can't delete first file in '%s': %s", - argv[0], argv[1], zip_err_str[zip_err]); - return 1; - } - - if (zip_close(za)!=0) { - fprintf(stderr, "%s: can't close file '%s': %s", argv[0], argv[1], - zip_err_str[zip_err]); - return 1; - } - - return 0; -}
diff --git a/regress/encoding-ascii.test b/regress/encoding-ascii.test new file mode 100644 index 0000000..5d086f8 --- /dev/null +++ b/regress/encoding-ascii.test
@@ -0,0 +1,5 @@ +# recognize ASCII +program encoding +return 0 +args ABC%^&&*!@#_.as./- +stdout guessing ABC%^&&*!@#_.as./-: ASCII
diff --git a/regress/encoding-cp437-all.test b/regress/encoding-cp437-all.test new file mode 100644 index 0000000..1e5ca73 --- /dev/null +++ b/regress/encoding-cp437-all.test
@@ -0,0 +1,5 @@ +# convert all CP437 +program cp437 +return 0 +args "" +stdout UTF-8 version: ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■
diff --git a/regress/encoding-cp437.test b/regress/encoding-cp437.test new file mode 100644 index 0000000..184c477 --- /dev/null +++ b/regress/encoding-cp437.test
@@ -0,0 +1,6 @@ +# recognize CP437 +program encoding +return 0 +args TestAá^$ +stdout guessing TestAá^$: CP437 +stdout UTF-8 version: TestÄÖAÜß^$
diff --git a/regress/encoding-utf-8.test b/regress/encoding-utf-8.test new file mode 100644 index 0000000..74e431b --- /dev/null +++ b/regress/encoding-utf-8.test
@@ -0,0 +1,5 @@ +# recognize UTF-8 +program encoding +return 0 +args TestÄÖAÜß^$ +stdout guessing TestÄÖAÜß^$: UTF-8
diff --git a/regress/mkname.c b/regress/encoding.c similarity index 68% copy from regress/mkname.c copy to regress/encoding.c index 647e836..7ba76d0 100644 --- a/regress/mkname.c +++ b/regress/encoding.c
@@ -1,6 +1,6 @@ /* - mkname.c -- add srcdir to name - Copyright (C) 2005 Dieter Baron and Thomas Klausner + encoding.c -- tool for encoding tests + Copyright (C) 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> @@ -31,49 +31,37 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - - #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "mkname.h" +#include "zip.h" +#include "zipint.h" - +const char *result[] = { + "ASCII", + "UTF-8", + "CP437" +}; -const char * -mkname(const char *name) +int +main(int argc, char *argv[]) { - static const char *srcdir; - static char *fullname; - static int len = 0; - static int srcdir_done = 0; + int ret; + const char *conv = NULL; + struct zip_error err; - int nlen; + if (argc != 2) { + fprintf(stderr, "usage: %s string_to_guess\n", argv[0]); + exit(1); + } + ret = _zip_guess_encoding((const zip_uint8_t *)argv[1], strlen(argv[1])); - if (!srcdir_done) { - srcdir = getenv("SRCDIR"); - srcdir_done = 1; + printf("guessing %s: %s\n", argv[1], result[ret]); + if (ret == ZIP_ENCODING_CP437) { + conv = (const char *)_zip_cp437_to_utf8((const zip_uint8_t *)argv[1], strlen(argv[1]), &err); + printf("UTF-8 version: %s\n", conv ? conv : "(conversion error)"); } - if (!srcdir) - return name; - - nlen = strlen(srcdir) + strlen(name) + 2; - - if (nlen > len) { - if (len == 0) - fullname = malloc(nlen); - else - fullname = realloc(fullname, nlen); - - if (fullname == NULL) { - fprintf(stderr, "malloc failure\n"); - exit(2); - } - } - - sprintf(fullname, "%s/%s", srcdir, name); - - return fullname; + exit(0); }
diff --git a/regress/encrypt.c b/regress/encrypt.c index d5b00ca..41a879e 100644 --- a/regress/encrypt.c +++ b/regress/encrypt.c
@@ -77,7 +77,7 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; }
diff --git a/regress/file_comment_encmismatch.test b/regress/file_comment_encmismatch.test new file mode 100644 index 0000000..18fa655 --- /dev/null +++ b/regress/file_comment_encmismatch.test
@@ -0,0 +1,6 @@ +# set file comment to UTF-8 for CP437 encoded filename (fails) +program modify +return 0 +args testfile file_comment 0 ÄÖÜßäöü +file testfile test-cp437.zip test-cp437.zip +stderr can't set file comment at index `0' to `ÄÖÜßäöü': Encoding of name and comment do not match
diff --git a/regress/fileadd.c b/regress/fileadd.c deleted file mode 100644 index 83ce168..0000000 --- a/regress/fileadd.c +++ /dev/null
@@ -1,38 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include "zip.h" - -int -main(int argc, char *argv[]) -{ - struct zip *za; - int i; - - if (argc < 3) { - fprintf(stderr, "%s: need at least two arguments: zipfile" - " and files to add\n", argv[0]); - exit(1); - } - - if ((za=zip_open(argv[1], ZIP_CHECKCONS|ZIP_CREATE)) == NULL) { - fprintf(stderr, "%s: can't open zipfile %s: %s\n", argv[0], - argv[1], zip_err_str[zip_err]); - exit(1); - } - - for (i=0; i<argc-2; i++) - if (zip_add_file(za, NULL, NULL, argv[i+2], 0, -1)==-1) { - fprintf(stderr, "%s: can't add file %s: %s\n", argv[0], - argv[i+2], zip_err_str[zip_err]); - exit(1); - } - - if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zipfile %s: %s\n", argv[0], - argv[1], zip_err_str[zip_err]); - exit(1); - } - - return 0; -}
diff --git a/regress/fopen_unchanged.c b/regress/fopen_unchanged.c new file mode 100644 index 0000000..2df665f --- /dev/null +++ b/regress/fopen_unchanged.c
@@ -0,0 +1,99 @@ +/* + fopen_unchanged.c -- test case for adding file and reading from unchanged + Copyright (C) 2012 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 <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "zip.h" + +const char *teststr="This is a test.\n"; +const char *file="teststring.txt"; +const char *prg; + +int +main(int argc, char *argv[]) +{ + const char *archive; + struct zip *za; + struct zip_source *zs; + char buf[100]; + int err; + + prg = argv[0]; + + if (argc != 2) { + fprintf(stderr, "usage: %s archive\n", prg); + return 1; + } + + archive = argv[1]; + + if ((za=zip_open(archive, ZIP_CREATE, &err)) == NULL) { + zip_error_to_str(buf, sizeof(buf), err, errno); + fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, + archive, buf); + return 1; + } + + if ((zs=zip_source_buffer(za, teststr, strlen(teststr), 0)) == NULL) { + fprintf(stderr, "%s: can't create zip_source from buffer: %s\n", prg, + zip_strerror(za)); + exit(1); + } + + if (zip_add(za, file, zs) == -1) { + zip_source_free(zs); + fprintf(stderr, "%s: can't add file `%s': %s\n", prg, + file, zip_strerror(za)); + return 1; + } + + if (zip_fopen(za, file, ZIP_FL_UNCHANGED) == NULL) { + /* expected error, don't pollute with prg */ + fprintf(stderr, "can't zip_fopen file `%s': %s\n", + file, zip_strerror(za)); + return 1; + } + + if (zip_close(za) == -1) { + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(za)); + return 1; + } + + return 0; +}
diff --git a/regress/fopen_unchanged.test b/regress/fopen_unchanged.test new file mode 100644 index 0000000..5e55d0c --- /dev/null +++ b/regress/fopen_unchanged.test
@@ -0,0 +1,5 @@ +# add buffer contents as file to zip, then read unchanged from it +program fopen_unchanged +return 1 +args testbuffer.zip +stderr can't zip_fopen file `teststring.txt': No such file
diff --git a/regress/fread.c b/regress/fread.c index 9080b8a..258a070 100644 --- a/regress/fread.c +++ b/regress/fread.c
@@ -75,7 +75,7 @@ if ((z=zip_open(archive, 0, &ze)) == NULL) { zip_error_to_str(errstr, sizeof(errstr), ze, errno); - printf("%s: opening zip archive ``%s'' failed: %s\n", + printf("%s: can't open zip archive `%s': %s\n", prg, archive, errstr); return 1; } @@ -113,7 +113,7 @@ zip_unchange_all(z); if (zip_close(z) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(z)); return 1; }
diff --git a/regress/get_comment.c b/regress/get_comment.c index 62a521f..2446f5a 100644 --- a/regress/get_comment.c +++ b/regress/get_comment.c
@@ -81,7 +81,7 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; }
diff --git a/regress/mkname.h b/regress/mkname.h deleted file mode 100644 index d85bde5..0000000 --- a/regress/mkname.h +++ /dev/null
@@ -1,5 +0,0 @@ -#ifndef HAD_MKNAME_H - -const char *mkname(const char *); - -#endif /* mkname.h */
diff --git a/regress/modify.c b/regress/modify.c new file mode 100644 index 0000000..2de8201 --- /dev/null +++ b/regress/modify.c
@@ -0,0 +1,128 @@ +/* + modify.c -- test case for modifying zip archive in multiple ways + Copyright (C) 2012 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 <errno.h> +#include <stdlib.h> +#include <string.h> + +#include "zip.h" + +const char *prg; + +int +main(int argc, char *argv[]) +{ + const char *archive; + struct zip *za; + struct zip_source *zs; + char buf[100]; + int err; + int arg; + int idx; + + arg = 0; + prg = argv[arg++]; + + if (argc < 2) { + fprintf(stderr, "usage: %s archive [add name content|add_dir name|delete index|file_comment index comment|rename index name]\n", prg); + return 1; + } + + archive = argv[arg++]; + + if ((za=zip_open(archive, ZIP_CREATE, &err)) == NULL) { + zip_error_to_str(buf, sizeof(buf), err, errno); + fprintf(stderr, "can't open zip archive `%s': %s\n", archive, buf); + return 1; + } + + while (arg < argc) { + if (strcmp(argv[arg], "add") == 0 && arg+2 < argc) { + /* add */ + if ((zs=zip_source_buffer(za, argv[arg+2], strlen(argv[arg+2]), 0)) == NULL) { + fprintf(stderr, "can't create zip_source from buffer: %s\n", zip_strerror(za)); + break; + } + + if (zip_add(za, argv[arg+1], zs) == -1) { + zip_source_free(zs); + fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); + break; + } + arg += 3; + } else if (strcmp(argv[arg], "add_dir") == 0 && arg+1 < argc) { + /* add directory */ + if (zip_add_dir(za, argv[arg+1]) < 0) { + fprintf(stderr, "can't add directory `%s': %s\n", argv[arg+1], zip_strerror(za)); + break; + } + arg += 2; + } else if (strcmp(argv[arg], "delete") == 0 && arg+1 < argc) { + /* delete */ + idx = atoi(argv[arg+1]); + if (zip_delete(za, idx) < 0) { + fprintf(stderr, "can't delete file at index `%d': %s\n", idx, zip_strerror(za)); + break; + } + arg += 2; + } else if (strcmp(argv[arg], "file_comment") == 0 && arg+2 < argc) { + /* set file comment */ + idx = atoi(argv[arg+1]); + if (zip_set_file_comment(za, idx, argv[arg+2], strlen(argv[arg+2])) < 0) { + fprintf(stderr, "can't set file comment at index `%d' to `%s': %s\n", idx, argv[arg+2], zip_strerror(za)); + break; + } + arg += 3; + } else if (strcmp(argv[arg], "rename") == 0 && arg+2 < argc) { + /* rename */ + idx = atoi(argv[arg+1]); + if (zip_rename(za, idx, argv[arg+2]) < 0) { + fprintf(stderr, "can't rename file at index `%d' to `%s': %s\n", idx, argv[arg+2], zip_strerror(za)); + break; + } + arg += 3; + } else { + fprintf(stderr, "unrecognized command `%s'\n", argv[arg]); + break; + } + } + + if (zip_close(za) == -1) { + fprintf(stderr, "can't close zip archive `%s': %s\n", archive, zip_strerror(za)); + return 1; + } + + return 0; +}
diff --git a/regress/name_locate.c b/regress/name_locate.c index 62d3714..eb997c5 100644 --- a/regress/name_locate.c +++ b/regress/name_locate.c
@@ -64,8 +64,10 @@ archive = argv[1]; if ((z=zip_open(archive, 0, &ze)) == NULL) { - printf("%s: opening zip archive ``%s'' failed (%d)\n", prg, - archive, ze); + char buf[100]; + zip_error_to_str(buf, sizeof(buf), ze, errno); + printf("%s: can't open zip archive `%s': %s\n", prg, + archive, buf); return 1; } @@ -88,8 +90,8 @@ fail += find_success(z, "test", 0); if (zip_close(z) == -1) { - fprintf(stderr, "%s: can't close zip archive %s\n", prg, - archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(z)); return 1; } @@ -108,8 +110,8 @@ zip_error_get(z, &ze, &se); if (ze != zerr) { zip_error_to_str(expected, sizeof(expected), zerr, 0); - printf("%s: unexpected error while looking for ``%s'': " - "got ``%s'', expected ``%s''\n", prg, name, + printf("%s: unexpected error while looking for `%s': " + "got `%s', expected `%s'\n", prg, name, zip_strerror(z), expected); return 1; } @@ -127,7 +129,7 @@ { if (zip_name_locate(z, name, flags) < 0) { - printf("%s: unexpected error while looking for ``%s'': %s\n", + printf("%s: unexpected error while looking for `%s': %s\n", prg, name, zip_strerror(z)); return 1; }
diff --git a/regress/open_cons_extrabytes.test b/regress/open_cons_extrabytes.test new file mode 100644 index 0000000..8fdf2cc --- /dev/null +++ b/regress/open_cons_extrabytes.test
@@ -0,0 +1,6 @@ +# zip_open: file has extra bytes at end of archive +program tryopen +file testextrabytes.zip testextrabytes.zip testextrabytes.zip +args -c testextrabytes.zip +return 1 +stdout opening `testextrabytes.zip' returned error 21
diff --git a/regress/open_empty.test b/regress/open_empty.test new file mode 100644 index 0000000..250bc40 --- /dev/null +++ b/regress/open_empty.test
@@ -0,0 +1,6 @@ +# zip_open: file contains no entry, but is valid +program tryopen +file testempty.zip testempty.zip testempty.zip +args testempty.zip +return 0 +stdout opening `testempty.zip' succeeded, 0 entries
diff --git a/regress/open_empty_2.test b/regress/open_empty_2.test new file mode 100644 index 0000000..0f6e215 --- /dev/null +++ b/regress/open_empty_2.test
@@ -0,0 +1,6 @@ +# zip_open: 0 size file is recognized as empty zip +program tryopen +file testfile.txt testfile.txt testfile.txt +args testfile.txt +return 0 +stdout opening `testfile.txt' succeeded, 0 entries
diff --git a/regress/open_extrabytes.test b/regress/open_extrabytes.test new file mode 100644 index 0000000..e647373 --- /dev/null +++ b/regress/open_extrabytes.test
@@ -0,0 +1,6 @@ +# zip_open: file has extra bytes at end of archive +program tryopen +file testextrabytes.zip testextrabytes.zip testextrabytes.zip +args testextrabytes.zip +return 0 +stdout opening `testextrabytes.zip' succeeded, 1 entries
diff --git a/regress/open_new_but_exists.test b/regress/open_new_but_exists.test index 612c8c9..9fb0460 100644 --- a/regress/open_new_but_exists.test +++ b/regress/open_new_but_exists.test
@@ -3,4 +3,4 @@ args -e test.zip return 1 file test.zip test.zip test.zip -stdout opening `test.zip' returned error 10/0 +stdout opening `test.zip' returned error 10
diff --git a/regress/open_nonarchive.test b/regress/open_nonarchive.test index b523abf..979a26e 100644 --- a/regress/open_nonarchive.test +++ b/regress/open_nonarchive.test
@@ -3,4 +3,4 @@ file Makefile.am Makefile.am Makefile.am args Makefile.am return 1 -stdout opening `Makefile.am' returned error 19/2 +stdout opening `Makefile.am' returned error 19
diff --git a/regress/open_truncate.test b/regress/open_truncate.test new file mode 100644 index 0000000..ac23068 --- /dev/null +++ b/regress/open_truncate.test
@@ -0,0 +1,6 @@ +# zip_open: file opens fine and gets truncated +program tryopen +args -t test.zip +return 0 +file-del test.zip test.zip +stdout opening `test.zip' succeeded, 0 entries
diff --git a/regress/rename.c b/regress/rename.c new file mode 100644 index 0000000..8b379cf --- /dev/null +++ b/regress/rename.c
@@ -0,0 +1,95 @@ +/* + rename.c -- test cases for renaming files in zip archives + Copyright (C) 2012 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 <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include "zip.h" + +const char *prg; + + + +int +main(int argc, char *argv[]) +{ + zip_uint64_t idx; + int ze; + struct zip *z; + const char *archive; + const char *oldname; + const char *newname; + + prg = argv[0]; + + if (argc != 4) { + fprintf(stderr, "usage: %s archive oldname newname\n", prg); + return 1; + } + + archive = argv[1]; + oldname = argv[2]; + newname = argv[3]; + + if ((z=zip_open(archive, 0, &ze)) == NULL) { + char buf[100]; + zip_error_to_str(buf, sizeof(buf), ze, errno); + printf("%s: can't open zip archive `%s': %s\n", prg, + archive, buf); + return 1; + } + + if ((idx=zip_name_locate(z, oldname, 0)) < 0) { + printf("%s: unexpected error while looking for `%s': %s\n", + prg, oldname, zip_strerror(z)); + return 1; + } + + if (zip_rename(z, idx, newname) < 0) { + /* expected error, so no prg prefix */ + printf("error renaming `%s' to `%s': %s\n", + oldname, newname, zip_strerror(z)); + return 1; + } + + if (zip_close(z) == -1) { + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, + archive, zip_strerror(z)); + return 1; + } + + exit(0); +}
diff --git a/regress/rename_ascii.test b/regress/rename_ascii.test new file mode 100644 index 0000000..bab7301 --- /dev/null +++ b/regress/rename_ascii.test
@@ -0,0 +1,5 @@ +# rename file to ASCII name in zip archive +program modify +return 0 +args testfile rename 0 testfile.txt +file testfile testfile-UTF8.zip testfile.zip
diff --git a/regress/rename_cp437.test b/regress/rename_cp437.test new file mode 100644 index 0000000..6596afd --- /dev/null +++ b/regress/rename_cp437.test
@@ -0,0 +1,6 @@ +# rename file to CP437 name in zip archive (fails) +program modify +return 0 +args testfile.zip rename 0 +file testfile.zip testfile.zip testfile.zip +stderr can't rename file at index `0' to ` ': Invalid argument
diff --git a/regress/rename_deleted.test b/regress/rename_deleted.test new file mode 100644 index 0000000..a5ae64b --- /dev/null +++ b/regress/rename_deleted.test
@@ -0,0 +1,6 @@ +# rename deleted entry in zip archive (fails) +program modify +return 0 +args testfile.zip delete 1 delete 3 rename 1 othername +file testfile.zip testcomment.zip testcomment13.zip +stderr can't rename file at index `1' to `othername': Entry has been deleted
diff --git a/regress/rename_fail.test b/regress/rename_fail.test new file mode 100644 index 0000000..cd95c54 --- /dev/null +++ b/regress/rename_fail.test
@@ -0,0 +1,6 @@ +# rename file inside zip archive, but file name already exists +program rename +return 1 +args rename.zip file2 file4 +file rename.zip testcomment.zip testcomment.zip +stdout error renaming `file2' to `file4': File already exists
diff --git a/regress/rename_ok.test b/regress/rename_ok.test new file mode 100644 index 0000000..efff5c5 --- /dev/null +++ b/regress/rename_ok.test
@@ -0,0 +1,5 @@ +# rename file inside zip archive +program rename +return 0 +args rename.zip file2 notfile2 +file rename.zip testcomment.zip rename_ok.zip
diff --git a/regress/rename_ok.zip b/regress/rename_ok.zip new file mode 100644 index 0000000..ad07306 --- /dev/null +++ b/regress/rename_ok.zip Binary files differ
diff --git a/regress/rename_utf8.test b/regress/rename_utf8.test new file mode 100644 index 0000000..25b92f0 --- /dev/null +++ b/regress/rename_utf8.test
@@ -0,0 +1,5 @@ +# rename file to UTF-8 name in zip archive +program modify +return 0 +args testfile rename 0 ÄÖÜßäöü +file testfile testfile.zip testfile-UTF8.zip
diff --git a/regress/rename_utf8_encmismatch.test b/regress/rename_utf8_encmismatch.test new file mode 100644 index 0000000..b45ff0f --- /dev/null +++ b/regress/rename_utf8_encmismatch.test
@@ -0,0 +1,6 @@ +# rename file to UTF-8 name in zip archive with CP437 comment (fails) +program modify +return 0 +args testfile rename 0 ÄÖÜßäöü +file testfile test-cp437-fc.zip test-cp437-fc.zip +stderr can't rename file at index `0' to `ÄÖÜßäöü': Encoding of name and comment do not match
diff --git a/regress/runtest b/regress/runtest index a104251..2d397e2 100755 --- a/regress/runtest +++ b/regress/runtest
@@ -288,7 +288,7 @@ test_empty "${RET}" return RET="$arg";; stderr) - echo "${PROGRAM}: $arg" >> stderr;; + echo "$arg" >> stderr;; stdout) echo "$arg" >> stdout;; *)
diff --git a/regress/set_comment_all.c b/regress/set_comment_all.c index 489a272..be886f0 100644 --- a/regress/set_comment_all.c +++ b/regress/set_comment_all.c
@@ -1,6 +1,6 @@ /* set_comment_all.c -- set global and file comments - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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,7 +38,7 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" +#include "zipint.h" const char *prg; const char *new_archive_comment="This is the new,\r\n" @@ -87,7 +87,7 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; }
diff --git a/regress/set_comment_localonly.c b/regress/set_comment_localonly.c index 55e25d3..b01ff21 100644 --- a/regress/set_comment_localonly.c +++ b/regress/set_comment_localonly.c
@@ -1,6 +1,6 @@ /* set_comment_localonly.c -- set file comments - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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,7 +38,7 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" +#include "zipint.h" const char *prg; @@ -83,7 +83,7 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; }
diff --git a/regress/set_comment_removeglobal.c b/regress/set_comment_removeglobal.c index c8ff6c5..2792372 100644 --- a/regress/set_comment_removeglobal.c +++ b/regress/set_comment_removeglobal.c
@@ -1,6 +1,6 @@ /* set_comment_removeglobal.c -- remove archive comment - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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,7 +38,7 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" +#include "zipint.h" const char *prg; @@ -73,7 +73,7 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; }
diff --git a/regress/set_comment_revert.c b/regress/set_comment_revert.c index 46a1b85..cd5611f 100644 --- a/regress/set_comment_revert.c +++ b/regress/set_comment_revert.c
@@ -1,6 +1,6 @@ /* set_comment_revert.c -- set global and file comments, but revert - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 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,7 +38,7 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" +#include "zipint.h" const char *prg; const char *new_archive_comment="This is the new,\r\n" @@ -93,7 +93,7 @@ } if (zip_close(za) == -1) { - fprintf(stderr, "%s: can't close zip archive `%s'\n", prg, archive); + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; }
diff --git a/regress/set_compression.c b/regress/set_compression.c new file mode 100644 index 0000000..e72d73d --- /dev/null +++ b/regress/set_compression.c
@@ -0,0 +1,89 @@ +/* + set_compression.c -- set compression method for file in archive + Copyright (C) 2012 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 <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "zipint.h" + +const char *prg; + +int +main(int argc, char *argv[]) +{ + const char *archive, *name; + int method; + struct zip *za; + char buf[100]; + int err; + int i; + int idx; + + prg = argv[0]; + + if (argc != 4) { + fprintf(stderr, "usage: %s archive file method\n", prg); + return 1; + } + + archive = argv[1]; + name = argv[2]; + method = atoi(argv[3]); + + if ((za=zip_open(archive, 0, &err)) == NULL) { + zip_error_to_str(buf, sizeof(buf), err, errno); + fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, + archive, buf); + return 1; + } + if ((idx=zip_name_locate(za, name, 0)) < 0) { + printf("%s: unexpected error while looking for `%s': %s\n", + prg, name, zip_strerror(za)); + return 1; + } + if (zip_set_file_compression(za, idx, method, /* XXX: add flags * when supported */ 0) < 0) { + fprintf(stderr, "zip_set_file_compression with method `%d' on file %d failed: %s\n", + method, idx, zip_strerror(za)); + return 1; + } + if (zip_close(za) == -1) { + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); + return 1; + } + + return 0; +}
diff --git a/regress/set_compression_deflate_to_deflate.test b/regress/set_compression_deflate_to_deflate.test new file mode 100644 index 0000000..bbcb873 --- /dev/null +++ b/regress/set_compression_deflate_to_deflate.test
@@ -0,0 +1,5 @@ +# change method from deflated to deflated (no change) +program set_compression +return 0 +args test.zip abac-repeat.txt 8 +file test.zip testdeflated.zip testdeflated.zip
diff --git a/regress/set_compression_deflate_to_store.test b/regress/set_compression_deflate_to_store.test new file mode 100644 index 0000000..824e672 --- /dev/null +++ b/regress/set_compression_deflate_to_store.test
@@ -0,0 +1,5 @@ +# change method from deflated to stored +program set_compression +return 0 +args test.zip abac-repeat.txt 0 +file test.zip testdeflated.zip teststored.zip
diff --git a/regress/set_compression_store_to_deflate.test b/regress/set_compression_store_to_deflate.test new file mode 100644 index 0000000..c9476cc --- /dev/null +++ b/regress/set_compression_store_to_deflate.test
@@ -0,0 +1,5 @@ +# change method from stored to deflated +program set_compression +return 0 +args test.zip abac-repeat.txt 8 +file test.zip teststored.zip testdeflated.zip
diff --git a/regress/set_compression_store_to_store.test b/regress/set_compression_store_to_store.test new file mode 100644 index 0000000..c5ea2af --- /dev/null +++ b/regress/set_compression_store_to_store.test
@@ -0,0 +1,5 @@ +# change method from stored to stored (no change) +program set_compression +return 0 +args test.zip abac-repeat.txt 0 +file test.zip teststored.zip teststored.zip
diff --git a/regress/set_compression_unknown.test b/regress/set_compression_unknown.test new file mode 100644 index 0000000..6fd9976 --- /dev/null +++ b/regress/set_compression_unknown.test
@@ -0,0 +1,6 @@ +# change method to unknown +program set_compression +return 1 +args test.zip abac-repeat.txt -99 +file test.zip teststored.zip teststored.zip +stderr zip_set_file_compression with method `-99' on file 0 failed: Compression method not supported
diff --git a/regress/stat_index.c b/regress/stat_index.c new file mode 100644 index 0000000..ad7f2b9 --- /dev/null +++ b/regress/stat_index.c
@@ -0,0 +1,137 @@ +/* + stat_index.c -- stat entry in archive and print details + Copyright (C) 2012 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 <errno.h> +#include <time.h> +#ifndef HAVE_GETOPT +#include "getopt.h" +#endif + +#include "zip.h" + +const char *prg; + +const char *usage = "usage: %s [-grs] file index [index ...]\n"; + + + +int +main(int argc, char *argv[]) +{ + const char *fname; + char buf[100]; + struct zip *z; + int c, flags, ze; + zip_uint64_t count; + struct zip_stat sb; + int index; + + flags = 0; + prg = argv[0]; + + while ((c=getopt(argc, argv, "grs")) != -1) { + switch (c) { + case 'g': + flags = ZIP_FL_NAME_GUESS; + break; + case 'r': + flags = ZIP_FL_NAME_RAW; + break; + case 's': + flags = ZIP_FL_NAME_STRICT; + break; + + default: + fprintf(stderr, usage, prg); + return 1; + } + } + if (argc < optind+2) { + fprintf(stderr, usage, prg); + return 1; + } + + fname = argv[optind++]; + errno = 0; + + if ((z=zip_open(fname, flags, &ze)) == NULL) { + zip_error_to_str(buf, sizeof(buf), ze, errno); + fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, + fname, buf); + return 1; + } + + while (optind < argc) { + index = atoi(argv[optind++]); + + if (zip_stat_index(z, index, flags, &sb) < 0) { + fprintf(stderr, "%s: zip_stat_index failed on `%d' failed: %s\n", + prg, index, zip_strerror(z)); + return 1; + } + + if (sb.valid & ZIP_STAT_NAME) + printf("name: `%s'\n", sb.name); + if (sb.valid & ZIP_STAT_INDEX) + printf("index: `%lld'\n", sb.index); + if (sb.valid & ZIP_STAT_SIZE) + printf("size: `%lld'\n", sb.size); + if (sb.valid & ZIP_STAT_COMP_SIZE) + printf("compressed size: `%lld'\n", sb.comp_size); + if (sb.valid & ZIP_STAT_MTIME) { + char buf[50]; + struct tm *tpm; + tpm = gmtime(&sb.mtime); + strftime(buf, sizeof(buf), "%a %b %d %T %Z %Y", tpm); + printf("mtime: `%s'\n", buf); + } + if (sb.valid & ZIP_STAT_CRC) + printf("crc: `%0x'\n", sb.crc); + if (sb.valid & ZIP_STAT_COMP_METHOD) + printf("compression method: `%lld'\n", sb.comp_method); + if (sb.valid & ZIP_STAT_ENCRYPTION_METHOD) + printf("encryption method: `%lld'\n", sb.encryption_method); + if (sb.valid & ZIP_STAT_FLAGS) + printf("flags: `%lld'\n", sb.flags); + printf("\n"); + } + + if (zip_close(z) == -1) { + fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, fname, zip_strerror(z)); + return 1; + } + + return 0; +}
diff --git a/regress/stat_index_cp437_guess.test b/regress/stat_index_cp437_guess.test new file mode 100644 index 0000000..32c2d82 --- /dev/null +++ b/regress/stat_index_cp437_guess.test
@@ -0,0 +1,149 @@ +# guess CP437 file names and autoconvert them +program stat_index +args test-cp437.zip 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +return 0 +file test-cp437.zip test-cp437.zip test-cp437.zip +stdout name: `☺☻♥♦♣♠•○◘◙♂♀♪♫☼►' +stdout index: `0' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:51:50 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `◄↕‼¶§▬↨↑↓→←∟↔▲▼ ' +stdout index: `1' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:51:54 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `!"#$%&'()*+,-./0' +stdout index: `2' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:51:58 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `123456789:;<=>?@' +stdout index: `3' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:04 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `ABCDEFGHIJKLMNOP' +stdout index: `4' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:08 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `QRSTUVWXYZ[\\]^_`' +stdout index: `5' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:12 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `abcdefghijklmnop' +stdout index: `6' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:18 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `qrstuvwxyz{|}~~Ç' +stdout index: `7' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:22 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `üéâäàåçêëèïîìÄÅÉ' +stdout index: `8' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:26 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `æÆôöòûùÿÖÜ¢£¥₧ƒá' +stdout index: `9' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:30 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `íóúñѪº¿⌐¬½¼¡«»░' +stdout index: `10' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:36 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `▒▓│┤╡╢╖╕╣║╗╝╜╛┐└' +stdout index: `11' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:40 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `┴┬├─┼╞╟╚╔╩╦╠═╬╧╨' +stdout index: `12' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:44 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `╤╥╙╘╒╓╫╪┘┌█▄▌▐▀α' +stdout index: `13' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:50 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `ßΓπΣσµτΦΘΩδ∞φε∩≡' +stdout index: `14' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:54 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `±≥≤⌠⌡÷≈°∙·√ⁿ²■ ' +stdout index: `15' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:53:02 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout
diff --git a/regress/stat_index_cp437_raw.test b/regress/stat_index_cp437_raw.test new file mode 100644 index 0000000..4ac895b --- /dev/null +++ b/regress/stat_index_cp437_raw.test Binary files differ
diff --git a/regress/stat_index_cp437_strict.test b/regress/stat_index_cp437_strict.test new file mode 100644 index 0000000..4caa47e --- /dev/null +++ b/regress/stat_index_cp437_strict.test
@@ -0,0 +1,149 @@ +# strictly follow ZIP spec and expect CP437 file names, and autoconvert them +program stat_index +args -s test-cp437.zip 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +return 0 +file test-cp437.zip test-cp437.zip test-cp437.zip +stdout name: `☺☻♥♦♣♠•○◘◙♂♀♪♫☼►' +stdout index: `0' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:51:50 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `◄↕‼¶§▬↨↑↓→←∟↔▲▼ ' +stdout index: `1' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:51:54 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `!"#$%&'()*+,-./0' +stdout index: `2' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:51:58 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `123456789:;<=>?@' +stdout index: `3' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:04 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `ABCDEFGHIJKLMNOP' +stdout index: `4' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:08 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `QRSTUVWXYZ[\\]^_`' +stdout index: `5' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:12 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `abcdefghijklmnop' +stdout index: `6' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:18 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `qrstuvwxyz{|}~~Ç' +stdout index: `7' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:22 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `üéâäàåçêëèïîìÄÅÉ' +stdout index: `8' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:26 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `æÆôöòûùÿÖÜ¢£¥₧ƒá' +stdout index: `9' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:30 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `íóúñѪº¿⌐¬½¼¡«»░' +stdout index: `10' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:36 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `▒▓│┤╡╢╖╕╣║╗╝╜╛┐└' +stdout index: `11' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:40 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `┴┬├─┼╞╟╚╔╩╦╠═╬╧╨' +stdout index: `12' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:44 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `╤╥╙╘╒╓╫╪┘┌█▄▌▐▀α' +stdout index: `13' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:50 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `ßΓπΣσµτΦΘΩδ∞φε∩≡' +stdout index: `14' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:52:54 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout +stdout name: `±≥≤⌠⌡÷≈°∙·√ⁿ²■ ' +stdout index: `15' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 19:53:02 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout
diff --git a/regress/stat_index_utf8_guess.test b/regress/stat_index_utf8_guess.test new file mode 100644 index 0000000..9b63ee7 --- /dev/null +++ b/regress/stat_index_utf8_guess.test
@@ -0,0 +1,14 @@ +# guess UTF-8 file names +program stat_index +args test-utf8.zip 0 +return 0 +file test-utf8.zip test-utf8.zip test-utf8.zip +stdout name: `ÄÖÜäöüßćçĉéèêëē' +stdout index: `0' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 23:15:08 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout
diff --git a/regress/stat_index_utf8_raw.test b/regress/stat_index_utf8_raw.test new file mode 100644 index 0000000..a69003a --- /dev/null +++ b/regress/stat_index_utf8_raw.test
@@ -0,0 +1,14 @@ +# print UTF-8 file names +program stat_index +args -r test-utf8.zip 0 +return 0 +file test-utf8.zip test-utf8.zip test-utf8.zip +stdout name: `ÄÖÜäöüßćçĉéèêëē' +stdout index: `0' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 23:15:08 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout
diff --git a/regress/stat_index_utf8_strict.test b/regress/stat_index_utf8_strict.test new file mode 100644 index 0000000..e5a7df4 --- /dev/null +++ b/regress/stat_index_utf8_strict.test
@@ -0,0 +1,15 @@ +# follow strict rules and convert UTF-8 as if it was CP437, but not +# if the files are marked as having UTF-8 names +program stat_index +args -s test-utf8.zip 0 +return 0 +file test-utf8.zip test-utf8.zip test-utf8.zip +stdout name: `ÄÖÜäöüßćçĉéèêëē' +stdout index: `0' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 23:15:08 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout
diff --git a/regress/stat_index_utf8_unmarked_strict.test b/regress/stat_index_utf8_unmarked_strict.test new file mode 100644 index 0000000..264a47d --- /dev/null +++ b/regress/stat_index_utf8_unmarked_strict.test
@@ -0,0 +1,15 @@ +# follow strict rules and convert UTF-8 as if it was CP437, +# if not marked otherwise (in this case: not marked) +program stat_index +args -s test-utf8-unmarked.zip 0 +return 0 +file test-utf8-unmarked.zip test-utf8-unmarked.zip test-utf8-unmarked.zip +stdout name: `ÄÖÜäöüßćçĉéèêëē' +stdout index: `0' +stdout size: `0' +stdout compressed size: `0' +stdout mtime: `Fri Feb 17 23:15:08 CET 2012' +stdout crc: `0' +stdout compression method: `0' +stdout encryption method: `0' +stdout
diff --git a/regress/test-cp437-fc.zip b/regress/test-cp437-fc.zip new file mode 100644 index 0000000..0c4f04d --- /dev/null +++ b/regress/test-cp437-fc.zip Binary files differ
diff --git a/regress/test-cp437.zip b/regress/test-cp437.zip new file mode 100644 index 0000000..066531e --- /dev/null +++ b/regress/test-cp437.zip Binary files differ
diff --git a/regress/test-utf8-unmarked.zip b/regress/test-utf8-unmarked.zip new file mode 100644 index 0000000..1bcb703 --- /dev/null +++ b/regress/test-utf8-unmarked.zip Binary files differ
diff --git a/regress/test-utf8.zip b/regress/test-utf8.zip new file mode 100644 index 0000000..3045e20 --- /dev/null +++ b/regress/test-utf8.zip Binary files differ
diff --git a/regress/test2.zip b/regress/test2.zip new file mode 100644 index 0000000..ff5e351 --- /dev/null +++ b/regress/test2.zip Binary files differ
diff --git a/regress/testcomment13.zip b/regress/testcomment13.zip new file mode 100644 index 0000000..bd6e1c3 --- /dev/null +++ b/regress/testcomment13.zip Binary files differ
diff --git a/regress/testdeflated.zip b/regress/testdeflated.zip new file mode 100644 index 0000000..c9ee5d2 --- /dev/null +++ b/regress/testdeflated.zip Binary files differ
diff --git a/regress/testempty.zip b/regress/testempty.zip new file mode 100644 index 0000000..15cb0ec --- /dev/null +++ b/regress/testempty.zip Binary files differ
diff --git a/regress/testextrabytes.zip b/regress/testextrabytes.zip new file mode 100644 index 0000000..f2a3fb2 --- /dev/null +++ b/regress/testextrabytes.zip Binary files differ
diff --git a/regress/testfile-UTF8.zip b/regress/testfile-UTF8.zip new file mode 100644 index 0000000..c09ede6 --- /dev/null +++ b/regress/testfile-UTF8.zip Binary files differ
diff --git a/regress/testfile.txt b/regress/testfile.txt old mode 100644 new mode 100755
diff --git a/regress/testfile.zip b/regress/testfile.zip index b46d298..b87dc48 100644 --- a/regress/testfile.zip +++ b/regress/testfile.zip Binary files differ
diff --git a/regress/teststored.zip b/regress/teststored.zip index 04bf517..91cb1e6 100644 --- a/regress/teststored.zip +++ b/regress/teststored.zip Binary files differ
diff --git a/regress/torrent-already.test b/regress/torrent-already.test index 8bd15b3..4369e71 100644 --- a/regress/torrent-already.test +++ b/regress/torrent-already.test
@@ -1,4 +1,4 @@ -# add directories to zip +# try converting archive to torrentzip that's already in that format program ../src/ziptorrent return 0 args -v test.zip
diff --git a/regress/torrent-new.test b/regress/torrent-new.test index 0224208..8bac8da 100644 --- a/regress/torrent-new.test +++ b/regress/torrent-new.test
@@ -1,4 +1,4 @@ -# add directories to zip +# convert archive to torrentzip format program ../src/ziptorrent return 0 args -v test.zip
diff --git a/regress/tryopen.c b/regress/tryopen.c index fcc280f..cab1460 100644 --- a/regress/tryopen.c +++ b/regress/tryopen.c
@@ -44,7 +44,7 @@ const char *prg; -const char *usage = "usage: %s [-cen] file\n"; +const char *usage = "usage: %s [-cent] file\n"; @@ -53,12 +53,13 @@ { const char *fname; struct zip *z; - int c, count, flags, ze; + int c, flags, ze; + zip_uint64_t count; flags = 0; prg = argv[0]; - while ((c=getopt(argc, argv, "cen")) != -1) { + while ((c=getopt(argc, argv, "cent")) != -1) { switch (c) { case 'c': flags |= ZIP_CHECKCONS; @@ -69,6 +70,9 @@ case 'n': flags |= ZIP_CREATE; break; + case 't': + flags |= ZIP_TRUNCATE; + break; default: fprintf(stderr, usage, prg); @@ -84,13 +88,15 @@ errno = 0; if ((z=zip_open(fname, flags, &ze)) != NULL) { - count = zip_get_num_files(z); - printf("opening `%s' succeeded, %d entries\n", fname, count); + count = zip_get_num_entries(z, 0); + printf("opening `%s' succeeded, %lld entries\n", fname, count); zip_close(z); return 0; } - printf("opening `%s' returned error %d/%d\n", - fname, ze, errno); + printf("opening `%s' returned error %d", fname, ze); + if (zip_error_get_sys_type(ze) == ZIP_ET_SYS) + printf("/%d", errno); + printf("\n"); return 1; }
diff --git a/regress/zip64.zip b/regress/zip64.zip new file mode 100644 index 0000000..c1ba76b --- /dev/null +++ b/regress/zip64.zip Binary files differ
diff --git a/regress/ziptest.c b/regress/ziptest.c deleted file mode 100644 index 7d37be5..0000000 --- a/regress/ziptest.c +++ /dev/null
@@ -1,99 +0,0 @@ -#include "zip.h" -#include "error.h" - - -int -main(int argc, char *argv[]) -{ -#if 0 - int i; -#endif - struct zip *za, *destza; -#if 0 -#define BUFSIZE 65536 - struct zip_file *zf1, *zf2; - char buf1[BUFSIZE], buf2[BUFSIZE]; -#endif - -#if 0 - if (argc != 2) { - fprintf(stderr, "%s: call with one option: the zip-file to destroy" - "^H^H^H^H^H^H^Htest\n", argv[0]); - return 1; - } -#endif - if (argc != 3) { - fprintf(stderr, "%s: call with two options: src dest\n", argv[0]); - return 1; - } - - if ((za=zip_open(argv[1], ZIP_CHECKCONS))==NULL) { - fprintf(stderr, "%s: %s: can't open file: %s\n", argv[0], argv[1], - zip_err_str[zip_err]); - return 1; - } - - if ((destza=zip_open(argv[2], ZIP_CREATE))==NULL) { - fprintf(stderr, "%s: %s: can't open file: %s\n", argv[0], argv[2], - zip_err_str[zip_err]); - return 1; - } - -#if 0 - for (i=0; i<za->nentry; i++) { - printf("%8d %s\n", za->entry[i].uncomp_size, za->entry[i].fn); - zip_add_zip(destza, za->entry[i].fn, za, i, 0, 0); - } -#endif - - if (zip_add_zip(destza, NULL, NULL, za, 0, 0, 0) == -1) - fprintf(stderr, "%s: %s: can't add file to zip '%s': %s\n", argv[0], - za->entry[0].fn, argv[1], zip_err_str[zip_err]); - -#if 0 - zf1= zf_open_index(za, 1); - if (!zf1) { - fprintf(stderr, "boese, boese\n"); - exit(100); - } - - i = zf_read(zf1, buf1, 100); - if (i < 0) - fprintf(stderr, "read error: %s\n", zip_err_str[zf1->flags]); - else { - buf1[i] = 0; - printf("read %d bytes: '%s'\n", i, buf1); - } - zf2 = zf_open_index(za, 1); - i = zf_read(zf2, buf2, 200); - if (i < 0) - fprintf(stderr, "read error: %s\n", zip_err_str[zf2->flags]); - else { - buf2[i] = 0; - printf("read %d bytes: '%s'\n", i, buf2); - } - i = zf_read(zf1, buf1, 100); - if (i < 0) - fprintf(stderr, "read error: %s\n", zip_err_str[zf1->flags]); - else { - buf1[i] = 0; - printf("read %d bytes: '%s'\n", i, buf1); - } - zf_close(zf1); - zf_close(zf2); -#endif - - if (zip_close(destza)!=0) { - fprintf(stderr, "%s: %s: can't close file: %s\n", argv[0], argv[2], - zip_err_str[zip_err]); - return 1; - } - - if (zip_close(za)!=0) { - fprintf(stderr, "%s: %s: can't close file: %s\n", argv[0], argv[1], - zip_err_str[zip_err]); - return 1; - } - - return 0; -}
diff --git a/src/Makefile.am b/src/Makefile.am index 7fa4b8e..dc13bbb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am
@@ -1,10 +1,10 @@ bin_PROGRAMS=zipcmp zipmerge ziptorrent -zipcmp_CPPFLAGS=-I${top_srcdir}/lib +zipcmp_CPPFLAGS=-I${top_srcdir}/lib -I../lib zipcmp_LDADD=${top_builddir}/lib/libzip.la -zipmerge_CPPFLAGS=-I${top_srcdir}/lib +zipmerge_CPPFLAGS=-I${top_srcdir}/lib -I../lib zipmerge_LDADD=${top_builddir}/lib/libzip.la -ziptorrent_CPPFLAGS=-I${top_srcdir}/lib +ziptorrent_CPPFLAGS=-I${top_srcdir}/lib -I../lib ziptorrent_LDADD=${top_builddir}/lib/libzip.la EXTRA_DIST= CMakeLists.txt getopt.c getopt.h
diff --git a/src/zipcmp.c b/src/zipcmp.c index 75a3e4e..6e1d5d2 100644 --- a/src/zipcmp.c +++ b/src/zipcmp.c
@@ -1,6 +1,6 @@ /* zipcmp.c -- compare zip files - Copyright (C) 2003-2010 Dieter Baron and Thomas Klausner + Copyright (C) 2003-2012 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> @@ -49,6 +49,7 @@ #endif #include "zip.h" +#include "zipint.h" struct entry { char *name; @@ -78,7 +79,7 @@ Report bugs to <libzip@nih.at>.\n"; char version_string[] = PROGRAM " (" PACKAGE " " VERSION ")\n\ -Copyright (C) 2010 Dieter Baron and Thomas Klausner\n\ +Copyright (C) 2012 Dieter Baron and Thomas Klausner\n\ " PACKAGE " comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law.\n"; #define OPTIONS "hViqtv" @@ -171,23 +172,27 @@ n[i] = zip_get_num_files(za); - if ((e[i]=malloc(sizeof(*e[i]) * n[i])) == NULL) { - fprintf(stderr, "%s: malloc failure\n", prg); - exit(1); - } + if (n[i] == 0) + e[i] = NULL; + else { + if ((e[i]=malloc(sizeof(*e[i]) * n[i])) == NULL) { + fprintf(stderr, "%s: malloc failure\n", prg); + exit(1); + } - for (j=0; j<n[i]; j++) { - zip_stat_index(za, j, 0, &st); - e[i][j].name = strdup(st.name); - e[i][j].size = st.size; - e[i][j].crc = st.crc; - if (test_files) - test_file(za, j, st.size, st.crc); - } + for (j=0; j<n[i]; j++) { + zip_stat_index(za, j, 0, &st); + e[i][j].name = strdup(st.name); + e[i][j].size = st.size; + e[i][j].crc = st.crc; + if (test_files) + test_file(za, j, st.size, st.crc); + } + qsort(e[i], n[i], sizeof(e[i][0]), entry_cmp); + } zip_close(za); - qsort(e[i], n[i], sizeof(e[i][0]), entry_cmp); } switch (compare_list(zn, verbose,