mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Sync ext/zip with pecl/zip version 1.3.2
- update libzip to version 1.11.1. We don't use any private symbol anymore - new method ZipArchive::setPassword($password) - add --with-libzip option to build with system libzip
This commit is contained in:
parent
2f555b8e60
commit
5dc37b3510
99 changed files with 4820 additions and 1877 deletions
|
@ -1,2 +1,2 @@
|
|||
Zip
|
||||
Pierre-Alain Joye
|
||||
Pierre-Alain Joye, Remi Collet
|
||||
|
|
|
@ -11,10 +11,14 @@ if test -z "$PHP_ZLIB_DIR"; then
|
|||
fi
|
||||
|
||||
PHP_ARG_WITH(pcre-dir, pcre install prefix,
|
||||
[ --with-pcre-dir ZIP: pcre install prefix], no, no)
|
||||
[ --with-pcre-dir ZIP: pcre install prefix], no, no)
|
||||
|
||||
PHP_ARG_WITH(libzip, libzip,
|
||||
[ --with-libzip[=DIR] ZIP: use libzip], no, no)
|
||||
|
||||
if test "$PHP_ZIP" != "no"; then
|
||||
|
||||
dnl libzip, depends on zlib
|
||||
if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then
|
||||
if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then
|
||||
PHP_ZLIB_DIR="$PHP_ZLIB_DIR"
|
||||
|
@ -47,61 +51,124 @@ if test "$PHP_ZIP" != "no"; then
|
|||
PHP_ADD_INCLUDE($PHP_ZLIB_INCDIR)
|
||||
fi
|
||||
|
||||
dnl This is PECL build, check if bundled PCRE library is used
|
||||
old_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS=$INCLUDES
|
||||
AC_EGREP_CPP(yes,[
|
||||
#include <main/php_config.h>
|
||||
#if defined(HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
yes
|
||||
#endif
|
||||
],[
|
||||
PHP_PCRE_REGEX=yes
|
||||
],[
|
||||
AC_EGREP_CPP(yes,[
|
||||
#include <main/php_config.h>
|
||||
#if defined(HAVE_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
yes
|
||||
#endif
|
||||
],[
|
||||
PHP_PCRE_REGEX=pecl
|
||||
],[
|
||||
PHP_PCRE_REGEX=no
|
||||
])
|
||||
])
|
||||
CPPFLAGS=$old_CPPFLAGS
|
||||
if test "$PHP_LIBZIP" != "no"; then
|
||||
|
||||
PHP_ZIP_SOURCES="$PHP_ZIP_SOURCES lib/zip_add.c lib/zip_error.c lib/zip_fclose.c \
|
||||
lib/zip_fread.c lib/zip_open.c lib/zip_source_filep.c \
|
||||
lib/zip_strerror.c lib/zip_close.c lib/zip_error_get.c \
|
||||
lib/zip_file_error_get.c lib/zip_free.c lib/zip_rename.c \
|
||||
lib/zip_source_free.c lib/zip_unchange_all.c lib/zip_delete.c \
|
||||
lib/zip_error_get_sys_type.c lib/zip_file_get_offset.c \
|
||||
lib/zip_get_name.c lib/zip_replace.c lib/zip_source_function.c \
|
||||
lib/zip_unchange.c lib/zip_dirent.c lib/zip_error_strerror.c \
|
||||
lib/zip_filerange_crc.c lib/zip_file_strerror.c lib/zip_get_num_files.c \
|
||||
lib/zip_get_archive_flag.c lib/zip_set_archive_flag.c \
|
||||
lib/zip_set_name.c lib/zip_source_zip.c lib/zip_unchange_data.c \
|
||||
lib/zip_entry_free.c lib/zip_error_to_str.c lib/zip_fopen.c \
|
||||
lib/zip_name_locate.c lib/zip_source_buffer.c lib/zip_stat.c \
|
||||
lib/zip_entry_new.c lib/zip_err_str.c lib/zip_fopen_index.c \
|
||||
lib/zip_get_archive_comment.c lib/zip_get_file_comment.c \
|
||||
lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c \
|
||||
lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \
|
||||
lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \
|
||||
lib/zip_error_clear.c lib/zip_file_error_clear.c \
|
||||
lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \
|
||||
lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \
|
||||
lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \
|
||||
lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \
|
||||
lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \
|
||||
lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \
|
||||
lib/zip_source_read.c lib/zip_source_stat.c"
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
|
||||
dnl system libzip, depends on libzip
|
||||
AC_MSG_CHECKING(for libzip)
|
||||
if test -r $PHP_LIBZIP/include/zip.h; then
|
||||
LIBZIP_CFLAGS="-I$PHP_LIBZIP/include"
|
||||
LIBZIP_LIBDIR="$PHP_LIBZIP/$PHP_LIBDIR"
|
||||
AC_MSG_RESULT(from option: found in $PHP_LIBZIP)
|
||||
|
||||
elif test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libzip; then
|
||||
LIBZIP_CFLAGS=`$PKG_CONFIG libzip --cflags`
|
||||
LIBZIP_LIBDIR=`$PKG_CONFIG libzip --variable=libdir`
|
||||
AC_MSG_RESULT(from pkgconfig: found in $LIBZIP_LIBDIR)
|
||||
|
||||
else
|
||||
for i in /usr/local /usr; do
|
||||
if test -r $i/include/zip.h; then
|
||||
LIBZIP_CFLAGS="-I$i/include"
|
||||
LIBZIP_LIBDIR="$i/$PHP_LIBDIR"
|
||||
AC_MSG_RESULT(in default path: found in $i)
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$LIBZIP_LIBDIR"; then
|
||||
AC_MSG_RESULT(not found)
|
||||
AC_MSG_ERROR(Please reinstall the libzip distribution)
|
||||
fi
|
||||
|
||||
dnl Could not think of a simple way to check libzip for overwrite support
|
||||
PHP_CHECK_LIBRARY(zip, zip_open,
|
||||
[
|
||||
PHP_ADD_LIBRARY_WITH_PATH(zip, $LIBZIP_LIBDIR, ZIP_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_LIBZIP,1,[ ])
|
||||
], [
|
||||
AC_MSG_ERROR(could not find usable libzip)
|
||||
], [
|
||||
-L$LIBZIP_LIBDIR
|
||||
])
|
||||
|
||||
AC_DEFINE(HAVE_ZIP,1,[ ])
|
||||
PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c, $ext_shared,, $LIBZIP_CFLAGS)
|
||||
PHP_SUBST(ZIP_SHARED_LIBADD)
|
||||
else
|
||||
|
||||
|
||||
PHP_ZIP_SOURCES="$PHP_ZIP_SOURCES lib/zip_add.c lib/zip_add_dir.c lib/zip_add_entry.c\
|
||||
lib/zip_close.c lib/zip_delete.c lib/zip_dir_add.c lib/zip_dirent.c lib/zip_discard.c lib/zip_entry.c\
|
||||
lib/zip_err_str.c lib/zip_error.c lib/zip_error_clear.c lib/zip_error_get.c lib/zip_error_get_sys_type.c\
|
||||
lib/zip_error_strerror.c lib/zip_error_to_str.c lib/zip_extra_field.c lib/zip_extra_field_api.c\
|
||||
lib/zip_fclose.c lib/zip_fdopen.c lib/zip_file_add.c lib/zip_file_error_clear.c lib/zip_file_error_get.c\
|
||||
lib/zip_file_get_comment.c lib/zip_file_get_offset.c lib/zip_file_rename.c lib/zip_file_replace.c\
|
||||
lib/zip_file_set_comment.c lib/zip_file_strerror.c lib/zip_filerange_crc.c lib/zip_fopen.c\
|
||||
lib/zip_fopen_encrypted.c lib/zip_fopen_index.c lib/zip_fopen_index_encrypted.c lib/zip_fread.c\
|
||||
lib/zip_get_archive_comment.c lib/zip_get_archive_flag.c lib/zip_get_compression_implementation.c\
|
||||
lib/zip_get_encryption_implementation.c lib/zip_get_file_comment.c lib/zip_get_name.c lib/zip_get_num_entries.c \
|
||||
lib/zip_get_num_files.c lib/zip_memdup.c lib/zip_name_locate.c lib/zip_new.c lib/zip_open.c lib/zip_rename.c lib/zip_replace.c\
|
||||
lib/zip_set_archive_comment.c lib/zip_set_archive_flag.c lib/zip_set_default_password.c lib/zip_set_file_comment.c\
|
||||
lib/zip_set_file_compression.c lib/zip_set_name.c lib/zip_source_buffer.c lib/zip_source_close.c lib/zip_source_crc.c\
|
||||
lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_file.c lib/zip_source_filep.c lib/zip_source_free.c\
|
||||
lib/zip_source_function.c lib/zip_source_layered.c lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c\
|
||||
lib/zip_source_read.c lib/zip_source_stat.c lib/zip_source_window.c lib/zip_source_zip.c lib/zip_source_zip_new.c\
|
||||
lib/zip_stat.c lib/zip_stat_index.c lib/zip_stat_init.c lib/zip_strerror.c lib/zip_string.c lib/zip_unchange.c lib/zip_unchange_all.c\
|
||||
lib/zip_unchange_archive.c lib/zip_unchange_data.c lib/zip_utf-8.c lib/mkstemp.c"
|
||||
|
||||
AC_DEFINE(HAVE_ZIP,1,[ ])
|
||||
PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/lib, 1)
|
||||
PHP_SUBST(ZIP_SHARED_LIBADD)
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_TYPES([int8_t])
|
||||
AC_CHECK_TYPES([int16_t])
|
||||
AC_CHECK_TYPES([int32_t])
|
||||
AC_CHECK_TYPES([int64_t])
|
||||
AC_CHECK_TYPES([uint8_t])
|
||||
AC_CHECK_TYPES([uint16_t])
|
||||
AC_CHECK_TYPES([uint32_t])
|
||||
AC_CHECK_TYPES([uint64_t])
|
||||
AC_CHECK_TYPES([ssize_t])
|
||||
|
||||
AC_CHECK_SIZEOF([short])
|
||||
AC_CHECK_SIZEOF([int])
|
||||
AC_CHECK_SIZEOF([long])
|
||||
AC_CHECK_SIZEOF([long long])
|
||||
AC_CHECK_SIZEOF([off_t])
|
||||
AC_CHECK_SIZEOF([size_t])
|
||||
|
||||
AC_PATH_PROG([TOUCH], [touch])
|
||||
AC_PATH_PROG([UNZIP], [unzip])
|
||||
|
||||
AC_STRUCT_TIMEZONE
|
||||
|
||||
case $host_os
|
||||
in
|
||||
*bsd*) MANFMT=mdoc;;
|
||||
*) MANFMT=man;;
|
||||
esac
|
||||
AC_SUBST([MANFMT])
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifndef HAVE_SSIZE_T
|
||||
# if SIZEOF_SIZE_T == SIZEOF_INT
|
||||
typedef int ssize_t;
|
||||
# elif SIZEOF_SIZE_T == SIZEOF_LONG
|
||||
typedef long ssize_t;
|
||||
# elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
|
||||
typedef long long ssize_t;
|
||||
# else
|
||||
#error no suitable type for ssize_t found
|
||||
# endif
|
||||
#endif
|
||||
])
|
||||
|
||||
|
||||
dnl so we always include the known-good working hack.
|
||||
PHP_ADD_MAKEFILE_FRAGMENT
|
||||
|
|
|
@ -9,36 +9,28 @@ if (PHP_ZIP != "no") {
|
|||
(PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "zip", PHP_ZIP)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED)))
|
||||
) {
|
||||
EXTENSION('zip', 'php_zip.c zip_stream.c');
|
||||
ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_error.c zip_fclose.c \
|
||||
zip_fread.c zip_open.c zip_source_filep.c \
|
||||
zip_strerror.c zip_close.c zip_error_get.c \
|
||||
zip_file_error_get.c zip_free.c zip_rename.c \
|
||||
zip_source_free.c zip_unchange_all.c zip_delete.c \
|
||||
zip_error_get_sys_type.c zip_file_get_offset.c \
|
||||
zip_get_name.c zip_replace.c zip_source_function.c \
|
||||
zip_unchange.c zip_dirent.c zip_error_strerror.c \
|
||||
zip_filerange_crc.c zip_file_strerror.c zip_get_num_files.c \
|
||||
zip_get_archive_flag.c zip_set_archive_flag.c \
|
||||
zip_set_name.c zip_source_zip.c zip_unchange_data.c \
|
||||
zip_entry_free.c zip_error_to_str.c zip_fopen.c \
|
||||
zip_name_locate.c zip_source_buffer.c zip_stat.c \
|
||||
zip_entry_new.c zip_err_str.c zip_fopen_index.c \
|
||||
zip_new.c zip_source_file.c zip_stat_index.c \
|
||||
zip_get_archive_comment.c zip_get_file_comment.c \
|
||||
zip_set_archive_comment.c zip_set_file_comment.c \
|
||||
zip_unchange_archive.c zip_memdup.c zip_stat_init.c \
|
||||
zip_add_dir.c zip_file_error_clear.c zip_error_clear.c \
|
||||
zip_fdopen.c zip_fopen_encrypted.c zip_fopen_index_encrypted.c \
|
||||
zip_get_compression_implementation.c zip_get_encryption_implementation.c \
|
||||
zip_get_file_extra.c zip_get_num_entries.c zip_set_default_password.c \
|
||||
zip_set_file_extra.c zip_source_close.c zip_source_crc.c \
|
||||
zip_source_deflate.c zip_source_error.c zip_source_layered.c \
|
||||
zip_source_open.c zip_source_pkware.c zip_source_pop.c \
|
||||
zip_source_read.c zip_source_stat.c", "zip");
|
||||
ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_add_dir.c zip_add_entry.c\
|
||||
zip_close.c zip_delete.c zip_dir_add.c zip_dirent.c zip_discard.c zip_entry.c\
|
||||
zip_err_str.c zip_error.c zip_error_clear.c zip_error_get.c zip_error_get_sys_type.c\
|
||||
zip_error_strerror.c zip_error_to_str.c zip_extra_field.c zip_extra_field_api.c\
|
||||
zip_fclose.c zip_fdopen.c zip_file_add.c zip_file_error_clear.c zip_file_error_get.c\
|
||||
zip_file_get_comment.c zip_file_get_offset.c zip_file_rename.c zip_file_replace.c\
|
||||
zip_file_set_comment.c zip_file_strerror.c zip_filerange_crc.c zip_fopen.c\
|
||||
zip_fopen_encrypted.c zip_fopen_index.c zip_fopen_index_encrypted.c zip_fread.c\
|
||||
zip_get_archive_comment.c zip_get_archive_flag.c zip_get_compression_implementation.c\
|
||||
zip_get_encryption_implementation.c zip_get_file_comment.c zip_get_name.c zip_get_num_entries.c \
|
||||
zip_get_num_files.c zip_memdup.c zip_name_locate.c zip_new.c zip_open.c zip_rename.c zip_replace.c\
|
||||
zip_set_archive_comment.c zip_set_archive_flag.c zip_set_default_password.c zip_set_file_comment.c\
|
||||
zip_set_file_compression.c zip_set_name.c zip_source_buffer.c zip_source_close.c zip_source_crc.c\
|
||||
zip_source_deflate.c zip_source_error.c zip_source_file.c zip_source_filep.c zip_source_free.c\
|
||||
zip_source_function.c zip_source_layered.c zip_source_open.c zip_source_pkware.c 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 zip_strerror.c zip_string.c zip_unchange.c zip_unchange_all.c\
|
||||
zip_unchange_archive.c zip_unchange_data.c zip_utf-8.c mkstemp.c", "zip");
|
||||
|
||||
AC_DEFINE('HAVE_ZIP', 1);
|
||||
ADD_FLAG("CFLAGS_ZIP", "/D _WIN32");
|
||||
} else {
|
||||
WARNING("zip not enabled; libraries and headers not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
ext/zip/examples/addglob.php
Normal file
14
ext/zip/examples/addglob.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
$z = new ZipArchive;
|
||||
$z->open('a.zip', ZIPARCHIVE::CREATE);
|
||||
|
||||
/* or 'remove_all_path' => 0*/
|
||||
$options = array(
|
||||
'remove_path' => '/home/francis/myimages',
|
||||
'add_path' => 'images/',
|
||||
);
|
||||
$found = $z->addGlob("/home/pierre/cvs/gd/libgd/tests/*.png", 0, $options);
|
||||
var_dump($found);
|
||||
$z->close();
|
||||
|
13
ext/zip/examples/addpattern.php
Normal file
13
ext/zip/examples/addpattern.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
$z = new ZipArchive;
|
||||
$z->open('a.zip', ZIPARCHIVE::CREATE);
|
||||
|
||||
/* or 'remove_all_path' => 0*/
|
||||
$options = array('remove_path' => '/home/pierre/cvs/gd/libgd/tests',
|
||||
'add_path' => 'images/',
|
||||
);
|
||||
|
||||
$found = $z->addPattern("/(\.png)$/i", "/home/pierre/cvs/gd/libgd/tests", $options);
|
||||
var_dump($found);
|
||||
$z->close();
|
||||
|
151
ext/zip/lib/mkstemp.c
Normal file
151
ext/zip/lib/mkstemp.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* Adapted from NetBSB libc by Dieter Baron */
|
||||
|
||||
/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_mkstemp(char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int ret;
|
||||
ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE);
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int fd;
|
||||
char *start, *trv;
|
||||
struct stat sbuf;
|
||||
pid_t pid;
|
||||
|
||||
/* To guarantee multiple calls generate unique names even if
|
||||
the file is not created. 676 different possibilities with 7
|
||||
or more X's, 26 with 6 or less. */
|
||||
static char xtra[2] = "aa";
|
||||
int xcnt = 0;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
/* Move to end of path and count trailing X's. */
|
||||
for (trv = path; *trv; ++trv)
|
||||
if (*trv == 'X')
|
||||
xcnt++;
|
||||
else
|
||||
xcnt = 0;
|
||||
|
||||
/* Use at least one from xtra. Use 2 if more than 6 X's. */
|
||||
if (*(trv - 1) == 'X')
|
||||
*--trv = xtra[0];
|
||||
if (xcnt > 6 && *(trv - 1) == 'X')
|
||||
*--trv = xtra[1];
|
||||
|
||||
/* Set remaining X's to pid digits with 0's to the left. */
|
||||
while (*--trv == 'X') {
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
|
||||
/* update xtra for next call. */
|
||||
if (xtra[0] != 'z')
|
||||
xtra[0]++;
|
||||
else {
|
||||
xtra[0] = 'a';
|
||||
if (xtra[1] != 'z')
|
||||
xtra[1]++;
|
||||
else
|
||||
xtra[1] = 'a';
|
||||
}
|
||||
|
||||
/*
|
||||
* check the target directory; if you have six X's and it
|
||||
* doesn't exist this runs for a *very* long time.
|
||||
*/
|
||||
for (start = trv + 1;; --trv) {
|
||||
if (trv <= path)
|
||||
break;
|
||||
if (*trv == '/') {
|
||||
*trv = '\0';
|
||||
if (stat(path, &sbuf))
|
||||
return (0);
|
||||
if (!S_ISDIR(sbuf.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
return (0);
|
||||
}
|
||||
*trv = '/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0)
|
||||
return (fd);
|
||||
if (errno != EEXIST)
|
||||
return (0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
for (trv = start;;) {
|
||||
if (!*trv)
|
||||
return (0);
|
||||
if (*trv == 'z')
|
||||
*trv++ = 'a';
|
||||
else {
|
||||
if (isdigit((unsigned char)*trv))
|
||||
*trv = 'a';
|
||||
else
|
||||
++*trv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
#endif
|
||||
}
|
57
ext/zip/lib/php_zip_config.w32.h
Normal file
57
ext/zip/lib/php_zip_config.w32.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef HAD_CONFIG_H
|
||||
#define HAD_CONFIG_H
|
||||
#define HAVE__CLOSE
|
||||
#define HAVE__DUP
|
||||
#define HAVE__FDOPEN
|
||||
#define HAVE__FILENO
|
||||
#define HAVE__OPEN
|
||||
#define HAVE__SNPRINTF
|
||||
/* #undef HAVE__STRCMPI */
|
||||
#define HAVE__STRDUP
|
||||
#define HAVE__STRICMP
|
||||
/* #undef HAVE_FSEEKO */
|
||||
/* #undef HAVE_FTELLO */
|
||||
/* #undef HAVE_MKSTEMP */
|
||||
#define HAVE_MOVEFILEEXA
|
||||
/* #undef HAVE_SNPRINTF */
|
||||
/* #undef HAVE_STRCASECMP */
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
/* #undef HAVE_STRUCT_TM_TM_ZONE */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
#define PACKAGE "libzip"
|
||||
#define VERSION "0.10.b"
|
||||
|
||||
/* #undef HAVE_SSIZE_T */
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
|
||||
#ifndef SIZE_T_LIBZIP
|
||||
#define SIZE_T_LIBZIP 4
|
||||
#endif
|
||||
#ifndef INT_LIBZIP
|
||||
#define INT_LIBZIP 4
|
||||
#endif
|
||||
#ifndef LONG_LIBZIP
|
||||
#define LONG_LIBZIP 4
|
||||
#endif
|
||||
#ifndef LONG_LONG_LIBZIP
|
||||
#define LONG_LONG_LIBZIP 8
|
||||
#endif
|
||||
#ifndef SIZEOF_OFF_T
|
||||
#define SIZEOF_OFF_T 4
|
||||
#endif
|
||||
|
||||
# if SIZE_T_LIBZIP == INT_LIBZIP
|
||||
# ifndef ssize_t
|
||||
typedef int ssize_t;
|
||||
# endif
|
||||
# elif SIZE_T_LIBZIP == LONG_LIBZIP
|
||||
typedef long ssize_t;
|
||||
# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP
|
||||
typedef long long ssize_t;
|
||||
# else
|
||||
#error no suitable type for ssize_t found
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* HAD_CONFIG_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>
|
||||
|
@ -38,18 +38,30 @@
|
|||
#include "main/php.h"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# include "zip_win32.h"
|
||||
# ifdef PHP_ZIP_EXPORTS
|
||||
# define ZIP_EXTERN(rt) __declspec(dllexport)rt _stdcall
|
||||
# else
|
||||
# define ZIP_EXTERN(rt) rt
|
||||
# endif
|
||||
#ifdef PHP_ZIP_EXPORTS
|
||||
# define ZIP_EXTERN __declspec(dllexport) _stdcall
|
||||
# else
|
||||
# define ZIP_EXTERN
|
||||
# endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define ZIP_EXTERN(rt) __attribute__ ((visibility("default"))) rt
|
||||
# define ZIP_EXTERN __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define ZIP_EXTERN(rt) rt
|
||||
# define ZIP_EXTERN
|
||||
#endif
|
||||
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
#include "zipconf.h"
|
||||
|
@ -63,27 +75,40 @@ BEGIN_EXTERN_C()
|
|||
#define ZIP_CREATE 1
|
||||
#define ZIP_EXCL 2
|
||||
#define ZIP_CHECKCONS 4
|
||||
#define ZIP_OVERWRITE 8
|
||||
|
||||
#define ZIP_TRUNCATE 8
|
||||
|
||||
/* flags for zip_name_locate, zip_fopen, zip_stat, ... */
|
||||
|
||||
#define ZIP_FL_NOCASE 1 /* ignore case on name lookup */
|
||||
#define ZIP_FL_NODIR 2 /* ignore directory component */
|
||||
#define ZIP_FL_COMPRESSED 4 /* read compressed data */
|
||||
#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */
|
||||
#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */
|
||||
#define ZIP_FL_ENCRYPTED 32 /* read encrypted data
|
||||
(implies ZIP_FL_COMPRESSED) */
|
||||
#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */
|
||||
#define ZIP_FL_NODIR 2u /* ignore directory component */
|
||||
#define ZIP_FL_COMPRESSED 4u /* read compressed data */
|
||||
#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */
|
||||
#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */
|
||||
#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
|
||||
#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */
|
||||
#define ZIP_FL_ENC_RAW 64u /* get unmodified string */
|
||||
#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */
|
||||
#define ZIP_FL_LOCAL 256u /* in local header */
|
||||
#define ZIP_FL_CENTRAL 512u /* in central directory */
|
||||
/* 1024u reserved for internal use */
|
||||
#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */
|
||||
#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */
|
||||
#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */
|
||||
|
||||
/* archive global flags flags */
|
||||
|
||||
#define ZIP_AFL_TORRENT 1 /* torrent zipped */
|
||||
#define ZIP_AFL_RDONLY 2 /* read only -- cannot be cleared */
|
||||
#define ZIP_AFL_TORRENT 1u /* torrent zipped */
|
||||
#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
|
||||
|
||||
|
||||
/* create a new extra field */
|
||||
|
||||
#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX
|
||||
#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX
|
||||
|
||||
/* flags for compression and encryption sources */
|
||||
|
||||
#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */
|
||||
#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */
|
||||
|
||||
|
||||
|
@ -178,15 +203,15 @@ enum zip_source_cmd {
|
|||
|
||||
#define ZIP_SOURCE_ERR_LOWER -2
|
||||
|
||||
#define ZIP_STAT_NAME 0x0001
|
||||
#define ZIP_STAT_INDEX 0x0002
|
||||
#define ZIP_STAT_SIZE 0x0004
|
||||
#define ZIP_STAT_COMP_SIZE 0x0008
|
||||
#define ZIP_STAT_MTIME 0x0010
|
||||
#define ZIP_STAT_CRC 0x0020
|
||||
#define ZIP_STAT_COMP_METHOD 0x0040
|
||||
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080
|
||||
#define ZIP_STAT_FLAGS 0x0100
|
||||
#define ZIP_STAT_NAME 0x0001u
|
||||
#define ZIP_STAT_INDEX 0x0002u
|
||||
#define ZIP_STAT_SIZE 0x0004u
|
||||
#define ZIP_STAT_COMP_SIZE 0x0008u
|
||||
#define ZIP_STAT_MTIME 0x0010u
|
||||
#define ZIP_STAT_CRC 0x0020u
|
||||
#define ZIP_STAT_COMP_METHOD 0x0040u
|
||||
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u
|
||||
#define ZIP_STAT_FLAGS 0x0100u
|
||||
|
||||
struct zip_stat {
|
||||
zip_uint64_t valid; /* which fields have valid values */
|
||||
|
@ -205,72 +230,78 @@ struct zip;
|
|||
struct zip_file;
|
||||
struct zip_source;
|
||||
|
||||
typedef zip_uint32_t zip_flags_t;
|
||||
|
||||
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t,
|
||||
enum zip_source_cmd);
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *);
|
||||
ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *);
|
||||
ZIP_EXTERN(int) zip_close(struct zip *);
|
||||
ZIP_EXTERN(int) zip_delete(struct zip *, zip_uint64_t);
|
||||
ZIP_EXTERN(void) zip_error_clear(struct zip *);
|
||||
ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *);
|
||||
ZIP_EXTERN(int) zip_error_get_sys_type(int);
|
||||
ZIP_EXTERN(int) zip_error_to_str(char *, zip_uint64_t, int, int);
|
||||
ZIP_EXTERN(int) zip_fclose(struct zip_file *);
|
||||
ZIP_EXTERN(struct zip *)zip_fdopen(int, int, int *);
|
||||
ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *);
|
||||
ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *);
|
||||
ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *);
|
||||
ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int);
|
||||
ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *,
|
||||
int, const char *);
|
||||
ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, zip_uint64_t, int);
|
||||
ZIP_EXTERN(struct zip_file *)zip_fopen_index_encrypted(struct zip *,
|
||||
zip_uint64_t, int,
|
||||
const char *);
|
||||
ZIP_EXTERN(zip_int64_t) zip_fread(struct zip_file *, void *, zip_uint64_t);
|
||||
ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int);
|
||||
ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int);
|
||||
ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t,
|
||||
int *, int);
|
||||
ZIP_EXTERN(const char *)zip_get_file_extra(struct zip *, zip_uint64_t,
|
||||
int *, int);
|
||||
ZIP_EXTERN(const char *)zip_get_name(struct zip *, zip_uint64_t, int);
|
||||
ZIP_EXTERN(zip_uint64_t) zip_get_num_entries(struct zip *, int);
|
||||
ZIP_EXTERN(int) zip_get_num_files(struct zip *); /* deprecated, use zip_get_num_entries instead */
|
||||
ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int);
|
||||
ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *);
|
||||
ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *);
|
||||
ZIP_EXTERN(int) zip_replace(struct zip *, zip_uint64_t, struct zip_source *);
|
||||
ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int);
|
||||
ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int);
|
||||
ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *);
|
||||
ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t,
|
||||
const char *, int);
|
||||
ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t,
|
||||
const char *, int);
|
||||
ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *,
|
||||
zip_uint64_t, int);
|
||||
ZIP_EXTERN(struct) zip_source *zip_source_file(struct zip *, const char *,
|
||||
zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN(struct) zip_source *zip_source_filep(struct zip *, FILE *,
|
||||
zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN(void) zip_source_free(struct zip_source *);
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *,
|
||||
zip_source_callback, void *);
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *,
|
||||
zip_uint64_t, int,
|
||||
zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *);
|
||||
ZIP_EXTERN(int) zip_stat_index(struct zip *, zip_uint64_t, int,
|
||||
struct zip_stat *);
|
||||
ZIP_EXTERN(void) zip_stat_init(struct zip_stat *);
|
||||
ZIP_EXTERN(const char *)zip_strerror(struct zip *);
|
||||
ZIP_EXTERN(int) zip_unchange(struct zip *, zip_uint64_t);
|
||||
ZIP_EXTERN(int) zip_unchange_all(struct zip *);
|
||||
ZIP_EXTERN(int) zip_unchange_archive(struct zip *);
|
||||
#ifndef ZIP_DISABLE_DEPRECATED
|
||||
ZIP_EXTERN zip_int64_t zip_add(struct zip *, const char *, struct zip_source *); /* use zip_file_add */
|
||||
ZIP_EXTERN zip_int64_t zip_add_dir(struct zip *, const char *); /* use zip_dir_add */
|
||||
ZIP_EXTERN const char *zip_get_file_comment(struct zip *, zip_uint64_t, int *, int); /* use zip_file_get_comment */
|
||||
ZIP_EXTERN int zip_get_num_files(struct zip *); /* use zip_get_num_entries instead */
|
||||
ZIP_EXTERN int zip_rename(struct zip *, zip_uint64_t, const char *); /* use zip_file_rename */
|
||||
ZIP_EXTERN int zip_replace(struct zip *, zip_uint64_t, struct zip_source *); /* use zip_file_replace */
|
||||
ZIP_EXTERN int zip_set_file_comment(struct zip *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */
|
||||
#endif
|
||||
|
||||
ZIP_EXTERN int zip_archive_set_tempdir(struct zip *, const char *);
|
||||
ZIP_EXTERN zip_int64_t zip_file_add(struct zip *, const char *, struct zip_source *, zip_flags_t);
|
||||
ZIP_EXTERN zip_int64_t zip_dir_add(struct zip *, const char *, zip_flags_t);
|
||||
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 int zip_file_extra_field_delete(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_extra_field_delete_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN void zip_error_clear(struct zip *);
|
||||
ZIP_EXTERN void zip_error_get(struct zip *, int *, int *);
|
||||
ZIP_EXTERN int zip_error_get_sys_type(int);
|
||||
ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int);
|
||||
ZIP_EXTERN int zip_fclose(struct zip_file *);
|
||||
ZIP_EXTERN struct zip *zip_fdopen(int, int, int *);
|
||||
ZIP_EXTERN void zip_file_error_clear(struct zip_file *);
|
||||
ZIP_EXTERN void zip_file_error_get(struct zip_file *, int *, int *);
|
||||
ZIP_EXTERN const char *zip_file_strerror(struct zip_file *);
|
||||
ZIP_EXTERN struct zip_file *zip_fopen(struct zip *, const char *, zip_flags_t);
|
||||
ZIP_EXTERN struct zip_file *zip_fopen_encrypted(struct zip *, const char *, zip_flags_t, const char *);
|
||||
ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, zip_uint64_t, zip_flags_t);
|
||||
ZIP_EXTERN struct zip_file *zip_fopen_index_encrypted(struct zip *, zip_uint64_t, zip_flags_t, const char *);
|
||||
ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *, void *, zip_uint64_t);
|
||||
ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, zip_flags_t);
|
||||
ZIP_EXTERN int zip_get_archive_flag(struct zip *, zip_flags_t, zip_flags_t);
|
||||
ZIP_EXTERN const char *zip_file_get_comment(struct zip *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
|
||||
ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
|
||||
ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
|
||||
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(struct zip *, zip_uint64_t, zip_flags_t);
|
||||
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, zip_flags_t);
|
||||
ZIP_EXTERN zip_int64_t zip_get_num_entries(struct zip *, zip_flags_t);
|
||||
ZIP_EXTERN zip_int64_t zip_name_locate(struct zip *, const char *, zip_flags_t);
|
||||
ZIP_EXTERN struct zip *zip_open(const char *, int, int *);
|
||||
ZIP_EXTERN int zip_file_rename(struct zip *, zip_uint64_t, const char *, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_replace(struct zip *, zip_uint64_t, struct zip_source *, zip_flags_t);
|
||||
ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, zip_uint16_t);
|
||||
ZIP_EXTERN int zip_set_archive_flag(struct zip *, zip_flags_t, int);
|
||||
ZIP_EXTERN int zip_set_default_password(struct zip *, const char *);
|
||||
ZIP_EXTERN int zip_file_set_comment(struct zip *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN int zip_set_file_compression(struct zip *, zip_uint64_t, zip_int32_t, zip_uint32_t);
|
||||
ZIP_EXTERN int zip_file_extra_field_set(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *, zip_uint64_t, int);
|
||||
ZIP_EXTERN struct zip_source *zip_source_file(struct zip *, const char *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN struct zip_source *zip_source_filep(struct zip *, FILE *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN void zip_source_free(struct zip_source *);
|
||||
ZIP_EXTERN struct zip_source *zip_source_function(struct zip *, zip_source_callback, void *);
|
||||
ZIP_EXTERN struct zip_source *zip_source_zip(struct zip *, struct zip *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN int zip_stat(struct zip *, const char *, zip_flags_t, struct zip_stat *);
|
||||
ZIP_EXTERN int zip_stat_index(struct zip *, zip_uint64_t, zip_flags_t, struct zip_stat *);
|
||||
ZIP_EXTERN void zip_stat_init(struct zip_stat *);
|
||||
ZIP_EXTERN const char *zip_strerror(struct zip *);
|
||||
ZIP_EXTERN int zip_unchange(struct zip *, zip_uint64_t);
|
||||
ZIP_EXTERN int zip_unchange_all(struct zip *);
|
||||
ZIP_EXTERN int zip_unchange_archive(struct zip *);
|
||||
|
||||
|
||||
END_EXTERN_C();
|
||||
#endif /* _HAD_ZIP_H */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_add.c -- add file via callback 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>
|
||||
|
@ -33,6 +33,7 @@
|
|||
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
@ -44,13 +45,8 @@
|
|||
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
|
||||
*/
|
||||
|
||||
ZIP_EXTERN(zip_int64_t)
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_add(struct zip *za, const char *name, struct zip_source *source)
|
||||
{
|
||||
if (name == NULL || source == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_replace(za, ZIP_UINT64_MAX, name, source);
|
||||
return zip_file_add(za, name, source, 0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_add_dir.c -- add directory
|
||||
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 1999-2013 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,56 +33,15 @@
|
|||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
ZIP_EXTERN(zip_int64_t)
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_add_dir(struct zip *za, const char *name)
|
||||
{
|
||||
int len;
|
||||
zip_int64_t ret;
|
||||
char *s;
|
||||
struct zip_source *source;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = NULL;
|
||||
len = strlen(name);
|
||||
|
||||
if (name[len-1] != '/') {
|
||||
if ((s=(char *)malloc(len+2)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
strcpy(s, name);
|
||||
s[len] = '/';
|
||||
s[len+1] = '\0';
|
||||
}
|
||||
|
||||
if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _zip_replace(za, -1, s ? s : name, source);
|
||||
|
||||
free(s);
|
||||
if (ret < 0)
|
||||
zip_source_free(source);
|
||||
|
||||
return ret;
|
||||
return zip_dir_add(za, name, 0);
|
||||
}
|
||||
|
|
66
ext/zip/lib/zip_add_entry.c
Normal file
66
ext/zip/lib/zip_add_entry.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
zip_add_entry.c -- create and init struct zip_entry
|
||||
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>
|
||||
|
||||
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"
|
||||
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
zip_int64_t
|
||||
_zip_add_entry(struct zip *za)
|
||||
{
|
||||
zip_uint64_t idx;
|
||||
|
||||
if (za->nentry+1 >= za->nentry_alloc) {
|
||||
struct zip_entry *rentries;
|
||||
zip_uint64_t nalloc = za->nentry_alloc + 16;
|
||||
rentries = (struct zip_entry *)realloc(za->entry, sizeof(struct zip_entry) * nalloc);
|
||||
if (!rentries) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
za->entry = rentries;
|
||||
za->nentry_alloc = nalloc;
|
||||
}
|
||||
|
||||
idx = za->nentry++;
|
||||
|
||||
_zip_entry_init(za->entry+idx);
|
||||
|
||||
return (zip_int64_t)idx;
|
||||
}
|
|
@ -38,6 +38,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
|
@ -49,110 +52,106 @@
|
|||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
static int add_data(struct zip *, struct zip_source *, struct zip_dirent *,
|
||||
FILE *);
|
||||
static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
|
||||
|
||||
|
||||
/* max deflate size increase: size + ceil(size/16k)*5+6 */
|
||||
#define MAX_DEFLATE_SIZE_32 4293656963u
|
||||
|
||||
static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, FILE *);
|
||||
static int copy_data(FILE *, zip_uint64_t, FILE *, struct zip_error *);
|
||||
static int copy_source(struct zip *, struct zip_source *, FILE *);
|
||||
static int write_cdir(struct zip *, struct zip_cdir *, FILE *);
|
||||
static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
|
||||
static int write_cdir(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *);
|
||||
static char *_zip_create_temp_output(struct zip *, FILE **);
|
||||
static int _zip_torrentzip_cmp(const void *, const void *);
|
||||
|
||||
|
||||
|
||||
struct filelist {
|
||||
int idx;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_close(struct zip *za)
|
||||
{
|
||||
int survivors;
|
||||
int i, j, error;
|
||||
zip_uint64_t i, j, survivors;
|
||||
int error;
|
||||
char *temp;
|
||||
FILE *out;
|
||||
#ifndef PHP_WIN32
|
||||
mode_t mask;
|
||||
#endif
|
||||
struct zip_cdir *cd;
|
||||
struct zip_dirent de;
|
||||
struct filelist *filelist;
|
||||
struct zip_filelist *filelist;
|
||||
int reopen_on_error;
|
||||
int new_torrentzip;
|
||||
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 ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors))
|
||||
== NULL)
|
||||
return -1;
|
||||
|
||||
if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) {
|
||||
free(filelist);
|
||||
return -1;
|
||||
if (!changed) {
|
||||
zip_discard(za);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0; i<survivors; i++)
|
||||
_zip_dirent_init(&cd->entry[i]);
|
||||
if (survivors > za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((filelist=(struct zip_filelist *)malloc(sizeof(filelist[0])*survivors)) == NULL)
|
||||
return -1;
|
||||
|
||||
/* archive comment is special for torrentzip */
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) {
|
||||
cd->comment = _zip_memdup(TORRENT_SIG "XXXXXXXX",
|
||||
TORRENT_SIG_LEN + TORRENT_CRC_LEN,
|
||||
&za->error);
|
||||
if (cd->comment == NULL) {
|
||||
_zip_cdir_free(cd);
|
||||
free(filelist);
|
||||
return -1;
|
||||
}
|
||||
cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN;
|
||||
}
|
||||
else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) {
|
||||
if (_zip_cdir_set_comment(cd, za) == -1) {
|
||||
_zip_cdir_free(cd);
|
||||
/* XXX: use internal function when zip_set_archive_comment clears TORRENT flag */
|
||||
if (zip_set_archive_comment(za, TORRENT_SIG "XXXXXXXX", TORRENT_SIG_LEN + TORRENT_CRC_LEN) < 0) {
|
||||
free(filelist);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
|
||||
_zip_cdir_free(cd);
|
||||
free(filelist);
|
||||
return -1;
|
||||
}
|
||||
/* XXX: if no longer torrentzip and archive comment not changed by user, delete it */
|
||||
|
||||
|
||||
/* create list of files with index into original archive */
|
||||
for (i=j=0; i<za->nentry; i++) {
|
||||
if (za->entry[i].state == ZIP_ST_DELETED)
|
||||
if (za->entry[i].deleted)
|
||||
continue;
|
||||
|
||||
if (j >= survivors) {
|
||||
free(filelist);
|
||||
_zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
filelist[j].idx = i;
|
||||
filelist[j].name = zip_get_name(za, i, 0);
|
||||
j++;
|
||||
}
|
||||
if (j < survivors) {
|
||||
free(filelist);
|
||||
_zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
|
||||
free(filelist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
|
||||
qsort(filelist, survivors, sizeof(filelist[0]),
|
||||
_zip_torrentzip_cmp);
|
||||
|
@ -162,106 +161,49 @@ zip_close(struct zip *za)
|
|||
ZIP_FL_UNCHANGED) == 0);
|
||||
error = 0;
|
||||
for (j=0; j<survivors; j++) {
|
||||
i = filelist[j].idx;
|
||||
int new_data;
|
||||
struct zip_entry *entry;
|
||||
struct zip_dirent *de;
|
||||
|
||||
_zip_dirent_init(&de);
|
||||
i = filelist[j].idx;
|
||||
entry = za->entry+i;
|
||||
|
||||
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || new_torrentzip || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD));
|
||||
|
||||
/* create new local directory entry */
|
||||
if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) {
|
||||
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
|
||||
_zip_dirent_torrent_normalize(&de);
|
||||
|
||||
/* use it as central directory entry */
|
||||
memcpy(cd->entry+j, &de, sizeof(cd->entry[j]));
|
||||
|
||||
/* set/update file name */
|
||||
if (za->entry[i].ch_filename == NULL) {
|
||||
if (za->entry[i].state == ZIP_ST_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 (entry->changes == NULL) {
|
||||
if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* copy existing directory entries */
|
||||
if ((NULL == za->zp) || (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1,
|
||||
&za->error) != 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
|
||||
if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
|
||||
de.crc = za->cdir->entry[i].crc;
|
||||
de.comp_size = za->cdir->entry[i].comp_size;
|
||||
de.uncomp_size = za->cdir->entry[i].uncomp_size;
|
||||
de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
cd->entry[j].bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
}
|
||||
de = entry->changes;
|
||||
|
||||
if (_zip_read_local_ef(za, i) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (za->entry[i].ch_filename) {
|
||||
free(de.filename);
|
||||
if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
de.filename_len = strlen(de.filename);
|
||||
cd->entry[j].filename = za->entry[i].ch_filename;
|
||||
cd->entry[j].filename_len = de.filename_len;
|
||||
}
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
|
||||
_zip_dirent_torrent_normalize(entry->changes);
|
||||
|
||||
if (za->entry[i].ch_extra_len != -1) {
|
||||
free(de.extrafield);
|
||||
if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len);
|
||||
de.extrafield_len = za->entry[i].ch_extra_len;
|
||||
/* as the rest of cd entries, its malloc/free is done by za */
|
||||
/* TODO unsure if this should also be set in the CD --
|
||||
* not done for now
|
||||
cd->entry[j].extrafield = za->entry[i].ch_extra;
|
||||
cd->entry[j].extrafield_len = za->entry[i].ch_extra_len;
|
||||
*/
|
||||
}
|
||||
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0
|
||||
&& za->entry[i].ch_comment_len != -1) {
|
||||
/* as the rest of cd entries, its malloc/free is done by za */
|
||||
cd->entry[j].comment = za->entry[i].ch_comment;
|
||||
cd->entry[j].comment_len = za->entry[i].ch_comment_len;
|
||||
}
|
||||
de->offset = (zip_uint64_t)ftello(out); /* XXX: check for errors */
|
||||
|
||||
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 (!ZIP_ENTRY_DATA_CHANGED(entry)) {
|
||||
if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) {
|
||||
/* add_data writes dirent */
|
||||
if (add_data(za, zs ? zs : entry->source, de, out) < 0) {
|
||||
error = 1;
|
||||
if (zs)
|
||||
zip_source_free(zs);
|
||||
|
@ -269,51 +211,49 @@ zip_close(struct zip *za)
|
|||
}
|
||||
if (zs)
|
||||
zip_source_free(zs);
|
||||
|
||||
cd->entry[j].last_mod = de.last_mod;
|
||||
cd->entry[j].comp_method = de.comp_method;
|
||||
cd->entry[j].comp_size = de.comp_size;
|
||||
cd->entry[j].uncomp_size = de.uncomp_size;
|
||||
cd->entry[j].crc = de.crc;
|
||||
}
|
||||
else {
|
||||
if (_zip_dirent_write(&de, out, 1, &za->error) < 0) {
|
||||
zip_uint64_t offset;
|
||||
|
||||
/* when copying data, all sizes are known -> no data descriptor needed */
|
||||
de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
if (_zip_dirent_write(de, out, ZIP_FL_LOCAL, &za->error) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
/* we just read the local dirent, file is at correct position */
|
||||
if (copy_data(za->zp, cd->entry[j].comp_size, out,
|
||||
&za->error) < 0) {
|
||||
if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if ((fseek(za->zp, (off_t)offset, SEEK_SET) < 0)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (copy_data(za->zp, de->comp_size, out, &za->error) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_zip_dirent_finalize(&de);
|
||||
if (!error) {
|
||||
if (write_cdir(za, filelist, survivors, out) < 0)
|
||||
error = 1;
|
||||
}
|
||||
|
||||
free(filelist);
|
||||
|
||||
if (!error) {
|
||||
if (write_cdir(za, cd, out) < 0)
|
||||
error = 1;
|
||||
}
|
||||
|
||||
/* pointers in cd entries are owned by za */
|
||||
cd->nentry = 0;
|
||||
_zip_cdir_free(cd);
|
||||
|
||||
if (error) {
|
||||
_zip_dirent_finalize(&de);
|
||||
fclose(out);
|
||||
remove(temp);
|
||||
(void)remove(temp);
|
||||
free(temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fclose(out) != 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_CLOSE, errno);
|
||||
remove(temp);
|
||||
(void)remove(temp);
|
||||
free(temp);
|
||||
return -1;
|
||||
}
|
||||
|
@ -325,7 +265,7 @@ zip_close(struct zip *za)
|
|||
}
|
||||
if (_zip_rename(temp, za->zn) != 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RENAME, errno);
|
||||
remove(temp);
|
||||
(void)remove(temp);
|
||||
free(temp);
|
||||
if (reopen_on_error) {
|
||||
/* ignore errors, since we're already in an error case */
|
||||
|
@ -339,56 +279,112 @@ zip_close(struct zip *za)
|
|||
chmod(za->zn, 0666&~mask);
|
||||
#endif
|
||||
|
||||
_zip_free(za);
|
||||
free(temp);
|
||||
|
||||
zip_discard(za);
|
||||
free(temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
|
||||
FILE *ft)
|
||||
add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, FILE *ft)
|
||||
{
|
||||
off_t offstart, offdata, offend;
|
||||
struct zip_stat st;
|
||||
struct zip_source *s2;
|
||||
zip_compression_implementation comp_impl;
|
||||
int ret;
|
||||
int is_zip64;
|
||||
zip_flags_t flags;
|
||||
|
||||
if (zip_source_stat(src, &st) < 0) {
|
||||
_zip_error_set_from_source(&za->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
|
||||
st.valid |= ZIP_STAT_COMP_METHOD;
|
||||
st.comp_method = ZIP_CM_STORE;
|
||||
}
|
||||
|
||||
if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
|
||||
de->comp_method = st.comp_method;
|
||||
else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
|
||||
st.valid |= ZIP_STAT_COMP_SIZE;
|
||||
st.comp_size = st.size;
|
||||
}
|
||||
else {
|
||||
/* we'll recompress */
|
||||
st.valid &= ~ZIP_STAT_COMP_SIZE;
|
||||
}
|
||||
|
||||
|
||||
flags = ZIP_EF_LOCAL;
|
||||
|
||||
if ((st.valid & ZIP_STAT_SIZE) == 0)
|
||||
flags |= ZIP_FL_FORCE_ZIP64;
|
||||
else {
|
||||
de->uncomp_size = st.size;
|
||||
|
||||
if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
|
||||
if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32)
|
||||
|| (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method))))
|
||||
flags |= ZIP_FL_FORCE_ZIP64;
|
||||
}
|
||||
else
|
||||
de->comp_size = st.comp_size;
|
||||
}
|
||||
|
||||
|
||||
offstart = ftello(ft);
|
||||
|
||||
if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
|
||||
/* as long as we don't support non-seekable output, clear data descriptor bit */
|
||||
de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
if ((is_zip64=_zip_dirent_write(de, ft, flags, &za->error)) < 0)
|
||||
return -1;
|
||||
|
||||
if ((s2=zip_source_crc(za, src, 0)) == NULL) {
|
||||
zip_source_pop(s2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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 (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->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->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
|
||||
if ((comp_impl=_zip_get_compression_implementation(de->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->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,18 +414,33 @@ add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
|
|||
return -1;
|
||||
}
|
||||
|
||||
de->last_mod = st.mtime;
|
||||
if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (st.valid & ZIP_STAT_MTIME)
|
||||
de->last_mod = st.mtime;
|
||||
else
|
||||
time(&de->last_mod);
|
||||
de->comp_method = st.comp_method;
|
||||
de->crc = st.crc;
|
||||
de->uncomp_size = st.size;
|
||||
de->comp_size = offend - offdata;
|
||||
de->comp_size = (zip_uint64_t)(offend - offdata);
|
||||
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
|
||||
_zip_dirent_torrent_normalize(de);
|
||||
|
||||
if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
|
||||
if ((ret=_zip_dirent_write(de, ft, flags, &za->error)) < 0)
|
||||
return -1;
|
||||
|
||||
|
||||
if (is_zip64 != ret) {
|
||||
/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
|
||||
_zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (fseeko(ft, offend, SEEK_SET) < 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
|
@ -441,24 +452,26 @@ add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
|
|||
|
||||
|
||||
static int
|
||||
copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
|
||||
copy_data(FILE *fs, zip_uint64_t len, FILE *ft, struct zip_error *error)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
int n, nn;
|
||||
size_t n, nn;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
while (len > 0) {
|
||||
nn = len > sizeof(buf) ? sizeof(buf) : len;
|
||||
if ((n=fread(buf, 1, nn, fs)) < 0) {
|
||||
_zip_error_set(error, ZIP_ER_READ, errno);
|
||||
return -1;
|
||||
}
|
||||
else if (n == 0) {
|
||||
_zip_error_set(error, ZIP_ER_EOF, 0);
|
||||
return -1;
|
||||
}
|
||||
if ((n=fread(buf, 1, nn, fs)) == 0) {
|
||||
if (ferror(fs)) {
|
||||
_zip_error_set(error, ZIP_ER_READ, errno);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
_zip_error_set(error, ZIP_ER_EOF, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fwrite(buf, 1, n, ft) != (size_t)n) {
|
||||
_zip_error_set(error, ZIP_ER_WRITE, errno);
|
||||
|
@ -487,7 +500,7 @@ copy_source(struct zip *za, struct zip_source *src, FILE *ft)
|
|||
|
||||
ret = 0;
|
||||
while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
|
||||
if (fwrite(buf, 1, n, ft) != (size_t)n) {
|
||||
if (fwrite(buf, 1, (size_t)n, ft) != (size_t)n) {
|
||||
_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
|
||||
ret = -1;
|
||||
break;
|
||||
|
@ -508,29 +521,32 @@ copy_source(struct zip *za, struct zip_source *src, FILE *ft)
|
|||
|
||||
|
||||
static int
|
||||
write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
|
||||
write_cdir(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *out)
|
||||
{
|
||||
off_t offset;
|
||||
off_t cd_start, end;
|
||||
zip_int64_t size;
|
||||
uLong crc;
|
||||
char buf[TORRENT_CRC_LEN+1];
|
||||
|
||||
if (_zip_cdir_write(cd, out, &za->error) < 0)
|
||||
cd_start = ftello(out);
|
||||
|
||||
if ((size=_zip_cdir_write(za, filelist, survivors, out)) < 0)
|
||||
return -1;
|
||||
|
||||
end = ftello(out);
|
||||
|
||||
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
/* fix up torrentzip comment */
|
||||
|
||||
offset = ftello(out);
|
||||
|
||||
if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0)
|
||||
if (_zip_filerange_crc(out, cd_start, size, &crc, &za->error) < 0)
|
||||
return -1;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%08lX", (long)crc);
|
||||
|
||||
if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) {
|
||||
if (fseeko(out, end-TORRENT_CRC_LEN, SEEK_SET) < 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
|
@ -545,47 +561,22 @@ write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
|
|||
|
||||
|
||||
|
||||
static int
|
||||
_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
|
||||
{
|
||||
if (src->ch_comment_len != -1) {
|
||||
dest->comment = _zip_memdup(src->ch_comment,
|
||||
src->ch_comment_len, &src->error);
|
||||
if (dest->comment == NULL)
|
||||
return -1;
|
||||
dest->comment_len = src->ch_comment_len;
|
||||
} else {
|
||||
if (src->cdir && src->cdir->comment) {
|
||||
dest->comment = _zip_memdup(src->cdir->comment,
|
||||
src->cdir->comment_len, &src->error);
|
||||
if (dest->comment == NULL)
|
||||
return -1;
|
||||
dest->comment_len = src->cdir->comment_len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_changed(struct zip *za, int *survivorsp)
|
||||
_zip_changed(const struct zip *za, zip_uint64_t *survivorsp)
|
||||
{
|
||||
int changed, i, survivors;
|
||||
int changed;
|
||||
zip_uint64_t i, survivors;
|
||||
|
||||
changed = survivors = 0;
|
||||
changed = 0;
|
||||
survivors = 0;
|
||||
|
||||
if (za->ch_comment_len != -1
|
||||
|| za->ch_flags != za->flags)
|
||||
if (za->comment_changed || za->ch_flags != za->flags)
|
||||
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].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0))
|
||||
changed = 1;
|
||||
if (za->entry[i].state != ZIP_ST_DELETED)
|
||||
if (!za->entry[i].deleted)
|
||||
survivors++;
|
||||
}
|
||||
|
||||
|
@ -603,14 +594,21 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
|
|||
char *temp;
|
||||
int tfd;
|
||||
FILE *tfp;
|
||||
int len = strlen(za->zn) + 8;
|
||||
|
||||
if ((temp=(char *)malloc(len)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
|
||||
if (za->tempdir) {
|
||||
if ((temp=(char *)malloc(strlen(za->tempdir)+13)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
sprintf(temp, "%s/.zip.XXXXXX", za->tempdir);
|
||||
}
|
||||
else {
|
||||
if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
sprintf(temp, "%s.XXXXXX", za->zn);
|
||||
}
|
||||
|
||||
snprintf(temp, len, "%s.XXXXXX", za->zn);
|
||||
|
||||
if ((tfd=mkstemp(temp)) == -1) {
|
||||
_zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
|
||||
|
@ -621,7 +619,7 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
|
|||
if ((tfp=fdopen(tfd, "r+b")) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
|
||||
close(tfd);
|
||||
remove(temp);
|
||||
(void)remove(temp);
|
||||
free(temp);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -630,7 +628,7 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
|
|||
According to Pierre Joye, Windows in some environments per
|
||||
default creates text files, so force binary mode.
|
||||
*/
|
||||
_setmode(_fileno(tfp), _O_BINARY );
|
||||
_setmode(_fileno(tfp), _O_BINARY );
|
||||
#endif
|
||||
|
||||
*outp = tfp;
|
||||
|
@ -642,6 +640,13 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
|
|||
static int
|
||||
_zip_torrentzip_cmp(const void *a, const void *b)
|
||||
{
|
||||
return strcasecmp(((const struct filelist *)a)->name,
|
||||
((const struct filelist *)b)->name);
|
||||
const char *aname = ((const struct zip_filelist *)a)->name;
|
||||
const char *bname = ((const struct zip_filelist *)b)->name;
|
||||
|
||||
if (aname == NULL)
|
||||
return (bname != NULL) * -1;
|
||||
else if (bname == NULL)
|
||||
return 1;
|
||||
|
||||
return strcasecmp(aname, bname);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_delete(struct zip *za, zip_uint64_t idx)
|
||||
{
|
||||
if (idx >= za->nentry) {
|
||||
|
@ -55,7 +55,7 @@ zip_delete(struct zip *za, zip_uint64_t idx)
|
|||
if (_zip_unchange(za, idx, 1) != 0)
|
||||
return -1;
|
||||
|
||||
za->entry[idx].state = ZIP_ST_DELETED;
|
||||
za->entry[idx].deleted = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_entry_new.c -- create and init struct zip_entry
|
||||
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
|
||||
zip_dir_add.c -- add directory
|
||||
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>
|
||||
|
@ -34,48 +34,55 @@
|
|||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
struct zip_entry *
|
||||
_zip_entry_new(struct zip *za)
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_dir_add(struct zip *za, const char *name, zip_flags_t flags)
|
||||
{
|
||||
struct zip_entry *ze;
|
||||
if (!za) {
|
||||
ze = (struct zip_entry *)malloc(sizeof(struct zip_entry));
|
||||
if (!ze) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (za->nentry+1 >= za->nentry_alloc) {
|
||||
struct zip_entry *rentries;
|
||||
za->nentry_alloc += 16;
|
||||
rentries = (struct zip_entry *)realloc(za->entry,
|
||||
sizeof(struct zip_entry)
|
||||
* za->nentry_alloc);
|
||||
if (!rentries) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
za->entry = rentries;
|
||||
}
|
||||
ze = za->entry+za->nentry;
|
||||
size_t len;
|
||||
zip_int64_t ret;
|
||||
char *s;
|
||||
struct zip_source *source;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ze->state = ZIP_ST_UNCHANGED;
|
||||
if (name == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
s = NULL;
|
||||
len = strlen(name);
|
||||
|
||||
if (za)
|
||||
za->nentry++;
|
||||
if (name[len-1] != '/') {
|
||||
if ((s=(char *)malloc(len+2)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
strcpy(s, name);
|
||||
s[len] = '/';
|
||||
s[len+1] = '\0';
|
||||
}
|
||||
|
||||
return ze;
|
||||
if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
|
||||
|
||||
free(s);
|
||||
if (ret < 0)
|
||||
zip_source_free(source);
|
||||
|
||||
return ret;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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,14 +39,14 @@
|
|||
|
||||
|
||||
|
||||
/* _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;
|
||||
zip_uint64_t i;
|
||||
|
||||
if (za == NULL)
|
||||
return;
|
||||
|
@ -58,13 +58,12 @@ _zip_free(struct zip *za)
|
|||
fclose(za->zp);
|
||||
|
||||
free(za->default_password);
|
||||
_zip_cdir_free(za->cdir);
|
||||
free(za->ch_comment);
|
||||
_zip_string_free(za->comment_orig);
|
||||
_zip_string_free(za->comment_changes);
|
||||
|
||||
if (za->entry) {
|
||||
for (i=0; i<za->nentry; i++) {
|
||||
_zip_entry_free(za->entry+i);
|
||||
}
|
||||
for (i=0; i<za->nentry; i++)
|
||||
_zip_entry_finalize(za->entry+i);
|
||||
free(za->entry);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_entry_free.c -- free struct zip_entry
|
||||
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
|
||||
zip_entry.c -- struct zip_entry helper functions
|
||||
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,23 +33,23 @@
|
|||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
void
|
||||
_zip_entry_finalize(struct zip_entry *e)
|
||||
{
|
||||
_zip_unchange_data(e);
|
||||
_zip_dirent_free(e->orig);
|
||||
_zip_dirent_free(e->changes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_entry_free(struct zip_entry *ze)
|
||||
_zip_entry_init(struct zip_entry *e)
|
||||
{
|
||||
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;
|
||||
|
||||
_zip_unchange_data(ze);
|
||||
e->orig = NULL;
|
||||
e->changes = NULL;
|
||||
e->source = NULL;
|
||||
e->deleted = 0;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_error.c -- struct zip_error helper functions
|
||||
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 1999-2013 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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -49,7 +52,7 @@ _zip_error_clear(struct zip_error *err)
|
|||
|
||||
|
||||
void
|
||||
_zip_error_copy(struct zip_error *dst, struct zip_error *src)
|
||||
_zip_error_copy(struct zip_error *dst, const struct zip_error *src)
|
||||
{
|
||||
dst->zip_err = src->zip_err;
|
||||
dst->sys_err = src->sys_err;
|
||||
|
@ -67,7 +70,7 @@ _zip_error_fini(struct zip_error *err)
|
|||
|
||||
|
||||
void
|
||||
_zip_error_get(struct zip_error *err, int *zep, int *sep)
|
||||
_zip_error_get(const struct zip_error *err, int *zep, int *sep)
|
||||
{
|
||||
if (zep)
|
||||
*zep = err->zip_err;
|
||||
|
|
|
@ -37,8 +37,11 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
ZIP_EXTERN void
|
||||
zip_error_clear(struct zip *za)
|
||||
{
|
||||
if (za == NULL)
|
||||
return;
|
||||
|
||||
_zip_error_clear(&za->error);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
ZIP_EXTERN void
|
||||
zip_error_get(struct zip *za, int *zep, int *sep)
|
||||
{
|
||||
_zip_error_get(&za->error, zep, sep);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_error_get_sys_type(int ze)
|
||||
{
|
||||
if (ze < 0 || ze >= _zip_nerr_str)
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
|
||||
{
|
||||
const char *zs, *ss;
|
||||
|
|
386
ext/zip/lib/zip_extra_field.c
Normal file
386
ext/zip/lib/zip_extra_field.c
Normal file
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
zip_extra_field.c -- manipulate extra fields
|
||||
Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
struct zip_extra_field *
|
||||
_zip_ef_clone(const struct zip_extra_field *ef, struct zip_error *error)
|
||||
{
|
||||
struct zip_extra_field *head, *prev, *def;
|
||||
|
||||
head = prev = NULL;
|
||||
|
||||
while (ef) {
|
||||
if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) {
|
||||
_zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
_zip_ef_free(head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (head == NULL)
|
||||
head = def;
|
||||
if (prev)
|
||||
prev->next = def;
|
||||
prev = def;
|
||||
|
||||
ef = ef->next;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
struct zip_extra_field *
|
||||
_zip_ef_delete_by_id(struct zip_extra_field *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags)
|
||||
{
|
||||
struct zip_extra_field *head, *prev;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
head = ef;
|
||||
prev = NULL;
|
||||
for (; ef; ef=(prev ? prev->next : head)) {
|
||||
if ((ef->flags & flags & ZIP_EF_BOTH) && ef->id == id) {
|
||||
if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) {
|
||||
ef->flags &= ~(flags & ZIP_EF_BOTH);
|
||||
if ((ef->flags & ZIP_EF_BOTH) == 0) {
|
||||
if (prev)
|
||||
prev->next = ef->next;
|
||||
else
|
||||
head = ef->next;
|
||||
ef->next = NULL;
|
||||
_zip_ef_free(ef);
|
||||
|
||||
if (id_idx == ZIP_EXTRA_FIELD_ALL)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i > id_idx)
|
||||
break;
|
||||
}
|
||||
prev = ef;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_ef_free(struct zip_extra_field *ef)
|
||||
{
|
||||
struct zip_extra_field *ef2;
|
||||
|
||||
while (ef) {
|
||||
ef2 = ef->next;
|
||||
free(ef->data);
|
||||
free(ef);
|
||||
ef = ef2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const zip_uint8_t *
|
||||
_zip_ef_get_by_id(const struct zip_extra_field *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, struct zip_error *error)
|
||||
{
|
||||
static const zip_uint8_t empty[1] = { '\0' };
|
||||
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) {
|
||||
if (i < id_idx) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lenp)
|
||||
*lenp = ef->size;
|
||||
if (ef->size > 0)
|
||||
return ef->data;
|
||||
else
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
_zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct zip_extra_field *
|
||||
_zip_ef_merge(struct zip_extra_field *to, struct zip_extra_field *from)
|
||||
{
|
||||
struct zip_extra_field *ef2, *tt, *tail;
|
||||
int duplicate;
|
||||
|
||||
if (to == NULL)
|
||||
return from;
|
||||
|
||||
for (tail=to; tail->next; tail=tail->next)
|
||||
;
|
||||
|
||||
for (; from; from=ef2) {
|
||||
ef2 = from->next;
|
||||
|
||||
duplicate = 0;
|
||||
for (tt=to; tt; tt=tt->next) {
|
||||
if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) {
|
||||
tt->flags |= (from->flags & ZIP_EF_BOTH);
|
||||
duplicate = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
from->next = NULL;
|
||||
if (duplicate)
|
||||
_zip_ef_free(from);
|
||||
else
|
||||
tail = tail->next = from;
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct zip_extra_field *
|
||||
_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags)
|
||||
{
|
||||
struct zip_extra_field *ef;
|
||||
|
||||
if ((ef=(struct zip_extra_field *)malloc(sizeof(*ef))) == NULL)
|
||||
return NULL;
|
||||
|
||||
ef->next = NULL;
|
||||
ef->flags = flags;
|
||||
ef->id = id;
|
||||
ef->size = size;
|
||||
if (size > 0) {
|
||||
if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) {
|
||||
free(ef);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
ef->data = NULL;
|
||||
|
||||
return ef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct zip_extra_field *
|
||||
_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, struct zip_error *error)
|
||||
{
|
||||
struct zip_extra_field *ef, *ef2, *ef_head;
|
||||
const zip_uint8_t *p;
|
||||
zip_uint16_t fid, flen;
|
||||
|
||||
ef_head = NULL;
|
||||
for (p=data; p<data+len; p+=flen) {
|
||||
if (p+4 > data+len) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_ef_free(ef_head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fid = _zip_read2(&p);
|
||||
flen = _zip_read2(&p);
|
||||
|
||||
if (p+flen > data+len) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_ef_free(ef_head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ef2=_zip_ef_new(fid, flen, p, flags)) == NULL) {
|
||||
_zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
_zip_ef_free(ef_head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ef_head) {
|
||||
ef->next = ef2;
|
||||
ef = ef2;
|
||||
}
|
||||
else
|
||||
ef_head = ef = ef2;
|
||||
}
|
||||
|
||||
return ef_head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct zip_extra_field *
|
||||
_zip_ef_remove_internal(struct zip_extra_field *ef)
|
||||
{
|
||||
struct zip_extra_field *ef_head;
|
||||
struct zip_extra_field *prev, *next;
|
||||
|
||||
ef_head = ef;
|
||||
prev = NULL;
|
||||
|
||||
while (ef) {
|
||||
if (ZIP_EF_IS_INTERNAL(ef->id)) {
|
||||
next = ef->next;
|
||||
if (ef_head == ef)
|
||||
ef_head = next;
|
||||
ef->next = NULL;
|
||||
_zip_ef_free(ef);
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
ef = next;
|
||||
}
|
||||
else {
|
||||
prev = ef;
|
||||
ef = ef->next;
|
||||
}
|
||||
}
|
||||
|
||||
return ef_head;
|
||||
}
|
||||
|
||||
|
||||
zip_uint16_t
|
||||
_zip_ef_size(const struct zip_extra_field *ef, zip_flags_t flags)
|
||||
{
|
||||
zip_uint16_t size;
|
||||
|
||||
size = 0;
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->flags & flags & ZIP_EF_BOTH)
|
||||
size += 4+ef->size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_ef_write(const struct zip_extra_field *ef, zip_flags_t flags, FILE *f)
|
||||
{
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->flags & flags & ZIP_EF_BOTH) {
|
||||
_zip_write2(ef->id, f);
|
||||
_zip_write2(ef->size, f);
|
||||
if (ef->size > 0)
|
||||
fwrite(ef->data, ef->size, 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_read_local_ef(struct zip *za, zip_uint64_t idx)
|
||||
{
|
||||
struct zip_entry *e;
|
||||
unsigned char b[4];
|
||||
const unsigned char *p;
|
||||
zip_uint16_t fname_len, ef_len;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->orig == NULL || e->orig->local_extra_fields_read)
|
||||
return 0;
|
||||
|
||||
|
||||
if (fseeko(za->zp, (off_t)(e->orig->offset + 26), SEEK_SET) < 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(b, sizeof(b), 1, za->zp) != 1) {
|
||||
_zip_error_set(&za->error, ZIP_ER_READ, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = b;
|
||||
fname_len = _zip_read2(&p);
|
||||
ef_len = _zip_read2(&p);
|
||||
|
||||
if (ef_len > 0) {
|
||||
struct zip_extra_field *ef;
|
||||
zip_uint8_t *ef_raw;
|
||||
|
||||
if (fseek(za->zp, fname_len, SEEK_CUR) < 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ef_raw = _zip_read_data(NULL, za->zp, ef_len, 0, &za->error);
|
||||
|
||||
if (ef_raw == NULL)
|
||||
return -1;
|
||||
|
||||
if ((ef=_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &za->error)) == NULL) {
|
||||
free(ef_raw);
|
||||
return -1;
|
||||
}
|
||||
free(ef_raw);
|
||||
|
||||
ef = _zip_ef_remove_internal(ef);
|
||||
e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
|
||||
}
|
||||
|
||||
e->orig->local_extra_fields_read = 1;
|
||||
|
||||
if (e->changes && e->changes->local_extra_fields_read == 0) {
|
||||
e->changes->extra_fields = e->orig->extra_fields;
|
||||
e->changes->local_extra_fields_read = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
364
ext/zip/lib/zip_extra_field_api.c
Normal file
364
ext/zip/lib/zip_extra_field_api.c
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
zip_extra_field_api.c -- public extra fields API functions
|
||||
Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_extra_field_delete(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags)
|
||||
{
|
||||
struct zip_dirent *de;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
de = za->entry[idx].changes;
|
||||
|
||||
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_extra_field_delete_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags)
|
||||
{
|
||||
struct zip_dirent *de;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
de = za->entry[idx].changes;
|
||||
|
||||
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN const zip_uint8_t *
|
||||
zip_file_extra_field_get(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags)
|
||||
{
|
||||
static const zip_uint8_t empty[1] = { '\0' };
|
||||
|
||||
struct zip_dirent *de;
|
||||
struct zip_extra_field *ef;
|
||||
int i;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
for (ef=de->extra_fields; ef; ef=ef->next) {
|
||||
if (ef->flags & flags & ZIP_EF_BOTH) {
|
||||
if (i < ef_idx) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (idp)
|
||||
*idp = ef->id;
|
||||
if (lenp)
|
||||
*lenp = ef->size;
|
||||
if (ef->size > 0)
|
||||
return ef->data;
|
||||
else
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
_zip_error_set(&za->error, ZIP_ER_NOENT, 0);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN const zip_uint8_t *
|
||||
zip_file_extra_field_get_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags)
|
||||
{
|
||||
struct zip_dirent *de;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return NULL;
|
||||
|
||||
return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int16_t
|
||||
zip_file_extra_fields_count(struct zip *za, zip_uint64_t idx, zip_flags_t flags)
|
||||
{
|
||||
struct zip_dirent *de;
|
||||
struct zip_extra_field *ef;
|
||||
zip_uint16_t n;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
for (ef=de->extra_fields; ef; ef=ef->next)
|
||||
if (ef->flags & flags & ZIP_EF_BOTH)
|
||||
n++;
|
||||
|
||||
return (zip_int16_t)n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int16_t
|
||||
zip_file_extra_fields_count_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags)
|
||||
{
|
||||
struct zip_dirent *de;
|
||||
struct zip_extra_field *ef;
|
||||
zip_uint16_t n;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
for (ef=de->extra_fields; ef; ef=ef->next)
|
||||
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
|
||||
n++;
|
||||
|
||||
return (zip_int16_t)n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_extra_field_set(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags)
|
||||
{
|
||||
struct zip_dirent *de;
|
||||
zip_uint16_t ls, cs;
|
||||
struct zip_extra_field *ef, *ef_prev, *ef_new;
|
||||
int i, found, new_len;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_EF_IS_INTERNAL(ef_id)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
de = za->entry[idx].changes;
|
||||
|
||||
ef = de->extra_fields;
|
||||
ef_prev = NULL;
|
||||
i = 0;
|
||||
found = 0;
|
||||
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
|
||||
if (i == ef_idx) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ef_prev = ef;
|
||||
}
|
||||
|
||||
if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ZIP_EF_LOCAL)
|
||||
ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
|
||||
else
|
||||
ls = 0;
|
||||
if (flags & ZIP_EF_CENTRAL)
|
||||
cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
|
||||
else
|
||||
cs = 0;
|
||||
|
||||
new_len = ls > cs ? ls : cs;
|
||||
if (found)
|
||||
new_len -= ef->size + 4;
|
||||
new_len += len + 4;
|
||||
|
||||
if (new_len > ZIP_UINT16_MAX) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
|
||||
ef_new->next = ef->next;
|
||||
ef->next = NULL;
|
||||
_zip_ef_free(ef);
|
||||
if (ef_prev)
|
||||
ef_prev->next = ef_new;
|
||||
else
|
||||
de->extra_fields = ef_new;
|
||||
}
|
||||
else {
|
||||
ef->flags &= ~(flags & ZIP_EF_BOTH);
|
||||
ef_new->next = ef->next;
|
||||
ef->next = ef_new;
|
||||
}
|
||||
}
|
||||
else if (ef_prev) {
|
||||
ef_new->next = ef_prev->next;
|
||||
ef_prev->next = ef_new;
|
||||
}
|
||||
else
|
||||
de->extra_fields = ef_new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_file_extra_field_prepare_for_change(struct zip *za, zip_uint64_t idx)
|
||||
{
|
||||
struct zip_entry *e;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
|
||||
return 0;
|
||||
|
||||
if (e->orig) {
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (e->orig && e->orig->extra_fields) {
|
||||
if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -39,20 +39,23 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_fclose(struct zip_file *zf)
|
||||
{
|
||||
int i, ret;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
if (zf->src)
|
||||
zip_source_free(zf->src);
|
||||
|
||||
for (i=0; i<zf->za->nfile; i++) {
|
||||
if (zf->za->file[i] == zf) {
|
||||
zf->za->file[i] = zf->za->file[zf->za->nfile-1];
|
||||
zf->za->nfile--;
|
||||
break;
|
||||
}
|
||||
if (zf->za) {
|
||||
for (i=0; i<zf->za->nfile; i++) {
|
||||
if (zf->za->file[i] == zf) {
|
||||
zf->za->file[i] = zf->za->file[zf->za->nfile-1];
|
||||
zf->za->nfile--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
|
|
@ -37,11 +37,24 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip *)
|
||||
zip_fdopen(int fd_orig, int flags, int *zep)
|
||||
ZIP_EXTERN struct zip *
|
||||
zip_fdopen(int fd_orig, int _flags, int *zep)
|
||||
{
|
||||
int fd;
|
||||
FILE *fp;
|
||||
unsigned int flags;
|
||||
|
||||
if (_flags < 0) {
|
||||
if (zep)
|
||||
*zep = ZIP_ER_INVAL;
|
||||
return NULL;
|
||||
}
|
||||
flags = (unsigned int)_flags;
|
||||
|
||||
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. */
|
||||
|
@ -58,5 +71,5 @@ zip_fdopen(int fd_orig, int flags, int *zep)
|
|||
}
|
||||
|
||||
close(fd_orig);
|
||||
return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep);
|
||||
return _zip_open(NULL, fp, flags, zep);
|
||||
}
|
||||
|
|
55
ext/zip/lib/zip_file_add.c
Normal file
55
ext/zip/lib/zip_file_add.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
zip_file_add.c -- add file via callback function
|
||||
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>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/*
|
||||
NOTE: Return type is signed so we can return -1 on error.
|
||||
The index can not be larger than ZIP_INT64_MAX since the size
|
||||
of the central directory cannot be larger than
|
||||
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
|
||||
*/
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_file_add(struct zip *za, const char *name, struct zip_source *source, zip_flags_t flags)
|
||||
{
|
||||
if (name == NULL || source == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags);
|
||||
}
|
|
@ -37,8 +37,11 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
ZIP_EXTERN void
|
||||
zip_file_error_clear(struct zip_file *zf)
|
||||
{
|
||||
if (zf == NULL)
|
||||
return;
|
||||
|
||||
_zip_error_clear(&zf->error);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
ZIP_EXTERN void
|
||||
zip_file_error_get(struct zip_file *zf, int *zep, int *sep)
|
||||
{
|
||||
_zip_error_get(&zf->error, zep, sep);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_get_file_extra.c -- get file extra field
|
||||
Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner
|
||||
zip_file_get_comment.c -- get file comment
|
||||
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>
|
||||
|
@ -17,7 +17,7 @@
|
|||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
|
@ -31,28 +31,28 @@
|
|||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */
|
||||
|
||||
|
||||
ZIP_EXTERN(const char *)
|
||||
zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
|
||||
ZIP_EXTERN const char *
|
||||
zip_file_get_comment(struct zip *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags)
|
||||
{
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
struct zip_dirent *de;
|
||||
zip_uint32_t len;
|
||||
const zip_uint8_t *str;
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED)
|
||||
|| (za->entry[idx].ch_extra_len == -1)) {
|
||||
if (lenp != NULL)
|
||||
*lenp = za->cdir->entry[idx].extrafield_len;
|
||||
return za->cdir->entry[idx].extrafield;
|
||||
}
|
||||
if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (lenp != NULL)
|
||||
*lenp = za->entry[idx].ch_extra_len;
|
||||
return za->entry[idx].ch_extra;
|
||||
if (lenp)
|
||||
*lenp = len;
|
||||
|
||||
return (const char *)str;
|
||||
}
|
|
@ -50,25 +50,27 @@
|
|||
On error, fills in za->error and returns 0.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
_zip_file_get_offset(struct zip *za, int idx)
|
||||
zip_uint64_t
|
||||
_zip_file_get_offset(const struct zip *za, zip_uint64_t idx, struct zip_error *error)
|
||||
{
|
||||
struct zip_dirent de;
|
||||
unsigned int offset;
|
||||
zip_uint64_t offset;
|
||||
zip_int32_t size;
|
||||
|
||||
offset = za->cdir->entry[idx].offset;
|
||||
offset = za->entry[idx].orig->offset;
|
||||
|
||||
if (fseeko(za->zp, offset, SEEK_SET) != 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
if (fseeko(za->zp, (off_t)offset, SEEK_SET) != 0) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, &za->error) != 0)
|
||||
/* XXX: cache? */
|
||||
if ((size=_zip_dirent_size(za->zp, ZIP_EF_LOCAL, error)) < 0)
|
||||
return 0;
|
||||
|
||||
offset += LENTRYSIZE + de.filename_len + de.extrafield_len;
|
||||
|
||||
_zip_dirent_finalize(&de);
|
||||
|
||||
return offset;
|
||||
if (offset+(zip_uint32_t)size > ZIP_OFF_MAX) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return offset + (zip_uint32_t)size;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_set_file_extra.c -- set extra field for file in archive
|
||||
Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner
|
||||
zip_file_rename.c -- rename file in zip archive
|
||||
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>
|
||||
|
@ -17,7 +17,7 @@
|
|||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
|
@ -31,23 +31,21 @@
|
|||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_set_file_extra(struct zip *za, zip_uint64_t idx,
|
||||
const char *extra, int len)
|
||||
ZIP_EXTERN int
|
||||
zip_file_rename(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
|
||||
{
|
||||
char *tmpext;
|
||||
|
||||
if (idx >= za->nentry
|
||||
|| len < 0 || len > MAXEXTLEN
|
||||
|| (len > 0 && extra == NULL)) {
|
||||
const char *old_name;
|
||||
int old_is_dir, new_is_dir;
|
||||
|
||||
if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
@ -57,16 +55,16 @@ zip_set_file_extra(struct zip *za, zip_uint64_t idx,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL)
|
||||
return -1;
|
||||
if ((old_name=zip_get_name(za, idx, 0)) == NULL)
|
||||
return -1;
|
||||
|
||||
new_is_dir = (name != NULL && name[strlen(name)-1] == '/');
|
||||
old_is_dir = (old_name[strlen(old_name)-1] == '/');
|
||||
|
||||
if (new_is_dir != old_is_dir) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
tmpext = NULL;
|
||||
|
||||
free(za->entry[idx].ch_extra);
|
||||
za->entry[idx].ch_extra = tmpext;
|
||||
za->entry[idx].ch_extra_len = len;
|
||||
|
||||
return 0;
|
||||
return _zip_set_name(za, idx, name, flags);
|
||||
}
|
111
ext/zip/lib/zip_file_replace.c
Normal file
111
ext/zip/lib/zip_file_replace.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
zip_file_replace.c -- replace file via callback function
|
||||
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>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source, zip_flags_t flags)
|
||||
{
|
||||
if (idx >= za->nentry || source == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_replace(za, idx, NULL, source, flags) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
zip_int64_t
|
||||
_zip_file_replace(struct zip *za, zip_uint64_t idx, const char *name, struct zip_source *source, zip_flags_t flags)
|
||||
{
|
||||
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) {
|
||||
zip_int64_t i = -1;
|
||||
|
||||
if (flags & ZIP_FL_OVERWRITE)
|
||||
i = _zip_name_locate(za, name, flags, NULL);
|
||||
|
||||
if (i == -1) {
|
||||
/* create and use new entry, used by zip_add */
|
||||
if ((i=_zip_add_entry(za)) < 0)
|
||||
return -1;
|
||||
}
|
||||
idx = (zip_uint64_t)i;
|
||||
}
|
||||
|
||||
if (name && _zip_set_name(za, idx, name, flags) != 0) {
|
||||
if (za->nentry != za_nentry_prev) {
|
||||
_zip_entry_finalize(za->entry+idx);
|
||||
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 (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) {
|
||||
if (za->entry[idx].changes == NULL) {
|
||||
if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT;
|
||||
za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD;
|
||||
}
|
||||
|
||||
za->entry[idx].source = source;
|
||||
|
||||
return (zip_int64_t)idx;
|
||||
}
|
105
ext/zip/lib/zip_file_set_comment.c
Normal file
105
ext/zip/lib/zip_file_set_comment.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
zip_file_set_comment.c -- set comment for file in archive
|
||||
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>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_set_comment(struct zip *za, zip_uint64_t idx,
|
||||
const char *comment, zip_uint16_t len, zip_flags_t flags)
|
||||
{
|
||||
struct zip_entry *e;
|
||||
struct zip_string *cstr;
|
||||
int changed;
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0 && comment == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
|
||||
cstr->encoding = ZIP_ENCODING_UTF8_KNOWN;
|
||||
}
|
||||
else
|
||||
cstr = NULL;
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->changes) {
|
||||
_zip_string_free(e->changes->comment);
|
||||
e->changes->comment = NULL;
|
||||
e->changes->changed &= ~ZIP_DIRENT_COMMENT;
|
||||
}
|
||||
|
||||
if (e->orig && e->orig->comment)
|
||||
changed = !_zip_string_equal(e->orig->comment, cstr);
|
||||
else
|
||||
changed = (cstr != NULL);
|
||||
|
||||
if (changed) {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
_zip_string_free(cstr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
e->changes->comment = cstr;
|
||||
e->changes->changed |= ZIP_DIRENT_COMMENT;
|
||||
}
|
||||
else {
|
||||
_zip_string_free(cstr);
|
||||
if (e->changes && e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(const char *)
|
||||
ZIP_EXTERN const char *
|
||||
zip_file_strerror(struct zip_file *zf)
|
||||
{
|
||||
return _zip_error_strerror(&zf->error);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_filerange_crc.c -- compute CRC32 for a range of a file
|
||||
Copyright (C) 2008 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 2008-2013 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>
|
||||
|
@ -56,13 +56,13 @@ _zip_filerange_crc(FILE *fp, off_t start, off_t len, uLong *crcp,
|
|||
}
|
||||
|
||||
while (len > 0) {
|
||||
n = len > BUFSIZE ? BUFSIZE : len;
|
||||
if ((n=fread(buf, 1, n, fp)) <= 0) {
|
||||
n = len > BUFSIZE ? BUFSIZE : (size_t)len;
|
||||
if ((n=fread(buf, 1, n, fp)) == 0) {
|
||||
_zip_error_set(errp, ZIP_ER_READ, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*crcp = crc32(*crcp, buf, n);
|
||||
*crcp = crc32(*crcp, buf, (uInt)n);
|
||||
|
||||
len-= n;
|
||||
}
|
||||
|
|
|
@ -37,13 +37,13 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_file *)
|
||||
zip_fopen(struct zip *za, const char *fname, int flags)
|
||||
ZIP_EXTERN struct zip_file *
|
||||
zip_fopen(struct zip *za, const char *fname, zip_flags_t flags)
|
||||
{
|
||||
int idx;
|
||||
zip_int64_t idx;
|
||||
|
||||
if ((idx=zip_name_locate(za, fname, flags)) < 0)
|
||||
return NULL;
|
||||
|
||||
return zip_fopen_index_encrypted(za, idx, flags, za->default_password);
|
||||
return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password);
|
||||
}
|
||||
|
|
|
@ -37,14 +37,13 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_file *)
|
||||
zip_fopen_encrypted(struct zip *za, const char *fname, int flags,
|
||||
const char *password)
|
||||
ZIP_EXTERN struct zip_file *
|
||||
zip_fopen_encrypted(struct zip *za, const char *fname, zip_flags_t flags, const char *password)
|
||||
{
|
||||
int idx;
|
||||
zip_int64_t idx;
|
||||
|
||||
if ((idx=zip_name_locate(za, fname, flags)) < 0)
|
||||
return NULL;
|
||||
|
||||
return zip_fopen_index_encrypted(za, idx, flags, password);
|
||||
return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_fopen_index.c -- open file in zip archive for reading by index
|
||||
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 1999-2013 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>
|
||||
|
@ -41,8 +41,8 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_file *)
|
||||
zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags)
|
||||
ZIP_EXTERN struct zip_file *
|
||||
zip_fopen_index(struct zip *za, zip_uint64_t index, zip_flags_t flags)
|
||||
{
|
||||
return zip_fopen_index_encrypted(za, fileno, flags, za->default_password);
|
||||
return zip_fopen_index_encrypted(za, index, flags, za->default_password);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
|
||||
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 1999-2013 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,103 +43,15 @@ static struct zip_file *_zip_file_new(struct zip *za);
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_file *)
|
||||
zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags,
|
||||
ZIP_EXTERN struct zip_file *
|
||||
zip_fopen_index_encrypted(struct zip *za, zip_uint64_t index, zip_flags_t flags,
|
||||
const char *password)
|
||||
{
|
||||
struct zip_file *zf;
|
||||
zip_compression_implementation comp_impl;
|
||||
zip_encryption_implementation enc_impl;
|
||||
struct zip_source *src, *s2;
|
||||
zip_uint64_t start;
|
||||
struct zip_stat st;
|
||||
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, index, 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 @@ zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
zf = _zip_file_new(za);
|
||||
if ((zf=_zip_file_new(za)) == NULL) {
|
||||
zip_source_free(src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zf->src = src;
|
||||
|
||||
|
@ -160,14 +75,14 @@ static struct zip_file *
|
|||
_zip_file_new(struct zip *za)
|
||||
{
|
||||
struct zip_file *zf, **file;
|
||||
int n;
|
||||
|
||||
if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (za->nfile >= za->nfile_alloc-1) {
|
||||
if (za->nfile+1 >= za->nfile_alloc) {
|
||||
unsigned int n;
|
||||
n = za->nfile_alloc + 10;
|
||||
file = (struct zip_file **)realloc(za->file,
|
||||
n*sizeof(struct zip_file *));
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(zip_int64_t)
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread)
|
||||
{
|
||||
zip_int64_t n;
|
||||
|
|
|
@ -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,28 +33,29 @@
|
|||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(const char *)
|
||||
zip_get_archive_comment(struct zip *za, int *lenp, int flags)
|
||||
ZIP_EXTERN const char *
|
||||
zip_get_archive_comment(struct zip *za, int *lenp, zip_flags_t flags)
|
||||
{
|
||||
if ((flags & ZIP_FL_UNCHANGED)
|
||||
|| (za->ch_comment_len == -1)) {
|
||||
if (za->cdir) {
|
||||
if (lenp != NULL)
|
||||
*lenp = za->cdir->comment_len;
|
||||
return za->cdir->comment;
|
||||
}
|
||||
else {
|
||||
if (lenp != NULL)
|
||||
*lenp = -1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (lenp != NULL)
|
||||
*lenp = za->ch_comment_len;
|
||||
return za->ch_comment;
|
||||
struct zip_string *comment;
|
||||
zip_uint32_t len;
|
||||
const zip_uint8_t *str;
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL))
|
||||
comment = za->comment_orig;
|
||||
else
|
||||
comment = za->comment_changes;
|
||||
|
||||
if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (lenp)
|
||||
*lenp = (int)len;
|
||||
|
||||
return (const char *)str;
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_get_archive_flag(struct zip *za, int flag, int flags)
|
||||
ZIP_EXTERN int
|
||||
zip_get_archive_flag(struct zip *za, unsigned int flag, zip_flags_t flags)
|
||||
{
|
||||
int fl;
|
||||
unsigned int fl;
|
||||
|
||||
fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags;
|
||||
|
||||
|
|
|
@ -37,10 +37,10 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(zip_compression_implementation)
|
||||
zip_get_compression_implementation(zip_uint16_t cm)
|
||||
zip_compression_implementation
|
||||
_zip_get_compression_implementation(zip_int32_t cm)
|
||||
{
|
||||
if (cm == ZIP_CM_DEFLATE)
|
||||
if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm))
|
||||
return zip_source_deflate;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(zip_encryption_implementation)
|
||||
zip_get_encryption_implementation(zip_uint16_t em)
|
||||
zip_encryption_implementation
|
||||
_zip_get_encryption_implementation(zip_uint16_t em)
|
||||
{
|
||||
if (em == ZIP_EM_TRAD_PKWARE)
|
||||
return zip_source_pkware;
|
||||
|
|
|
@ -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,26 +33,21 @@
|
|||
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(const char *)
|
||||
ZIP_EXTERN const char *
|
||||
zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
|
||||
{
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
zip_uint32_t len;
|
||||
const char *s;
|
||||
|
||||
if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) {
|
||||
if (lenp)
|
||||
*lenp = (int)len;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED)
|
||||
|| (za->entry[idx].ch_comment_len == -1)) {
|
||||
if (lenp != NULL)
|
||||
*lenp = za->cdir->entry[idx].comment_len;
|
||||
return za->cdir->entry[idx].comment;
|
||||
}
|
||||
|
||||
if (lenp != NULL)
|
||||
*lenp = za->entry[idx].ch_comment_len;
|
||||
return za->entry[idx].ch_comment;
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -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,12 +33,14 @@
|
|||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(const char *)
|
||||
zip_get_name(struct zip *za, zip_uint64_t idx, int flags)
|
||||
ZIP_EXTERN const char *
|
||||
zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags)
|
||||
{
|
||||
return _zip_get_name(za, idx, flags, &za->error);
|
||||
}
|
||||
|
@ -46,27 +48,16 @@ zip_get_name(struct zip *za, zip_uint64_t idx, int flags)
|
|||
|
||||
|
||||
const char *
|
||||
_zip_get_name(struct zip *za, zip_uint64_t idx, int flags,
|
||||
struct zip_error *error)
|
||||
_zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error)
|
||||
{
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
struct zip_dirent *de;
|
||||
const zip_uint8_t *str;
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED) == 0) {
|
||||
if (za->entry[idx].state == ZIP_ST_DELETED) {
|
||||
_zip_error_set(error, ZIP_ER_DELETED, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (za->entry[idx].ch_filename)
|
||||
return za->entry[idx].ch_filename;
|
||||
}
|
||||
|
||||
if (za->cdir == NULL || idx >= za->cdir->nentry) {
|
||||
_zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return za->cdir->entry[idx].filename;
|
||||
|
||||
if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return (const char *)str;
|
||||
}
|
||||
|
|
|
@ -37,16 +37,19 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(zip_uint64_t)
|
||||
zip_get_num_entries(struct zip *za, int flags)
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_get_num_entries(struct zip *za, zip_flags_t flags)
|
||||
{
|
||||
zip_uint64_t n;
|
||||
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
if (flags & ZIP_FL_UNCHANGED) {
|
||||
if (za->cdir == NULL)
|
||||
return 0;
|
||||
return za->cdir->nentry;
|
||||
n = za->nentry;
|
||||
while (n>0 && za->entry[n-1].orig == NULL)
|
||||
--n;
|
||||
return (zip_int64_t)n;
|
||||
}
|
||||
return za->nentry;
|
||||
return (zip_int64_t)za->nentry;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,17 @@
|
|||
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_get_num_files(struct zip *za)
|
||||
{
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
return za->nentry;
|
||||
/* XXX: check for overflow */
|
||||
return (int)za->nentry;
|
||||
}
|
||||
|
|
|
@ -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 @@ _zip_memdup(const void *mem, size_t len, struct zip_error *error)
|
|||
{
|
||||
void *ret;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
ret = malloc(len);
|
||||
if (!ret) {
|
||||
_zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
|
|
|
@ -34,26 +34,28 @@
|
|||
|
||||
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_name_locate(struct zip *za, const char *fname, int flags)
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags)
|
||||
{
|
||||
return _zip_name_locate(za, fname, flags, &za->error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_name_locate(struct zip *za, const char *fname, int flags,
|
||||
struct zip_error *error)
|
||||
zip_int64_t
|
||||
_zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags, struct zip_error *error)
|
||||
{
|
||||
int (*cmp)(const char *, const char *);
|
||||
const char *fn, *p;
|
||||
int i, n;
|
||||
zip_uint64_t i;
|
||||
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
@ -63,21 +65,12 @@ _zip_name_locate(struct zip *za, const char *fname, int flags,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED) && za->cdir == NULL) {
|
||||
_zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return -1;
|
||||
}
|
||||
cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
|
||||
|
||||
cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : strcmp;
|
||||
for (i=0; i<za->nentry; i++) {
|
||||
fn = _zip_get_name(za, i, flags, error);
|
||||
|
||||
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);
|
||||
|
||||
/* newly added (partially filled) entry */
|
||||
/* newly added (partially filled) entry or error */
|
||||
if (fn == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -87,11 +80,12 @@ _zip_name_locate(struct zip *za, const char *fname, int flags,
|
|||
fn = p+1;
|
||||
}
|
||||
|
||||
if (cmp(fname, fn) == 0)
|
||||
return i;
|
||||
if (cmp(fname, fn) == 0) {
|
||||
_zip_error_clear(error);
|
||||
return (zip_int64_t)i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for an entry should not raise an error */
|
||||
/* _zip_error_set(error, ZIP_ER_NOENT, 0);*/
|
||||
_zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_new.c -- create and init struct zip
|
||||
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>
|
||||
|
@ -56,16 +56,17 @@ _zip_new(struct zip_error *error)
|
|||
|
||||
za->zn = NULL;
|
||||
za->zp = NULL;
|
||||
za->open_flags = 0;
|
||||
_zip_error_init(&za->error);
|
||||
za->cdir = NULL;
|
||||
za->ch_comment = NULL;
|
||||
za->ch_comment_len = -1;
|
||||
za->flags = za->ch_flags = 0;
|
||||
za->default_password = NULL;
|
||||
za->comment_orig = za->comment_changes = NULL;
|
||||
za->comment_changed = 0;
|
||||
za->nentry = za->nentry_alloc = 0;
|
||||
za->entry = NULL;
|
||||
za->nfile = za->nfile_alloc = 0;
|
||||
za->file = NULL;
|
||||
za->flags = za->ch_flags = 0;
|
||||
za->default_password = NULL;
|
||||
za->tempdir = NULL;
|
||||
|
||||
return za;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
@ -42,38 +42,53 @@
|
|||
|
||||
#include "zipint.h"
|
||||
|
||||
static void set_error(int *, struct zip_error *, int);
|
||||
static struct zip *_zip_allocate_new(const char *, 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);
|
||||
static int _zip_file_exists(const char *, int, int *);
|
||||
static int _zip_headercomp(struct zip_dirent *, int,
|
||||
struct zip_dirent *, int);
|
||||
static unsigned char *_zip_memmem(const unsigned char *, int,
|
||||
const unsigned char *, int);
|
||||
static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, unsigned char *,
|
||||
int, int, struct zip_error *);
|
||||
static void set_error(int *, const struct zip_error *, int);
|
||||
static struct zip *_zip_allocate_new(const char *, unsigned int, int *);
|
||||
static zip_int64_t _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *);
|
||||
static void _zip_check_torrentzip(struct zip *, const struct zip_cdir *);
|
||||
static struct zip_cdir *_zip_find_central_dir(FILE *, unsigned int, int *, off_t);
|
||||
static int _zip_file_exists(const char *, unsigned int, int *);
|
||||
static int _zip_headercomp(const struct zip_dirent *, const struct zip_dirent *);
|
||||
static unsigned char *_zip_memmem(const unsigned char *, size_t,
|
||||
const unsigned char *, size_t);
|
||||
static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, const unsigned char *,
|
||||
size_t, unsigned int, struct zip_error *);
|
||||
static struct zip_cdir *_zip_read_eocd(const unsigned char *, const unsigned char *, off_t,
|
||||
size_t, unsigned int, struct zip_error *);
|
||||
static struct zip_cdir *_zip_read_eocd64(FILE *, const unsigned char *, const unsigned char *,
|
||||
off_t, size_t, unsigned int, struct zip_error *);
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip *)
|
||||
zip_open(const char *fn, int flags, int *zep)
|
||||
ZIP_EXTERN struct zip *
|
||||
zip_open(const char *fn, int _flags, int *zep)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if (flags & ZIP_OVERWRITE) {
|
||||
return _zip_allocate_new(fn, zep);
|
||||
unsigned int flags;
|
||||
|
||||
if (_flags < 0) {
|
||||
if (zep)
|
||||
*zep = ZIP_ER_INVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flags = (unsigned int)_flags;
|
||||
|
||||
switch (_zip_file_exists(fn, flags, zep)) {
|
||||
case -1:
|
||||
if (!(flags & ZIP_OVERWRITE)) {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
case 0:
|
||||
return _zip_allocate_new(fn, zep);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -82,17 +97,36 @@ zip_open(const char *fn, int flags, int *zep)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return _zip_open(fn, fp, flags, 0, zep);
|
||||
return _zip_open(fn, fp, flags, zep);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_archive_set_tempdir(struct zip *za, const char *tempdir)
|
||||
{
|
||||
char *new_tempdir;
|
||||
|
||||
if (tempdir) {
|
||||
if ((new_tempdir = strdup(tempdir)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
new_tempdir = NULL;
|
||||
|
||||
free(za->tempdir);
|
||||
za->tempdir = new_tempdir;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct zip *
|
||||
_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
|
||||
_zip_open(const char *fn, FILE *fp, unsigned int flags, int *zep)
|
||||
{
|
||||
struct zip *za;
|
||||
struct zip_cdir *cdir;
|
||||
int i;
|
||||
off_t len;
|
||||
|
||||
if (fseeko(fp, 0, SEEK_END) < 0) {
|
||||
|
@ -103,7 +137,7 @@ _zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
|
|||
|
||||
/* 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;
|
||||
|
@ -116,34 +150,32 @@ _zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
|
|||
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;
|
||||
}
|
||||
|
||||
za->cdir = cdir;
|
||||
za->entry = cdir->entry;
|
||||
za->nentry = cdir->nentry;
|
||||
za->nentry_alloc = cdir->nentry_alloc;
|
||||
za->comment_orig = cdir->comment;
|
||||
|
||||
za->zp = fp;
|
||||
|
||||
if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry))
|
||||
* cdir->nentry)) == NULL) {
|
||||
set_error(zep, NULL, ZIP_ER_MEMORY);
|
||||
_zip_free(za);
|
||||
return NULL;
|
||||
}
|
||||
for (i=0; i<cdir->nentry; i++)
|
||||
_zip_entry_new(za);
|
||||
_zip_check_torrentzip(za, cdir);
|
||||
|
||||
_zip_check_torrentzip(za);
|
||||
za->ch_flags = za->flags;
|
||||
|
||||
free(cdir);
|
||||
|
||||
return za;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
set_error(int *zep, struct zip_error *err, int ze)
|
||||
set_error(int *zep, const struct zip_error *err, int ze)
|
||||
{
|
||||
int se;
|
||||
|
||||
|
@ -166,16 +198,17 @@ set_error(int *zep, struct zip_error *err, int ze)
|
|||
entries, or NULL if unsuccessful. */
|
||||
|
||||
static struct zip_cdir *
|
||||
_zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eocd, int buflen,
|
||||
int flags, struct zip_error *error)
|
||||
_zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, const unsigned char *eocd, size_t buflen,
|
||||
unsigned int flags, struct zip_error *error)
|
||||
{
|
||||
struct zip_cdir *cd;
|
||||
unsigned char *cdp, **bufp;
|
||||
int i, comlen, nentry;
|
||||
zip_uint32_t left;
|
||||
const unsigned char *cdp;
|
||||
const unsigned char **bufp;
|
||||
zip_int64_t tail_len, comment_len;
|
||||
zip_uint64_t i, left;
|
||||
|
||||
comlen = buf + buflen - eocd - EOCDLEN;
|
||||
if (comlen < 0) {
|
||||
tail_len = buf + buflen - eocd - EOCDLEN;
|
||||
if (tail_len < 0) {
|
||||
/* not enough bytes left for comment */
|
||||
_zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return NULL;
|
||||
|
@ -192,46 +225,32 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc
|
|||
return NULL;
|
||||
}
|
||||
|
||||
cdp = eocd + 8;
|
||||
/* number of cdir-entries on this disk */
|
||||
i = _zip_read2(&cdp);
|
||||
/* number of cdir-entries */
|
||||
nentry = _zip_read2(&cdp);
|
||||
if (eocd-EOCD64LOCLEN >= buf && memcmp(eocd-EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0)
|
||||
cd = _zip_read_eocd64(fp, eocd-EOCD64LOCLEN, buf, buf_offset, buflen, flags, error);
|
||||
else
|
||||
cd = _zip_read_eocd(eocd, buf, buf_offset, buflen, flags, error);
|
||||
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
if (cd == NULL)
|
||||
return NULL;
|
||||
|
||||
cd->size = _zip_read4(&cdp);
|
||||
cd->offset = _zip_read4(&cdp);
|
||||
cd->comment = NULL;
|
||||
cd->comment_len = _zip_read2(&cdp);
|
||||
cdp = eocd + 20;
|
||||
comment_len = _zip_read2(&cdp);
|
||||
|
||||
if (((zip_uint64_t)cd->offset)+cd->size > buf_offset + (eocd-buf)) {
|
||||
if ((zip_uint64_t)cd->offset+(zip_uint64_t)cd->size > (zip_uint64_t)buf_offset + (zip_uint64_t)(eocd-buf)) {
|
||||
/* cdir spans past EOCD record */
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
cd->nentry = 0;
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((comlen < cd->comment_len) || (cd->nentry != i)) {
|
||||
_zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
cd->nentry = 0;
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) {
|
||||
if (tail_len < comment_len || ((flags & ZIP_CHECKCONS) && tail_len != comment_len)) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
cd->nentry = 0;
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cd->comment_len) {
|
||||
if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN,
|
||||
cd->comment_len, error))
|
||||
== NULL) {
|
||||
cd->nentry = 0;
|
||||
if (comment_len) {
|
||||
if ((cd->comment=_zip_string_new(eocd+EOCDLEN, (zip_uint16_t)comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) {
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -249,40 +268,32 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc
|
|||
fseeko(fp, cd->offset, SEEK_SET);
|
||||
/* possible consistency check: cd->offset =
|
||||
len-(cd->size+cd->comment_len+EOCDLEN) ? */
|
||||
if (ferror(fp) || ((unsigned long)ftello(fp) != cd->offset)) {
|
||||
if (ferror(fp) || (ftello(fp) != cd->offset)) {
|
||||
/* seek error or offset of cdir wrong */
|
||||
if (ferror(fp))
|
||||
_zip_error_set(error, ZIP_ER_SEEK, errno);
|
||||
else
|
||||
_zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
cd->nentry = 0;
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
left = cd->size;
|
||||
left = (zip_uint64_t)cd->size;
|
||||
i=0;
|
||||
while (i<cd->nentry && left > 0) {
|
||||
if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) {
|
||||
cd->nentry = i;
|
||||
if ((cd->entry[i].orig=_zip_dirent_new()) == NULL
|
||||
|| (_zip_dirent_read(cd->entry[i].orig, fp, bufp, &left, 0, error)) < 0) {
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
i++;
|
||||
|
||||
if (i == cd->nentry && left > 0) {
|
||||
/* Infozip extension for more than 64k entries:
|
||||
nentries wraps around, size indicates correct EOCD */
|
||||
if (_zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error) < 0) {
|
||||
cd->nentry = i;
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cd->nentry = i;
|
||||
if (i != cd->nentry || ((flags & ZIP_CHECKCONS) && left != 0)) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
@ -295,84 +306,88 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc
|
|||
file and header offsets. Returns -1 if not plausible, else the
|
||||
difference between the lowest and the highest fileposition reached */
|
||||
|
||||
static int
|
||||
static zip_int64_t
|
||||
_zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error)
|
||||
{
|
||||
int i;
|
||||
unsigned int min, max, j;
|
||||
zip_uint64_t i;
|
||||
zip_uint64_t min, max, j;
|
||||
struct zip_dirent temp;
|
||||
|
||||
if (cd->nentry) {
|
||||
max = cd->entry[0].offset;
|
||||
min = cd->entry[0].offset;
|
||||
max = cd->entry[0].orig->offset;
|
||||
min = cd->entry[0].orig->offset;
|
||||
}
|
||||
else
|
||||
min = max = 0;
|
||||
|
||||
for (i=0; i<cd->nentry; i++) {
|
||||
if (cd->entry[i].offset < min)
|
||||
min = cd->entry[i].offset;
|
||||
if (min > cd->offset) {
|
||||
if (cd->entry[i].orig->offset < min)
|
||||
min = cd->entry[i].orig->offset;
|
||||
if (min > (zip_uint64_t)cd->offset) {
|
||||
_zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
j = cd->entry[i].offset + cd->entry[i].comp_size
|
||||
+ cd->entry[i].filename_len + LENTRYSIZE;
|
||||
j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
|
||||
+ _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
|
||||
if (j > max)
|
||||
max = j;
|
||||
if (max > cd->offset) {
|
||||
if (max > (zip_uint64_t)cd->offset) {
|
||||
_zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fseeko(fp, cd->entry[i].offset, SEEK_SET) != 0) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, 0);
|
||||
if (fseeko(fp, (off_t)cd->entry[i].orig->offset, SEEK_SET) != 0) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_dirent_read(&temp, fp, NULL, NULL, 1, error) == -1)
|
||||
return -1;
|
||||
|
||||
if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) {
|
||||
if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_dirent_finalize(&temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
|
||||
cd->entry[i].orig->local_extra_fields_read = 1;
|
||||
temp.extra_fields = NULL;
|
||||
|
||||
_zip_dirent_finalize(&temp);
|
||||
}
|
||||
|
||||
return max - min;
|
||||
return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* _zip_check_torrentzip:
|
||||
check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */
|
||||
check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */
|
||||
|
||||
static void
|
||||
_zip_check_torrentzip(struct zip *za)
|
||||
_zip_check_torrentzip(struct zip *za, const struct zip_cdir *cdir)
|
||||
{
|
||||
uLong crc_got, crc_should;
|
||||
char buf[8+1];
|
||||
char *end;
|
||||
|
||||
if (za->zp == NULL || za->cdir == NULL)
|
||||
if (za->zp == NULL || cdir == NULL)
|
||||
return;
|
||||
|
||||
if (za->cdir->comment_len != TORRENT_SIG_LEN+8
|
||||
|| strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0)
|
||||
if (_zip_string_length(cdir->comment) != TORRENT_SIG_LEN+8
|
||||
|| strncmp((const char *)cdir->comment->raw, TORRENT_SIG, TORRENT_SIG_LEN) != 0)
|
||||
return;
|
||||
|
||||
memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8);
|
||||
memcpy(buf, cdir->comment->raw+TORRENT_SIG_LEN, 8);
|
||||
buf[8] = '\0';
|
||||
errno = 0;
|
||||
crc_should = strtoul(buf, &end, 16);
|
||||
if ((crc_should == UINT_MAX && errno != 0) || (end && *end))
|
||||
return;
|
||||
|
||||
if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size,
|
||||
&crc_got, NULL) < 0)
|
||||
if (_zip_filerange_crc(za->zp, cdir->offset, cdir->size, &crc_got, NULL) < 0)
|
||||
return;
|
||||
|
||||
if (crc_got == crc_should)
|
||||
|
@ -383,68 +398,32 @@ _zip_check_torrentzip(struct zip *za)
|
|||
|
||||
|
||||
/* _zip_headercomp:
|
||||
compares two headers h1 and h2; if they are local headers, set
|
||||
local1p or local2p respectively to 1, else 0. Return 0 if they
|
||||
are identical, -1 if not. */
|
||||
compares a central directory entry and a local file header
|
||||
Return 0 if they are consistent, -1 if not. */
|
||||
|
||||
static int
|
||||
_zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2,
|
||||
int local2p)
|
||||
_zip_headercomp(const struct zip_dirent *central, const struct zip_dirent *local)
|
||||
{
|
||||
if ((h1->version_needed != h2->version_needed)
|
||||
if ((central->version_needed != local->version_needed)
|
||||
#if 0
|
||||
/* some zip-files have different values in local
|
||||
and global headers for the bitflags */
|
||||
|| (h1->bitflags != h2->bitflags)
|
||||
|| (central->bitflags != local->bitflags)
|
||||
#endif
|
||||
|| (h1->comp_method != h2->comp_method)
|
||||
|| (h1->last_mod != h2->last_mod)
|
||||
|| (h1->filename_len != h2->filename_len)
|
||||
|| !h1->filename || !h2->filename
|
||||
|| strcmp(h1->filename, h2->filename))
|
||||
|| (central->comp_method != local->comp_method)
|
||||
|| (central->last_mod != local->last_mod)
|
||||
|| !_zip_string_equal(central->filename, local->filename))
|
||||
return -1;
|
||||
|
||||
/* check that CRC and sizes are zero if data descriptor is used */
|
||||
if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p
|
||||
&& (h1->crc != 0
|
||||
|| h1->comp_size != 0
|
||||
|| h1->uncomp_size != 0))
|
||||
return -1;
|
||||
if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p
|
||||
&& (h2->crc != 0
|
||||
|| h2->comp_size != 0
|
||||
|| h2->uncomp_size != 0))
|
||||
return -1;
|
||||
|
||||
/* check that CRC and sizes are equal if no data descriptor is used */
|
||||
if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0)
|
||||
&& ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) {
|
||||
if ((h1->crc != h2->crc)
|
||||
|| (h1->comp_size != h2->comp_size)
|
||||
|| (h1->uncomp_size != h2->uncomp_size))
|
||||
|
||||
if ((central->crc != local->crc) || (central->comp_size != local->comp_size)
|
||||
|| (central->uncomp_size != local->uncomp_size)) {
|
||||
/* InfoZip stores valid values in local header even when data descriptor is used.
|
||||
This is in violation of the appnote. */
|
||||
if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0
|
||||
|| local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((local1p == local2p)
|
||||
&& ((h1->extrafield_len != h2->extrafield_len)
|
||||
|| (h1->extrafield_len && h2->extrafield
|
||||
&& memcmp(h1->extrafield, h2->extrafield,
|
||||
h1->extrafield_len))))
|
||||
return -1;
|
||||
|
||||
/* if either is local, nothing more to check */
|
||||
if (local1p || local2p)
|
||||
return 0;
|
||||
|
||||
if ((h1->version_madeby != h2->version_madeby)
|
||||
|| (h1->disk_number != h2->disk_number)
|
||||
|| (h1->int_attrib != h2->int_attrib)
|
||||
|| (h1->ext_attrib != h2->ext_attrib)
|
||||
|| (h1->offset != h2->offset)
|
||||
|| (h1->comment_len != h2->comment_len)
|
||||
|| (h1->comment_len && h2->comment
|
||||
&& memcmp(h1->comment, h2->comment, h1->comment_len)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -452,7 +431,7 @@ _zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2,
|
|||
|
||||
|
||||
static struct zip *
|
||||
_zip_allocate_new(const char *fn, int *zep)
|
||||
_zip_allocate_new(const char *fn, unsigned int flags, int *zep)
|
||||
{
|
||||
struct zip *za;
|
||||
struct zip_error error;
|
||||
|
@ -467,18 +446,19 @@ _zip_allocate_new(const char *fn, int *zep)
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
_zip_file_exists(const char *fn, int flags, int *zep)
|
||||
_zip_file_exists(const char *fn, unsigned int flags, int *zep)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
@ -488,7 +468,7 @@ _zip_file_exists(const char *fn, int flags, int *zep)
|
|||
}
|
||||
|
||||
if (stat(fn, &st) != 0) {
|
||||
if (flags & ZIP_CREATE || flags & ZIP_OVERWRITE)
|
||||
if (flags & ZIP_CREATE)
|
||||
return 0;
|
||||
else {
|
||||
set_error(zep, NULL, ZIP_ER_OPEN);
|
||||
|
@ -508,12 +488,14 @@ _zip_file_exists(const char *fn, int flags, int *zep)
|
|||
|
||||
|
||||
static struct zip_cdir *
|
||||
_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
|
||||
_zip_find_central_dir(FILE *fp, unsigned int flags, int *zep, off_t len)
|
||||
{
|
||||
struct zip_cdir *cdir, *cdirnew;
|
||||
unsigned char *buf, *match;
|
||||
off_t buf_offset;
|
||||
int a, best, buflen, i;
|
||||
size_t buflen;
|
||||
zip_int64_t a, i;
|
||||
zip_int64_t best;
|
||||
struct zip_error zerr;
|
||||
|
||||
i = fseeko(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END);
|
||||
|
@ -541,10 +523,10 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
|
|||
|
||||
best = -1;
|
||||
cdir = NULL;
|
||||
match = buf;
|
||||
match = buf+ (buflen < CDBUFSIZE ? 0 : EOCD64LOCLEN);
|
||||
_zip_error_set(&zerr, ZIP_ER_NOZIP, 0);
|
||||
|
||||
while ((match=_zip_memmem(match, buflen-(match-buf)-18,
|
||||
while ((match=_zip_memmem(match, buflen-(size_t)(match-buf)-(EOCDLEN-4),
|
||||
(const unsigned char *)EOCD_MAGIC, 4))!=NULL) {
|
||||
/* found match -- check, if good */
|
||||
/* to avoid finding the same match all over again */
|
||||
|
@ -589,8 +571,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
|
|||
|
||||
|
||||
static unsigned char *
|
||||
_zip_memmem(const unsigned char *big, int biglen, const unsigned char *little,
|
||||
int littlelen)
|
||||
_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen)
|
||||
{
|
||||
const unsigned char *p;
|
||||
|
||||
|
@ -598,11 +579,159 @@ _zip_memmem(const unsigned char *big, int biglen, const unsigned char *little,
|
|||
return NULL;
|
||||
p = big-1;
|
||||
while ((p=(const unsigned char *)
|
||||
memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1)))
|
||||
!= NULL) {
|
||||
memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) {
|
||||
if (memcmp(p+1, little+1, littlelen-1)==0)
|
||||
return (unsigned char *)p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct zip_cdir *
|
||||
_zip_read_eocd(const unsigned char *eocd, const unsigned char *buf, off_t buf_offset, size_t buflen,
|
||||
unsigned int flags, struct zip_error *error)
|
||||
{
|
||||
struct zip_cdir *cd;
|
||||
const unsigned char *cdp;
|
||||
zip_uint64_t i, nentry, size, offset;
|
||||
|
||||
if (eocd+EOCDLEN > buf+buflen) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cdp = eocd + 8;
|
||||
|
||||
/* number of cdir-entries on this disk */
|
||||
i = _zip_read2(&cdp);
|
||||
/* number of cdir-entries */
|
||||
nentry = _zip_read2(&cdp);
|
||||
|
||||
if (nentry != i) {
|
||||
_zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = _zip_read4(&cdp);
|
||||
offset = _zip_read4(&cdp);
|
||||
|
||||
if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX || offset+size > ZIP_OFF_MAX) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (offset+size > (zip_uint64_t)(buf_offset + (eocd-buf))) {
|
||||
/* cdir spans past EOCD record */
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_CHECKCONS) && offset+size != (zip_uint64_t)(buf_offset + (eocd-buf))) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
cd->size = (off_t)size;
|
||||
cd->offset = (off_t)offset;
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct zip_cdir *
|
||||
_zip_read_eocd64(FILE *f, const zip_uint8_t *eocd64loc, const zip_uint8_t *buf,
|
||||
off_t buf_offset, size_t buflen, unsigned int flags, struct zip_error *error)
|
||||
{
|
||||
struct zip_cdir *cd;
|
||||
zip_uint64_t offset;
|
||||
const zip_uint8_t *cdp;
|
||||
zip_uint8_t eocd[EOCD64LEN];
|
||||
zip_uint64_t eocd_offset;
|
||||
zip_uint64_t size, nentry, i;
|
||||
|
||||
cdp = eocd64loc+8;
|
||||
eocd_offset = _zip_read8(&cdp);
|
||||
|
||||
if (eocd_offset > ZIP_OFF_MAX || eocd_offset + EOCD64LEN > ZIP_OFF_MAX) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (eocd64loc < buf || (off_t)eocd_offset+EOCD64LEN > (buf_offset+(eocd64loc-buf))) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((off_t)eocd_offset >= buf_offset && (off_t)eocd_offset+EOCD64LEN <= buf_offset+(ssize_t)buflen)
|
||||
cdp = buf+((off_t)eocd_offset-buf_offset);
|
||||
else {
|
||||
if (fseeko(f, (off_t)eocd_offset, SEEK_SET) != 0) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clearerr(f);
|
||||
if (fread(eocd, 1, EOCD64LEN, f) < EOCD64LEN) {
|
||||
_zip_error_set(error, ZIP_ER_READ, errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ferror(f)) {
|
||||
_zip_error_set(error, ZIP_ER_READ, errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cdp = eocd;
|
||||
}
|
||||
|
||||
if (memcmp(cdp, EOCD64_MAGIC, 4) != 0) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
cdp += 4;
|
||||
|
||||
size = _zip_read8(&cdp);
|
||||
|
||||
if ((flags & ZIP_CHECKCONS) && size+eocd_offset+12 != (zip_uint64_t)(buf_offset+(eocd64loc-buf))) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cdp += 4; /* skip version made by/needed */
|
||||
cdp += 8; /* skip num disks */
|
||||
|
||||
nentry = _zip_read8(&cdp);
|
||||
i = _zip_read8(&cdp);
|
||||
|
||||
if (nentry != i) {
|
||||
_zip_error_set(error, ZIP_ER_MULTIDISK, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = _zip_read8(&cdp);
|
||||
offset = _zip_read8(&cdp);
|
||||
|
||||
if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX || offset+size > ZIP_OFF_MAX) {
|
||||
_zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
}
|
||||
if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) {
|
||||
_zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
cd->size = (off_t)size;
|
||||
cd->offset = (off_t)offset;
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_rename.c -- rename file in zip archive
|
||||
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>
|
||||
|
@ -35,36 +35,13 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_rename(struct zip *za, zip_uint64_t idx, const char *name)
|
||||
{
|
||||
const char *old_name;
|
||||
int old_is_dir, new_is_dir;
|
||||
|
||||
if (idx >= za->nentry || name[0] == '\0') {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((old_name=zip_get_name(za, idx, 0)) == NULL)
|
||||
return -1;
|
||||
|
||||
new_is_dir = (name[strlen(name)-1] == '/');
|
||||
old_is_dir = (old_name[strlen(old_name)-1] == '/');
|
||||
|
||||
if (new_is_dir != old_is_dir) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_set_name(za, idx, name);
|
||||
return zip_file_rename(za, idx, name, 0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_replace.c -- replace file via callback function
|
||||
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>
|
||||
|
@ -33,53 +33,13 @@
|
|||
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source)
|
||||
{
|
||||
if (idx >= za->nentry || source == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_replace(za, idx, NULL, source) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
zip_int64_t
|
||||
_zip_replace(struct zip *za, zip_uint64_t idx, const char *name,
|
||||
struct zip_source *source)
|
||||
{
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (idx == ZIP_UINT64_MAX) {
|
||||
if (_zip_entry_new(za) == NULL)
|
||||
return -1;
|
||||
|
||||
idx = za->nentry - 1;
|
||||
}
|
||||
|
||||
_zip_unchange_data(za->entry+idx);
|
||||
|
||||
if (name && _zip_set_name(za, idx, name) != 0)
|
||||
return -1;
|
||||
|
||||
za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry)
|
||||
? ZIP_ST_ADDED : ZIP_ST_REPLACED);
|
||||
za->entry[idx].source = source;
|
||||
|
||||
return idx;
|
||||
return zip_file_replace(za, idx, source, 0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_set_archive_comment.c -- set archive comment
|
||||
Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 2006-2013 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,32 +39,46 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_set_archive_comment(struct zip *za, const char *comment, int len)
|
||||
ZIP_EXTERN int
|
||||
zip_set_archive_comment(struct zip *za, const char *comment, zip_uint16_t len)
|
||||
{
|
||||
char *tmpcom;
|
||||
|
||||
if (len < 0 || len > MAXCOMLEN
|
||||
|| (len > 0 && comment == NULL)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
struct zip_string *cstr;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0 && comment == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
|
||||
if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) {
|
||||
_zip_string_free(cstr);
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
tmpcom = NULL;
|
||||
cstr = NULL;
|
||||
|
||||
free(za->ch_comment);
|
||||
za->ch_comment = tmpcom;
|
||||
za->ch_comment_len = len;
|
||||
_zip_string_free(za->comment_changes);
|
||||
za->comment_changes = NULL;
|
||||
|
||||
if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr))
|
||||
|| (za->comment_orig == NULL && cstr == NULL))) {
|
||||
_zip_string_free(cstr);
|
||||
za->comment_changed = 0;
|
||||
}
|
||||
else {
|
||||
za->comment_changes = cstr;
|
||||
za->comment_changed = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_set_archive_flag(struct zip *za, int flag, int value)
|
||||
ZIP_EXTERN int
|
||||
zip_set_archive_flag(struct zip *za, unsigned int flag, int value)
|
||||
{
|
||||
unsigned int new_flags;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_set_default_password(struct zip *za, const char *passwd)
|
||||
{
|
||||
if (za == NULL)
|
||||
|
|
|
@ -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>
|
||||
|
@ -35,38 +35,17 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_set_file_comment(struct zip *za, zip_uint64_t idx,
|
||||
const char *comment, int len)
|
||||
ZIP_EXTERN int
|
||||
zip_set_file_comment(struct zip *za, zip_uint64_t idx, const char *comment, int len)
|
||||
{
|
||||
char *tmpcom;
|
||||
|
||||
if (idx >= za->nentry
|
||||
|| len < 0 || len > MAXCOMLEN
|
||||
|| (len > 0 && comment == NULL)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
if (len < 0 || len > ZIP_UINT16_MAX) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
tmpcom = NULL;
|
||||
|
||||
free(za->entry[idx].ch_comment);
|
||||
za->entry[idx].ch_comment = tmpcom;
|
||||
za->entry[idx].ch_comment_len = len;
|
||||
|
||||
return 0;
|
||||
return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0);
|
||||
}
|
||||
|
|
90
ext/zip/lib/zip_set_file_compression.c
Normal file
90
ext/zip/lib/zip_set_file_compression.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
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>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_set_file_compression(struct zip *za, zip_uint64_t idx,
|
||||
zip_int32_t method, zip_uint32_t flags)
|
||||
{
|
||||
struct zip_entry *e;
|
||||
zip_int32_t old_method;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) {
|
||||
_zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method);
|
||||
|
||||
/* XXX: revisit this when flags are supported, since they may require a recompression */
|
||||
|
||||
if (method == old_method) {
|
||||
if (e->changes) {
|
||||
e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
|
||||
if (e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
e->changes->comp_method = method;
|
||||
e->changes->changed |= ZIP_DIRENT_COMP_METHOD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -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>
|
||||
|
@ -41,35 +41,77 @@
|
|||
|
||||
|
||||
int
|
||||
_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name)
|
||||
_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
|
||||
{
|
||||
char *s;
|
||||
struct zip_entry *e;
|
||||
struct zip_string *str;
|
||||
int changed;
|
||||
zip_int64_t i;
|
||||
|
||||
if (idx >= za->nentry || name == NULL) {
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) {
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name && strlen(name) > 0) {
|
||||
/* XXX: check for string too long */
|
||||
if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
|
||||
str->encoding = ZIP_ENCODING_UTF8_KNOWN;
|
||||
}
|
||||
else
|
||||
str = NULL;
|
||||
|
||||
/* XXX: encoding flags needed for CP437? */
|
||||
if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
|
||||
_zip_string_free(str);
|
||||
_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* no effective name change */
|
||||
if (i == idx)
|
||||
if (i>=0 && (zip_uint64_t)i == idx) {
|
||||
_zip_string_free(str);
|
||||
return 0;
|
||||
|
||||
if ((s=strdup(name)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (za->entry[idx].state == ZIP_ST_UNCHANGED)
|
||||
za->entry[idx].state = ZIP_ST_RENAMED;
|
||||
|
||||
free(za->entry[idx].ch_filename);
|
||||
za->entry[idx].ch_filename = s;
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->changes) {
|
||||
_zip_string_free(e->changes->filename);
|
||||
e->changes->filename = NULL;
|
||||
e->changes->changed &= ~ZIP_DIRENT_FILENAME;
|
||||
}
|
||||
|
||||
if (e->orig)
|
||||
changed = !_zip_string_equal(e->orig->filename, str);
|
||||
else
|
||||
changed = 1;
|
||||
|
||||
if (changed) {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
_zip_string_free(str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
e->changes->filename = str;
|
||||
e->changes->changed |= ZIP_DIRENT_FILENAME;
|
||||
}
|
||||
else {
|
||||
_zip_string_free(str);
|
||||
if (e->changes && e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd);
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
ZIP_EXTERN struct zip_source *
|
||||
zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep)
|
||||
{
|
||||
struct read_data *f;
|
||||
|
@ -98,9 +98,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
/* XXX: return error if (len > ZIP_INT64_MAX) */
|
||||
|
||||
n = z->end - z->buf;
|
||||
n = (zip_uint64_t)(z->end - z->buf);
|
||||
if (n > len)
|
||||
n = len;
|
||||
|
||||
|
@ -109,7 +107,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
z->buf += n;
|
||||
}
|
||||
|
||||
return n;
|
||||
return (zip_int64_t)n;
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
return 0;
|
||||
|
@ -125,7 +123,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
|
||||
zip_stat_init(st);
|
||||
st->mtime = z->mtime;
|
||||
st->size = z->end - z->data;
|
||||
st->size = (zip_uint64_t)(z->end - z->data);
|
||||
st->comp_size = st->size;
|
||||
st->comp_method = ZIP_CM_STORE;
|
||||
st->encryption_method = ZIP_EM_NONE;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
void
|
||||
zip_source_close(struct zip_source *src)
|
||||
{
|
||||
if (!src->is_open)
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "zipint.h"
|
||||
|
||||
struct crc {
|
||||
struct crc_context {
|
||||
int eof;
|
||||
int validate;
|
||||
int e[2];
|
||||
|
@ -51,23 +51,27 @@ static zip_int64_t crc_read(struct zip_source *, void *, void *
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
struct zip_source *
|
||||
zip_source_crc(struct zip *za, struct zip_source *src, int validate)
|
||||
{
|
||||
struct crc *ctx;
|
||||
struct crc_context *ctx;
|
||||
|
||||
if (src == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
|
||||
if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->eof = 0;
|
||||
ctx->validate = validate;
|
||||
|
||||
ctx->e[0] = ctx->e[1] = 0;
|
||||
ctx->size = 0;
|
||||
ctx->crc = 0;
|
||||
|
||||
return zip_source_layered(za, src, crc_read, ctx);
|
||||
}
|
||||
|
||||
|
@ -77,15 +81,15 @@ static zip_int64_t
|
|||
crc_read(struct zip_source *src, void *_ctx, void *data,
|
||||
zip_uint64_t len, enum zip_source_cmd cmd)
|
||||
{
|
||||
struct crc *ctx;
|
||||
struct crc_context *ctx;
|
||||
zip_int64_t n;
|
||||
|
||||
ctx = (struct crc *)_ctx;
|
||||
ctx = (struct crc_context *)_ctx;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_OPEN:
|
||||
ctx->eof = 0;
|
||||
ctx->crc = crc32(0, NULL, 0);
|
||||
ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
|
||||
ctx->size = 0;
|
||||
|
||||
return 0;
|
||||
|
@ -120,8 +124,8 @@ crc_read(struct zip_source *src, void *_ctx, void *data,
|
|||
}
|
||||
}
|
||||
else {
|
||||
ctx->size += n;
|
||||
ctx->crc = crc32(ctx->crc, data, n);
|
||||
ctx->size += (zip_uint64_t)n;
|
||||
ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data, (uInt)n); /* XXX: check for overflow, use multiple crc calls if needed */
|
||||
}
|
||||
return n;
|
||||
|
||||
|
@ -139,7 +143,10 @@ crc_read(struct zip_source *src, void *_ctx, void *data,
|
|||
After all, this only works for uncompressed data. */
|
||||
st->size = ctx->size;
|
||||
st->crc = ctx->crc;
|
||||
st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC;
|
||||
st->comp_size = ctx->size;
|
||||
st->comp_method = ZIP_CM_STORE;
|
||||
st->encryption_method = ZIP_EM_NONE;
|
||||
st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -60,14 +60,14 @@ static void deflate_free(struct deflate *);
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
struct zip_source *
|
||||
zip_source_deflate(struct zip *za, struct zip_source *src,
|
||||
zip_uint16_t cm, int flags)
|
||||
zip_int32_t cm, int flags)
|
||||
{
|
||||
struct deflate *ctx;
|
||||
struct zip_source *s2;
|
||||
|
||||
if (src == NULL || cm != ZIP_CM_DEFLATE) {
|
||||
if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ compress_read(struct zip_source *src, struct deflate *ctx,
|
|||
return 0;
|
||||
|
||||
ctx->zstr.next_out = (Bytef *)data;
|
||||
ctx->zstr.avail_out = len;
|
||||
ctx->zstr.avail_out = (uInt)len; /* XXX: check for overflow */
|
||||
|
||||
end = 0;
|
||||
while (!end) {
|
||||
|
@ -136,8 +136,7 @@ compress_read(struct zip_source *src, struct deflate *ctx,
|
|||
break;
|
||||
}
|
||||
|
||||
if ((n=zip_source_read(src, ctx->buffer,
|
||||
sizeof(ctx->buffer))) < 0) {
|
||||
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
||||
zip_source_error(src, ctx->e, ctx->e+1);
|
||||
end = 1;
|
||||
break;
|
||||
|
@ -149,7 +148,7 @@ compress_read(struct zip_source *src, struct deflate *ctx,
|
|||
}
|
||||
else {
|
||||
ctx->zstr.next_in = (Bytef *)ctx->buffer;
|
||||
ctx->zstr.avail_in = n;
|
||||
ctx->zstr.avail_in = (uInt)n;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -167,7 +166,7 @@ compress_read(struct zip_source *src, struct deflate *ctx,
|
|||
}
|
||||
|
||||
if (ctx->zstr.avail_out < len)
|
||||
return len - ctx->zstr.avail_out;
|
||||
return (zip_int64_t)(len - ctx->zstr.avail_out);
|
||||
|
||||
return (ctx->e[0] == 0) ? 0 : -1;
|
||||
}
|
||||
|
@ -188,7 +187,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx,
|
|||
return 0;
|
||||
|
||||
ctx->zstr.next_out = (Bytef *)data;
|
||||
ctx->zstr.avail_out = len;
|
||||
ctx->zstr.avail_out = (uInt)len; /* XXX: check for overflow */
|
||||
|
||||
end = 0;
|
||||
while (!end && ctx->zstr.avail_out) {
|
||||
|
@ -210,8 +209,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx,
|
|||
break;
|
||||
}
|
||||
|
||||
if ((n=zip_source_read(src, ctx->buffer,
|
||||
sizeof(ctx->buffer))) < 0) {
|
||||
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
||||
zip_source_error(src, ctx->e, ctx->e+1);
|
||||
end = 1;
|
||||
break;
|
||||
|
@ -220,7 +218,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx,
|
|||
ctx->eof = 1;
|
||||
else {
|
||||
ctx->zstr.next_in = (Bytef *)ctx->buffer;
|
||||
ctx->zstr.avail_in = n;
|
||||
ctx->zstr.avail_in = (uInt)n;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -237,7 +235,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx,
|
|||
}
|
||||
|
||||
if (ctx->zstr.avail_out < len)
|
||||
return len - ctx->zstr.avail_out;
|
||||
return (zip_int64_t)(len - ctx->zstr.avail_out);
|
||||
|
||||
return (ctx->e[0] == 0) ? 0 : -1;
|
||||
}
|
||||
|
@ -334,7 +332,7 @@ deflate_decompress(struct zip_source *src, void *ud, void *data,
|
|||
ctx->zstr.zfree = Z_NULL;
|
||||
ctx->zstr.opaque = NULL;
|
||||
ctx->zstr.next_in = (Bytef *)ctx->buffer;
|
||||
ctx->zstr.avail_in = n;
|
||||
ctx->zstr.avail_in = (uInt)n /* XXX: check for overflow */;
|
||||
|
||||
/* negative value to tell zlib that there is no header */
|
||||
if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_source_error.c -- get last error from zip_source
|
||||
Copyright (C) 2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 2009-2013 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>
|
||||
|
@ -37,24 +37,21 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
void
|
||||
zip_source_error(struct zip_source *src, int *ze, int *se)
|
||||
{
|
||||
int e[2] = { 0, 0 };
|
||||
int e[2];
|
||||
|
||||
if (src->src == NULL) {
|
||||
if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
|
||||
e[0] = ZIP_ER_INTERNAL;
|
||||
e[1] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (src->error_source) {
|
||||
case ZIP_LES_NONE:
|
||||
if (src->src == NULL) {
|
||||
if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
|
||||
e[0] = ZIP_ER_INTERNAL;
|
||||
e[1] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
e[0] = e[1] = 0;
|
||||
e[0] = e[1] = 0;
|
||||
break;
|
||||
|
||||
case ZIP_LES_INVAL:
|
||||
|
@ -67,8 +64,7 @@ zip_source_error(struct zip_source *src, int *ze, int *se)
|
|||
return;
|
||||
|
||||
case ZIP_LES_UPPER:
|
||||
if (src->cb.l(src->src, src->ud, e, sizeof(e),
|
||||
ZIP_SOURCE_ERROR) < 0) {
|
||||
if (src->cb.l(src->src, src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
|
||||
e[0] = ZIP_ER_INTERNAL;
|
||||
e[1] = 0;
|
||||
}
|
||||
|
@ -77,6 +73,7 @@ zip_source_error(struct zip_source *src, int *ze, int *se)
|
|||
default:
|
||||
e[0] = ZIP_ER_INTERNAL;
|
||||
e[1] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
ZIP_EXTERN struct zip_source *
|
||||
zip_source_file(struct zip *za, const char *fname, zip_uint64_t start,
|
||||
zip_int64_t len)
|
||||
{
|
||||
|
|
|
@ -58,14 +58,14 @@ static zip_int64_t read_file(void *state, void *data, zip_uint64_t len,
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
ZIP_EXTERN struct zip_source *
|
||||
zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start,
|
||||
zip_int64_t len)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
{
|
||||
struct read_file *z;
|
||||
char *buf;
|
||||
int i, n;
|
||||
size_t i, n;
|
||||
|
||||
z = (struct read_file *)state;
|
||||
buf = (char *)data;
|
||||
|
@ -140,7 +140,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (z->closep) {
|
||||
if (z->closep && z->off > 0) {
|
||||
if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) {
|
||||
z->e[0] = ZIP_ER_SEEK;
|
||||
z->e[1] = errno;
|
||||
|
@ -153,30 +153,31 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
case ZIP_SOURCE_READ:
|
||||
/* XXX: return INVAL if len > size_t max */
|
||||
if (z->remain != -1)
|
||||
n = len > z->remain ? z->remain : len;
|
||||
n = len > (zip_uint64_t)z->remain ? (zip_uint64_t)z->remain : len;
|
||||
else
|
||||
n = len;
|
||||
|
||||
if (!z->closep) {
|
||||
/* we might share this file with others, so let's be safe */
|
||||
if (fseeko(z->f, (off_t)(z->off + z->len-z->remain),
|
||||
SEEK_SET) < 0) {
|
||||
if (fseeko(z->f, (off_t)(z->off + (zip_uint64_t)(z->len-z->remain)), SEEK_SET) < 0) {
|
||||
z->e[0] = ZIP_ER_SEEK;
|
||||
z->e[1] = errno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i=fread(buf, 1, n, z->f)) < 0) {
|
||||
z->e[0] = ZIP_ER_READ;
|
||||
z->e[1] = errno;
|
||||
return -1;
|
||||
if ((i=fread(buf, 1, n, z->f)) == 0) {
|
||||
if (ferror(z->f)) {
|
||||
z->e[0] = ZIP_ER_READ;
|
||||
z->e[1] = errno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (z->remain != -1)
|
||||
z->remain -= i;
|
||||
|
||||
return i;
|
||||
return (zip_int64_t)i;
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
if (z->fname) {
|
||||
|
@ -214,11 +215,11 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
|
|||
st->mtime = fst.st_mtime;
|
||||
st->valid |= ZIP_STAT_MTIME;
|
||||
if (z->len != -1) {
|
||||
st->size = z->len;
|
||||
st->size = (zip_uint64_t)z->len;
|
||||
st->valid |= ZIP_STAT_SIZE;
|
||||
}
|
||||
else if ((fst.st_mode&S_IFMT) == S_IFREG) {
|
||||
st->size = fst.st_size;
|
||||
st->size = (zip_uint64_t)fst.st_size;
|
||||
st->valid |= ZIP_STAT_SIZE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
ZIP_EXTERN void
|
||||
zip_source_free(struct zip_source *src)
|
||||
{
|
||||
if (src == NULL)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
ZIP_EXTERN struct zip_source *
|
||||
zip_source_function(struct zip *za, zip_source_callback zcb, void *ud)
|
||||
{
|
||||
struct zip_source *zs;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
struct zip_source *
|
||||
zip_source_layered(struct zip *za, struct zip_source *src,
|
||||
zip_source_layered_callback cb, void *ud)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
zip_source_open.c -- open zip_source (prepare for reading)
|
||||
Copyright (C) 2009 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 2009-2013 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>
|
||||
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
int
|
||||
zip_source_open(struct zip_source *src)
|
||||
{
|
||||
zip_int64_t ret;
|
||||
|
@ -60,7 +60,7 @@ zip_source_open(struct zip_source *src)
|
|||
ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN);
|
||||
|
||||
if (ret < 0) {
|
||||
(void)zip_source_close(src->src);
|
||||
zip_source_close(src->src);
|
||||
|
||||
if (ret == ZIP_SOURCE_ERR_LOWER)
|
||||
src->error_source = ZIP_LES_LOWER;
|
||||
|
|
|
@ -49,10 +49,6 @@ struct trad_pkware {
|
|||
#define KEY1 591751049
|
||||
#define KEY2 878082192
|
||||
|
||||
static const uLongf *crc = NULL;
|
||||
|
||||
#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8))
|
||||
|
||||
|
||||
|
||||
static void decrypt(struct trad_pkware *, zip_uint8_t *,
|
||||
|
@ -64,7 +60,7 @@ static void pkware_free(struct trad_pkware *);
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
struct zip_source *
|
||||
zip_source_pkware(struct zip *za, struct zip_source *src,
|
||||
zip_uint16_t em, int flags, const char *password)
|
||||
{
|
||||
|
@ -80,9 +76,6 @@ zip_source_pkware(struct zip *za, struct zip_source *src,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (crc == NULL)
|
||||
crc = get_crc_table();
|
||||
|
||||
if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
|
||||
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
|
@ -118,7 +111,7 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
|
|||
|
||||
if (!update_only) {
|
||||
/* decrypt next byte */
|
||||
tmp = ctx->key[2] | 2;
|
||||
tmp = (zip_uint16_t)(ctx->key[2] | 2);
|
||||
tmp = (tmp * (tmp ^ 1)) >> 8;
|
||||
b ^= tmp;
|
||||
}
|
||||
|
@ -128,10 +121,10 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
|
|||
out[i] = b;
|
||||
|
||||
/* update keys */
|
||||
ctx->key[0] = CRC32(ctx->key[0], b);
|
||||
ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
|
||||
ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
|
||||
b = ctx->key[1] >> 24;
|
||||
ctx->key[2] = CRC32(ctx->key[2], b);
|
||||
ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +189,7 @@ pkware_decrypt(struct zip_source *src, void *ud, void *data,
|
|||
if ((n=zip_source_read(src, data, len)) < 0)
|
||||
return ZIP_SOURCE_ERR_LOWER;
|
||||
|
||||
decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
|
||||
decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
|
||||
0);
|
||||
return n;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)
|
||||
struct zip_source *
|
||||
zip_source_pop(struct zip_source *src)
|
||||
{
|
||||
struct zip_source *lower;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(zip_int64_t)
|
||||
zip_int64_t
|
||||
zip_source_read(struct zip_source *src, void *data, zip_uint64_t len)
|
||||
{
|
||||
zip_int64_t ret;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
int
|
||||
zip_source_stat(struct zip_source *src, struct zip_stat *st)
|
||||
{
|
||||
zip_int64_t ret;
|
||||
|
|
150
ext/zip/lib/zip_source_window.c
Normal file
150
ext/zip/lib/zip_source_window.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
zip_source_window.c -- return part of lower source
|
||||
Copyright (C) 2012-2013 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);
|
||||
|
||||
|
||||
|
||||
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 ret;
|
||||
zip_uint64_t n, i;
|
||||
char b[8192];
|
||||
|
||||
ctx = (struct window *)_ctx;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_OPEN:
|
||||
for (n=0; n<ctx->skip; n+=(zip_uint64_t)ret) {
|
||||
i = (ctx->skip-n > sizeof(b) ? sizeof(b) : ctx->skip-n);
|
||||
if ((ret=zip_source_read(src, b, i)) < 0)
|
||||
return ZIP_SOURCE_ERR_LOWER;
|
||||
if (ret==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 ((ret=zip_source_read(src, data, len)) < 0)
|
||||
return ZIP_SOURCE_ERR_LOWER;
|
||||
|
||||
ctx->left -= (zip_uint64_t)ret;
|
||||
|
||||
if (ret == 0) {
|
||||
if (ctx->left > 0) {
|
||||
ctx->e[0] = ZIP_ER_EOF;
|
||||
ctx->e[1] = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -38,153 +38,24 @@
|
|||
|
||||
#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_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)
|
||||
zip_flags_t 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 (len < -1) {
|
||||
_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 (len == -1)
|
||||
len = 0;
|
||||
|
||||
if (start == 0 && len == 0)
|
||||
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, (zip_uint64_t)len, NULL);
|
||||
}
|
||||
|
|
172
ext/zip/lib/zip_source_zip_new.c
Normal file
172
ext/zip/lib/zip_source_zip_new.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
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, zip_flags_t flags,
|
||||
zip_uint64_t start, zip_uint64_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 || 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].deleted)) {
|
||||
_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INTERNAL, 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;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
struct zip_stat st2;
|
||||
|
||||
st2.size = len ? len : st.size-start;
|
||||
st2.comp_size = st2.size;
|
||||
st2.comp_method = ZIP_CM_STORE;
|
||||
st2.mtime = st.mtime;
|
||||
st2.valid = ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_MTIME;
|
||||
|
||||
/* XXX: check for overflow of st2.size */
|
||||
if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset+start, (zip_int64_t)st2.size, 0, &st2)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* XXX: check for overflow of st.comp_size */
|
||||
if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset, (zip_int64_t)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 || 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;
|
||||
}
|
|
@ -37,13 +37,13 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st)
|
||||
ZIP_EXTERN int
|
||||
zip_stat(struct zip *za, const char *fname, zip_flags_t flags, struct zip_stat *st)
|
||||
{
|
||||
int idx;
|
||||
zip_int64_t idx;
|
||||
|
||||
if ((idx=zip_name_locate(za, fname, flags)) < 0)
|
||||
return -1;
|
||||
|
||||
return zip_stat_index(za, idx, flags, st);
|
||||
return zip_stat_index(za, (zip_uint64_t)idx, flags, st);
|
||||
}
|
||||
|
|
|
@ -37,16 +37,15 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
zip_stat_index(struct zip *za, zip_uint64_t index, int flags,
|
||||
ZIP_EXTERN int
|
||||
zip_stat_index(struct zip *za, zip_uint64_t index, zip_flags_t flags,
|
||||
struct zip_stat *st)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (index >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
struct zip_dirent *de;
|
||||
|
||||
if ((de=_zip_get_dirent(za, index, flags, NULL)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((name=zip_get_name(za, index, flags)) == NULL)
|
||||
return -1;
|
||||
|
@ -60,20 +59,15 @@ zip_stat_index(struct zip *za, zip_uint64_t index, int flags,
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (za->cdir == NULL || index >= za->cdir->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip_stat_init(st);
|
||||
|
||||
st->crc = za->cdir->entry[index].crc;
|
||||
st->size = za->cdir->entry[index].uncomp_size;
|
||||
st->mtime = za->cdir->entry[index].last_mod;
|
||||
st->comp_size = za->cdir->entry[index].comp_size;
|
||||
st->comp_method = za->cdir->entry[index].comp_method;
|
||||
if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) {
|
||||
if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
|
||||
st->crc = de->crc;
|
||||
st->size = de->uncomp_size;
|
||||
st->mtime = de->last_mod;
|
||||
st->comp_size = de->comp_size;
|
||||
st->comp_method = (zip_uint16_t)de->comp_method;
|
||||
if (de->bitflags & ZIP_GPBF_ENCRYPTED) {
|
||||
if (de->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
|
||||
/* XXX */
|
||||
st->encryption_method = ZIP_EM_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(void)
|
||||
ZIP_EXTERN void
|
||||
zip_stat_init(struct zip_stat *st)
|
||||
{
|
||||
st->valid = 0;
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN(const char *)
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_strerror(struct zip *za)
|
||||
{
|
||||
return _zip_error_strerror(&za->error);
|
||||
|
|
196
ext/zip/lib/zip_string.c
Normal file
196
ext/zip/lib/zip_string.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
zip_string.c -- string handling (with encoding)
|
||||
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"
|
||||
|
||||
|
||||
|
||||
zip_uint32_t
|
||||
_zip_string_crc32(const struct zip_string *s)
|
||||
{
|
||||
zip_uint32_t crc;
|
||||
|
||||
crc = (zip_uint32_t)crc32(0L, Z_NULL, 0);
|
||||
|
||||
if (s != NULL)
|
||||
crc = (zip_uint32_t)crc32(crc, s->raw, s->length);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_string_equal(const struct zip_string *a, const struct zip_string *b)
|
||||
{
|
||||
if (a == NULL || b == NULL)
|
||||
return a == b;
|
||||
|
||||
if (a->length != b->length)
|
||||
return 0;
|
||||
|
||||
/* XXX: encoding */
|
||||
|
||||
return (memcmp(a->raw, b->raw, a->length) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_string_free(struct zip_string *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
free(s->raw);
|
||||
free(s->converted);
|
||||
free(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const zip_uint8_t *
|
||||
_zip_string_get(struct zip_string *string, zip_uint32_t *lenp, zip_flags_t flags, struct zip_error *error)
|
||||
{
|
||||
static const zip_uint8_t empty[1] = "";
|
||||
|
||||
if (string == NULL) {
|
||||
if (lenp)
|
||||
*lenp = 0;
|
||||
return empty;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_FL_ENC_RAW) == 0) {
|
||||
/* start guessing */
|
||||
if (string->encoding == ZIP_ENCODING_UNKNOWN)
|
||||
_zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN);
|
||||
|
||||
if (((flags & ZIP_FL_ENC_STRICT)
|
||||
&& string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN)
|
||||
|| (string->encoding == ZIP_ENCODING_CP437)) {
|
||||
if (string->converted == NULL) {
|
||||
if ((string->converted=_zip_cp437_to_utf8(string->raw, string->length,
|
||||
&string->converted_length, error)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (lenp)
|
||||
*lenp = string->converted_length;
|
||||
return string->converted;
|
||||
}
|
||||
}
|
||||
|
||||
if (lenp)
|
||||
*lenp = string->length;
|
||||
return string->raw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
zip_uint16_t
|
||||
_zip_string_length(const struct zip_string *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
return s->length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct zip_string *
|
||||
_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, struct zip_error *error)
|
||||
{
|
||||
struct zip_string *s;
|
||||
enum zip_encoding_type expected_encoding;
|
||||
|
||||
if (length == 0)
|
||||
return NULL;
|
||||
|
||||
switch (flags & ZIP_FL_ENCODING_ALL) {
|
||||
case ZIP_FL_ENC_GUESS:
|
||||
expected_encoding = ZIP_ENCODING_UNKNOWN;
|
||||
break;
|
||||
case ZIP_FL_ENC_UTF_8:
|
||||
expected_encoding = ZIP_ENCODING_UTF8_KNOWN;
|
||||
break;
|
||||
case ZIP_FL_ENC_CP437:
|
||||
expected_encoding = ZIP_ENCODING_CP437;
|
||||
break;
|
||||
default:
|
||||
_zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((s=(struct zip_string *)malloc(sizeof(*s))) == NULL) {
|
||||
_zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((s->raw=(zip_uint8_t *)malloc(length+1)) == NULL) {
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(s->raw, raw, length);
|
||||
s->raw[length] = '\0';
|
||||
s->length = length;
|
||||
s->encoding = ZIP_ENCODING_UNKNOWN;
|
||||
s->converted = NULL;
|
||||
s->converted_length = 0;
|
||||
|
||||
if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
|
||||
if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) {
|
||||
_zip_string_free(s);
|
||||
_zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_string_write(const struct zip_string *s, FILE *f)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
fwrite(s->raw, s->length, 1, f);
|
||||
}
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_unchange(struct zip *za, zip_uint64_t idx)
|
||||
{
|
||||
return _zip_unchange(za, idx, 0);
|
||||
|
@ -50,34 +50,23 @@ zip_unchange(struct zip *za, zip_uint64_t idx)
|
|||
int
|
||||
_zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates)
|
||||
{
|
||||
int i;
|
||||
zip_int64_t i;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (za->entry[idx].ch_filename) {
|
||||
if (!allow_duplicates) {
|
||||
i = _zip_name_locate(za,
|
||||
_zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL),
|
||||
0, NULL);
|
||||
if (i != -1 && i != idx) {
|
||||
_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
|
||||
return -1;
|
||||
}
|
||||
if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) {
|
||||
i = _zip_name_locate(za, _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), 0, NULL);
|
||||
if (i >= 0 && (zip_uint64_t)i != idx) {
|
||||
_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(za->entry[idx].ch_filename);
|
||||
za->entry[idx].ch_filename = NULL;
|
||||
}
|
||||
|
||||
free(za->entry[idx].ch_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;
|
||||
_zip_dirent_free(za->entry[idx].changes);
|
||||
za->entry[idx].changes = NULL;
|
||||
|
||||
_zip_unchange_data(za->entry+idx);
|
||||
|
||||
|
|
|
@ -39,10 +39,11 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_unchange_all(struct zip *za)
|
||||
{
|
||||
int ret, i;
|
||||
int ret;
|
||||
zip_uint64_t i;
|
||||
|
||||
ret = 0;
|
||||
for (i=0; i<za->nentry; i++)
|
||||
|
|
|
@ -39,13 +39,15 @@
|
|||
|
||||
|
||||
|
||||
ZIP_EXTERN(int)
|
||||
ZIP_EXTERN int
|
||||
zip_unchange_archive(struct zip *za)
|
||||
{
|
||||
free(za->ch_comment);
|
||||
za->ch_comment = NULL;
|
||||
za->ch_comment_len = -1;
|
||||
|
||||
if (za->comment_changed) {
|
||||
_zip_string_free(za->comment_changes);
|
||||
za->comment_changes = NULL;
|
||||
za->comment_changed = 0;
|
||||
}
|
||||
|
||||
za->ch_flags = za->flags;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/*
|
||||
$NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz Exp $
|
||||
|
||||
zip_unchange_data.c -- undo helper function
|
||||
Copyright (C) 1999, 2004 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>
|
||||
|
@ -35,8 +33,6 @@
|
|||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
void
|
||||
|
@ -46,7 +42,15 @@ _zip_unchange_data(struct zip_entry *ze)
|
|||
zip_source_free(ze->source);
|
||||
ze->source = NULL;
|
||||
}
|
||||
|
||||
ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED;
|
||||
|
||||
if (ze->changes != NULL && (ze->changes->changed & ZIP_DIRENT_COMP_METHOD) && ze->changes->comp_method == ZIP_CM_REPLACED_DEFAULT) {
|
||||
ze->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
|
||||
if (ze->changes->changed == 0) {
|
||||
_zip_dirent_free(ze->changes);
|
||||
ze->changes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ze->deleted = 0;
|
||||
}
|
||||
|
||||
|
|
255
ext/zip/lib/zip_utf-8.c
Normal file
255
ext/zip/lib/zip_utf-8.c
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
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 "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(struct zip_string *str, enum zip_encoding_type expected_encoding)
|
||||
{
|
||||
enum zip_encoding_type enc;
|
||||
const zip_uint8_t *name;
|
||||
zip_uint32_t i, j, ulen;
|
||||
|
||||
if (str == NULL)
|
||||
return ZIP_ENCODING_ASCII;
|
||||
|
||||
name = str->raw;
|
||||
|
||||
if (str->encoding != ZIP_ENCODING_UNKNOWN)
|
||||
enc = str->encoding;
|
||||
else {
|
||||
enc = ZIP_ENCODING_ASCII;
|
||||
for (i=0; i<str->length; i++) {
|
||||
if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t')
|
||||
continue;
|
||||
|
||||
enc = ZIP_ENCODING_UTF8_GUESSED;
|
||||
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 {
|
||||
enc = ZIP_ENCODING_CP437;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i + ulen >= str->length) {
|
||||
enc = ZIP_ENCODING_CP437;
|
||||
break;
|
||||
}
|
||||
|
||||
for (j=1; j<=ulen; j++) {
|
||||
if ((name[i+j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) {
|
||||
enc = ZIP_ENCODING_CP437;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
i += ulen;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
str->encoding = enc;
|
||||
|
||||
if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
|
||||
if (expected_encoding == ZIP_ENCODING_UTF8_KNOWN && enc == ZIP_ENCODING_UTF8_GUESSED)
|
||||
str->encoding = enc = ZIP_ENCODING_UTF8_KNOWN;
|
||||
|
||||
if (expected_encoding != enc && enc != ZIP_ENCODING_ASCII)
|
||||
return ZIP_ENCODING_ERROR;
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 *cp437buf = (zip_uint8_t *)_cp437buf;
|
||||
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;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#define _POSIX_
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <zconf.h>
|
||||
|
||||
#ifndef strcasecmp
|
||||
# define strcmpi _strcmpi
|
||||
#endif
|
||||
|
||||
#ifndef ssize_t
|
||||
# define ssize_t SSIZE_T
|
||||
#endif
|
||||
|
||||
#ifndef mode_t
|
||||
# define mode_t int
|
||||
#endif
|
||||
|
||||
#ifndef snprintf
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifndef mkstemp
|
||||
# define mkstemp(t) _creat(_mktemp(t), _S_IREAD|_S_IWRITE)
|
||||
#endif
|
||||
/*
|
||||
#ifndef fseeko
|
||||
# define fseeko fseek
|
||||
#endif
|
||||
*/
|
|
@ -1,47 +1,129 @@
|
|||
#ifndef _HAD_ZIPCONF_H
|
||||
#define _HAD_ZIPCONF_H
|
||||
|
||||
/*
|
||||
zipconf.h -- platform specific include file
|
||||
|
||||
This file was generated automatically by ./make_zipconf.sh
|
||||
based on ../config.h.
|
||||
*/
|
||||
|
||||
#define LIBZIP_VERSION "0.10.1"
|
||||
#define LIBZIP_VERSION_MAJOR 0
|
||||
#define LIBZIP_VERSION_MINOR 10
|
||||
#define LIBZIP_VERSION_MICRO 0
|
||||
|
||||
#include <php_stdint.h>
|
||||
|
||||
typedef int8_t zip_int8_t;
|
||||
#define ZIP_INT8_MIN INT8_MIN
|
||||
#define ZIP_INT8_MAX INT8_MAX
|
||||
|
||||
typedef uint8_t zip_uint8_t;
|
||||
#define ZIP_UINT8_MAX UINT8_MAX
|
||||
|
||||
typedef int16_t zip_int16_t;
|
||||
#define ZIP_INT16_MIN INT16_MIN
|
||||
#define ZIP_INT16_MAX INT16_MAX
|
||||
|
||||
typedef uint16_t zip_uint16_t;
|
||||
#define ZIP_UINT16_MAX UINT16_MAX
|
||||
|
||||
typedef int32_t zip_int32_t;
|
||||
#define ZIP_INT32_MIN INT32_MIN
|
||||
#define ZIP_INT32_MAX INT32_MAX
|
||||
|
||||
typedef uint32_t zip_uint32_t;
|
||||
#define ZIP_UINT32_MAX UINT32_MAX
|
||||
|
||||
typedef int64_t zip_int64_t;
|
||||
#define ZIP_INT64_MIN INT64_MIN
|
||||
#define ZIP_INT64_MAX INT64_MAX
|
||||
|
||||
typedef uint64_t zip_uint64_t;
|
||||
#define ZIP_UINT64_MAX UINT64_MAX
|
||||
|
||||
|
||||
#endif /* zipconf.h */
|
||||
#ifndef _HAD_ZIPCONF_H
|
||||
#define _HAD_ZIPCONF_H
|
||||
|
||||
/*
|
||||
zipconf.h -- platform specific include file
|
||||
|
||||
This file was generated automatically by CMake
|
||||
based on ../cmake-zipconf.h.in.
|
||||
*/
|
||||
#define LIBZIP_VERSION "0.11.1"
|
||||
/* #undef HAVE_INTTYPES_H_LIBZIP */
|
||||
|
||||
#if defined(_WIN32)
|
||||
# if _MSC_VER > 1500
|
||||
# define HAVE_STDINT_H_LIBZIP
|
||||
# else
|
||||
# include "win32/php_stdint.h"
|
||||
# endif
|
||||
#else
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#define HAVE_SYS_TYPES_H_LIBZIP
|
||||
#define HAVE___INT8_LIBZIP
|
||||
#define HAVE_INT8_T_LIBZIP
|
||||
#define HAVE_UINT8_T_LIBZIP
|
||||
#define HAVE___INT16_LIBZIP
|
||||
#define HAVE_INT16_T_LIBZIP
|
||||
#define HAVE_UINT16_T_LIBZIP
|
||||
#define HAVE___INT32_LIBZIP
|
||||
#define HAVE_INT32_T_LIBZIP
|
||||
#define HAVE_UINT32_T_LIBZIP
|
||||
#define HAVE___INT64_LIBZIP
|
||||
#define HAVE_INT64_T_LIBZIP
|
||||
#define HAVE_UINT64_T_LIBZIP
|
||||
#define SHORT_LIBZIP 2
|
||||
#define INT_LIBZIP 4
|
||||
#define LONG_LIBZIP 4
|
||||
#define LONG_LONG_LIBZIP 8
|
||||
|
||||
#if defined(HAVE_STDINT_H_LIBZIP)
|
||||
#include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H_LIBZIP)
|
||||
#include <inttypes.h>
|
||||
#elif defined(HAVE_SYS_TYPES_H_LIBZIP)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
typedef signed long zip_int32_t;
|
||||
#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
|
||||
typedef unsigned long zip_uint32_t;
|
||||
#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(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8
|
||||
typedef signed long long zip_int64_t;
|
||||
#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) && LONG_LONG_LIBZIP == 8
|
||||
typedef unsigned long zip_uint64_t;
|
||||
#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8
|
||||
typedef unsigned long long zip_uint64_t;
|
||||
#endif
|
||||
|
||||
#define ZIP_INT8_MIN -0x80
|
||||
#define ZIP_INT8_MAX 0x7f
|
||||
#define ZIP_UINT8_MAX 0xff
|
||||
|
||||
#define ZIP_INT16_MIN -0x8000
|
||||
#define ZIP_INT16_MAX 0x7fff
|
||||
#define ZIP_UINT16_MAX 0xffff
|
||||
|
||||
#define ZIP_INT32_MIN -0x80000000L
|
||||
#define ZIP_INT32_MAX 0x7fffffffL
|
||||
#define ZIP_UINT32_MAX 0xffffffffLU
|
||||
|
||||
#define ZIP_INT64_MIN -0x8000000000000000LL
|
||||
#define ZIP_INT64_MAX 0x7fffffffffffffffLL
|
||||
#define ZIP_UINT64_MAX 0xffffffffffffffffULL
|
||||
|
||||
#endif /* zipconf.h */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/*
|
||||
zipint.h -- internal declarations.
|
||||
Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 1999-2013 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>
|
||||
|
@ -20,7 +20,7 @@
|
|||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
|
@ -34,9 +34,64 @@
|
|||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* to have *_MAX definitions for all types when compiling with g++ */
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* for dup(), close(), etc. */
|
||||
#include <io.h>
|
||||
#include "config.w32.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ZIP_COMPILING_DEPRECATED
|
||||
#define ZIP_DISABLE_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "zip.h"
|
||||
#ifdef PHP_WIN32
|
||||
# include "php_zip_config.w32.h"
|
||||
#else
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MOVEFILEEXA) && defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#define _zip_rename(s, t) \
|
||||
(!MoveFileExA((s), (t), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
|
||||
#else
|
||||
#define _zip_rename rename
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef strcasecmp
|
||||
# define strcasecmp _strcmpi
|
||||
#endif
|
||||
|
||||
#if defined(HAVE__CLOSE)
|
||||
#define close _close
|
||||
#endif
|
||||
#if defined(HAVE__DUP)
|
||||
#define dup _dup
|
||||
#endif
|
||||
/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
|
||||
#if defined(HAVE__FDOPEN)
|
||||
#define fdopen _fdopen
|
||||
#endif
|
||||
#if defined(HAVE__FILENO)
|
||||
#define fileno _fileno
|
||||
#endif
|
||||
/* Windows' open() doesn't understand Unix permissions */
|
||||
#if defined(HAVE__OPEN)
|
||||
#define open(a, b, c) _open((a), (b))
|
||||
#endif
|
||||
#if defined(HAVE__SNPRINTF)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#if defined(HAVE__STRDUP) && !defined(strdup)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FSEEKO
|
||||
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
|
||||
|
@ -46,57 +101,56 @@
|
|||
#define ftello(s) ((long)ftell((s)))
|
||||
#endif
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
#ifndef HAVE_MKSTEMP
|
||||
int _zip_mkstemp(char *);
|
||||
#define mkstemp _zip_mkstemp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#define _zip_rename(s, t) \
|
||||
(!MoveFileExA((s), (t), \
|
||||
MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
|
||||
|
||||
/* for dup(), close(), etc. */
|
||||
#include <io.h>
|
||||
|
||||
#if !defined(HAVE_OPEN)
|
||||
#if defined(HAVE__OPEN)
|
||||
#define open(a, b, c) _open((a), (b))
|
||||
#if !defined(HAVE_STRCASECMP)
|
||||
#if defined(HAVE__STRICMP)
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SIZEOF_OFF_T == 8
|
||||
#define ZIP_OFF_MAX ZIP_INT64_MAX
|
||||
#elif SIZEOF_OFF_T == 4
|
||||
#define ZIP_OFF_MAX ZIP_INT32_MAX
|
||||
#elif SIZEOF_OFF_T == 2
|
||||
#define ZIP_OFF_MAX ZIP_INT16_MAX
|
||||
#else
|
||||
#define _zip_rename rename
|
||||
#error unsupported size of off_t
|
||||
#endif
|
||||
|
||||
#ifndef strcasecmp
|
||||
# define strcmpi strcasecmp
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#define CENTRAL_MAGIC "PK\1\2"
|
||||
#define LOCAL_MAGIC "PK\3\4"
|
||||
#define EOCD_MAGIC "PK\5\6"
|
||||
#define DATADES_MAGIC "PK\7\8"
|
||||
#define EOCD64LOC_MAGIC "PK\6\7"
|
||||
#define EOCD64_MAGIC "PK\6\6"
|
||||
#define TORRENT_SIG "TORRENTZIPPED-"
|
||||
#define TORRENT_SIG_LEN 14
|
||||
#define TORRENT_CRC_LEN 8
|
||||
#define TORRENT_MEM_LEVEL 8
|
||||
#define CDENTRYSIZE 46u
|
||||
#define LENTRYSIZE 30
|
||||
#undef MAXCOMLEN /* defined as 19 on BSD for max command name */
|
||||
#define MAXCOMLEN 65536
|
||||
#define MAXEXTLEN 65536
|
||||
#define EOCDLEN 22
|
||||
#define CDBUFSIZE (MAXCOMLEN+EOCDLEN)
|
||||
#define EOCD64LOCLEN 20
|
||||
#define EOCD64LEN 56
|
||||
#define CDBUFSIZE (MAXCOMLEN+EOCDLEN+EOCD64LOCLEN)
|
||||
#define BUFSIZE 8192
|
||||
|
||||
#define ZIP_CM_REPLACED_DEFAULT (-2)
|
||||
|
||||
#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT)
|
||||
|
||||
#define ZIP_EF_UTF_8_COMMENT 0x6375
|
||||
#define ZIP_EF_UTF_8_NAME 0x7075
|
||||
#define ZIP_EF_ZIP64 0x0001
|
||||
|
||||
#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_ZIP64)
|
||||
|
||||
|
||||
/* This section contains API that won't materialize like this. It's
|
||||
|
@ -104,20 +158,22 @@ int _zip_mkstemp(char *);
|
|||
|
||||
typedef struct zip_source *(*zip_compression_implementation)(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_uint16_t, int);
|
||||
zip_int32_t, int);
|
||||
typedef struct zip_source *(*zip_encryption_implementation)(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_uint16_t, int,
|
||||
const char *);
|
||||
|
||||
ZIP_EXTERN(zip_compression_implementation) zip_get_compression_implementation(
|
||||
zip_uint16_t);
|
||||
ZIP_EXTERN(zip_encryption_implementation) zip_get_encryption_implementation(
|
||||
zip_uint16_t);
|
||||
zip_compression_implementation _zip_get_compression_implementation(zip_int32_t);
|
||||
zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t);
|
||||
|
||||
|
||||
|
||||
|
||||
/* This API is not final yet, but we need it internally, so it's private for now. */
|
||||
|
||||
const zip_uint8_t *zip_get_extra_field_by_id(struct zip *, int, int, zip_uint16_t, int, zip_uint16_t *);
|
||||
|
||||
/* This section contains API that is of limited use until support for
|
||||
user-supplied compression/encryption implementation is finished.
|
||||
Thus we will keep it private for now. */
|
||||
|
@ -126,40 +182,37 @@ typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *,
|
|||
void *, zip_uint64_t,
|
||||
enum zip_source_cmd);
|
||||
|
||||
ZIP_EXTERN(void) zip_source_close(struct zip_source *);
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_crc(struct zip *, struct zip_source *,
|
||||
int);
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_deflate(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_uint16_t, int);
|
||||
ZIP_EXTERN(void) zip_source_error(struct zip_source *, int *, int *);
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_layered(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_source_layered_callback,
|
||||
void *);
|
||||
ZIP_EXTERN(int) zip_source_open(struct zip_source *);
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_pkware(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_uint16_t, int,
|
||||
const char *);
|
||||
ZIP_EXTERN(zip_int64_t) zip_source_read(struct zip_source *, void *,
|
||||
zip_uint64_t);
|
||||
ZIP_EXTERN(int) zip_source_stat(struct zip_source *, struct zip_stat *);
|
||||
void zip_source_close(struct zip_source *);
|
||||
struct zip_source *zip_source_crc(struct zip *, struct zip_source *,
|
||||
int);
|
||||
struct zip_source *zip_source_deflate(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_int32_t, int);
|
||||
void zip_source_error(struct zip_source *, int *, int *);
|
||||
struct zip_source *zip_source_layered(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_source_layered_callback,
|
||||
void *);
|
||||
int zip_source_open(struct zip_source *);
|
||||
struct zip_source *zip_source_pkware(struct zip *,
|
||||
struct zip_source *,
|
||||
zip_uint16_t, int,
|
||||
const char *);
|
||||
zip_int64_t zip_source_read(struct zip_source *, void *,
|
||||
zip_uint64_t);
|
||||
int zip_source_stat(struct zip_source *, struct zip_stat *);
|
||||
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
|
||||
implement compression/encryption routines. (We should probably
|
||||
rename it to _zip_source_pop.) */
|
||||
|
||||
ZIP_EXTERN(struct zip_source *)zip_source_pop(struct zip_source *);
|
||||
struct zip_source *zip_source_pop(struct zip_source *);
|
||||
|
||||
|
||||
|
||||
/* state of change of a file in zip archive */
|
||||
|
||||
enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED,
|
||||
ZIP_ST_ADDED, ZIP_ST_RENAMED };
|
||||
|
||||
/* error source for layered sources */
|
||||
|
||||
enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
|
||||
|
@ -169,6 +222,28 @@ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
|
|||
#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 */
|
||||
|
||||
|
||||
/* extra fields */
|
||||
#define ZIP_EF_LOCAL ZIP_FL_LOCAL /* include in local header */
|
||||
#define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */
|
||||
#define ZIP_EF_BOTH (ZIP_EF_LOCAL|ZIP_EF_CENTRAL) /* include in both */
|
||||
|
||||
#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */
|
||||
|
||||
#define ZIP_FL_ENCODING_ALL (ZIP_FL_ENC_GUESS|ZIP_FL_ENC_CP437|ZIP_FL_ENC_UTF_8)
|
||||
|
||||
|
||||
/* encoding type */
|
||||
enum zip_encoding_type {
|
||||
ZIP_ENCODING_UNKNOWN, /* not yet analyzed */
|
||||
ZIP_ENCODING_ASCII, /* plain ASCII */
|
||||
ZIP_ENCODING_UTF8_KNOWN, /* is UTF-8 */
|
||||
ZIP_ENCODING_UTF8_GUESSED, /* possibly UTF-8 */
|
||||
ZIP_ENCODING_CP437, /* Code Page 437 */
|
||||
ZIP_ENCODING_ERROR /* should be UTF-8 but isn't */
|
||||
};
|
||||
|
||||
/* error information */
|
||||
|
||||
|
@ -181,25 +256,29 @@ struct zip_error {
|
|||
/* zip archive, part of API */
|
||||
|
||||
struct zip {
|
||||
char *zn; /* file name */
|
||||
FILE *zp; /* file */
|
||||
struct zip_error error; /* error information */
|
||||
char *zn; /* file name */
|
||||
FILE *zp; /* file */
|
||||
unsigned int open_flags; /* flags passed to zip_open */
|
||||
struct zip_error error; /* error information */
|
||||
|
||||
unsigned int flags; /* archive global flags */
|
||||
unsigned int ch_flags; /* changed archive global flags */
|
||||
unsigned int flags; /* archive global flags */
|
||||
unsigned int ch_flags; /* changed archive global flags */
|
||||
|
||||
char *default_password; /* password used when no other supplied */
|
||||
char *default_password; /* password used when no other supplied */
|
||||
|
||||
struct zip_cdir *cdir; /* central directory */
|
||||
char *ch_comment; /* changed archive comment */
|
||||
int ch_comment_len; /* length of changed zip archive
|
||||
* comment, -1 if unchanged */
|
||||
zip_uint64_t nentry; /* number of entries */
|
||||
zip_uint64_t nentry_alloc; /* number of entries allocated */
|
||||
struct zip_entry *entry; /* entries */
|
||||
int nfile; /* number of opened files within archive */
|
||||
int nfile_alloc; /* number of files allocated */
|
||||
struct zip_file **file; /* opened files within archive */
|
||||
struct zip_string *comment_orig; /* archive comment */
|
||||
struct zip_string *comment_changes; /* changed archive comment */
|
||||
int comment_changed; /* whether archive comment was changed */
|
||||
|
||||
zip_uint64_t nentry; /* number of entries */
|
||||
zip_uint64_t nentry_alloc; /* number of entries allocated */
|
||||
struct zip_entry *entry; /* entries */
|
||||
|
||||
unsigned int nfile; /* number of opened files within archive */
|
||||
unsigned int nfile_alloc; /* number of files allocated */
|
||||
struct zip_file **file; /* opened files within archive */
|
||||
|
||||
char *tempdir; /* custom temp dir (needed e.g. for OS X sandboxing) */
|
||||
};
|
||||
|
||||
/* file in zip archive, part of API */
|
||||
|
@ -213,37 +292,52 @@ struct zip_file {
|
|||
|
||||
/* zip archive directory entry (central or local) */
|
||||
|
||||
#define ZIP_DIRENT_COMP_METHOD 0x0001u
|
||||
#define ZIP_DIRENT_FILENAME 0x0002u
|
||||
#define ZIP_DIRENT_COMMENT 0x0004u
|
||||
#define ZIP_DIRENT_EXTRA_FIELD 0x0008u
|
||||
#define ZIP_DIRENT_ALL 0xffffu
|
||||
|
||||
struct zip_dirent {
|
||||
unsigned short version_madeby; /* (c) version of creator */
|
||||
unsigned short version_needed; /* (cl) version needed to extract */
|
||||
unsigned short bitflags; /* (cl) general purpose bit flag */
|
||||
unsigned short comp_method; /* (cl) compression method used */
|
||||
time_t last_mod; /* (cl) time of last modification */
|
||||
unsigned int crc; /* (cl) CRC-32 of uncompressed data */
|
||||
unsigned int comp_size; /* (cl) size of commpressed data */
|
||||
unsigned int uncomp_size; /* (cl) size of uncommpressed data */
|
||||
char *filename; /* (cl) file name (NUL-terminated) */
|
||||
unsigned short filename_len; /* (cl) length of filename (w/o NUL) */
|
||||
char *extrafield; /* (cl) extra field */
|
||||
unsigned short extrafield_len; /* (cl) length of extra field */
|
||||
char *comment; /* (c) file comment */
|
||||
unsigned short comment_len; /* (c) length of file comment */
|
||||
unsigned short disk_number; /* (c) disk number start */
|
||||
unsigned short int_attrib; /* (c) internal file attributes */
|
||||
unsigned int ext_attrib; /* (c) external file attributes */
|
||||
unsigned int offset; /* (c) offset of local header */
|
||||
zip_uint32_t changed;
|
||||
int local_extra_fields_read; /* whether we already read in local header extra fields */
|
||||
int cloned; /* wether this instance is cloned, and thus shares non-changed strings */
|
||||
|
||||
zip_uint16_t version_madeby; /* (c) version of creator */
|
||||
zip_uint16_t version_needed; /* (cl) version needed to extract */
|
||||
zip_uint16_t bitflags; /* (cl) general purpose bit flag */
|
||||
zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */
|
||||
time_t last_mod; /* (cl) time of last modification */
|
||||
zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */
|
||||
zip_uint64_t comp_size; /* (cl) size of compressed data */
|
||||
zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */
|
||||
struct zip_string *filename; /* (cl) file name (NUL-terminated) */
|
||||
struct zip_extra_field *extra_fields; /* (cl) extra fields, parsed */
|
||||
struct zip_string *comment; /* (c) file comment */
|
||||
zip_uint32_t disk_number; /* (c) disk number start */
|
||||
zip_uint16_t int_attrib; /* (c) internal file attributes */
|
||||
zip_uint32_t ext_attrib; /* (c) external file attributes */
|
||||
zip_uint64_t offset; /* (c) offset of local header */
|
||||
};
|
||||
|
||||
/* zip archive central directory */
|
||||
|
||||
struct zip_cdir {
|
||||
struct zip_dirent *entry; /* directory entries */
|
||||
int nentry; /* number of entries */
|
||||
struct zip_entry *entry; /* directory entries */
|
||||
zip_uint64_t nentry; /* number of entries */
|
||||
zip_uint64_t nentry_alloc; /* number of entries allocated */
|
||||
|
||||
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 */
|
||||
off_t size; /* size of central directory */
|
||||
off_t offset; /* offset of central directory in file */
|
||||
struct zip_string *comment; /* zip archive comment */
|
||||
};
|
||||
|
||||
struct zip_extra_field {
|
||||
struct zip_extra_field *next;
|
||||
zip_flags_t flags; /* in local/central header */
|
||||
zip_uint16_t id; /* header id */
|
||||
zip_uint16_t size; /* data size */
|
||||
zip_uint8_t *data;
|
||||
};
|
||||
|
||||
|
||||
|
@ -262,13 +356,31 @@ struct zip_source {
|
|||
/* entry in zip archive directory */
|
||||
|
||||
struct zip_entry {
|
||||
enum zip_state state;
|
||||
struct zip_dirent *orig;
|
||||
struct zip_dirent *changes;
|
||||
struct zip_source *source;
|
||||
char *ch_filename;
|
||||
char *ch_extra;
|
||||
int ch_extra_len;
|
||||
char *ch_comment;
|
||||
int ch_comment_len;
|
||||
int deleted;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* file or archive comment, or filename */
|
||||
|
||||
struct zip_string {
|
||||
zip_uint8_t *raw; /* raw string */
|
||||
zip_uint16_t length; /* length of raw string */
|
||||
enum zip_encoding_type encoding; /* autorecognized encoding */
|
||||
zip_uint8_t *converted; /* autoconverted string */
|
||||
zip_uint32_t converted_length; /* length of converted */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* which files to write, and in which order (name is for torrentzip sorting) */
|
||||
|
||||
struct zip_filelist {
|
||||
zip_uint64_t idx;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
|
@ -279,66 +391,111 @@ extern const int _zip_err_type[];
|
|||
|
||||
|
||||
|
||||
#define ZIP_ENTRY_DATA_CHANGED(x) \
|
||||
((x)->state == ZIP_ST_REPLACED \
|
||||
|| (x)->state == ZIP_ST_ADDED)
|
||||
#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f)))
|
||||
|
||||
#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL)
|
||||
|
||||
#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
|
||||
|
||||
|
||||
|
||||
zip_int64_t _zip_add_entry(struct zip *);
|
||||
|
||||
int _zip_cdir_compute_crc(struct zip *, uLong *);
|
||||
void _zip_cdir_free(struct zip_cdir *);
|
||||
int _zip_cdir_grow(struct zip_cdir *, int, struct zip_error *);
|
||||
struct zip_cdir *_zip_cdir_new(int, struct zip_error *);
|
||||
int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *);
|
||||
int _zip_cdir_grow(struct zip_cdir *, zip_uint64_t, struct zip_error *);
|
||||
struct zip_cdir *_zip_cdir_new(zip_uint64_t, struct zip_error *);
|
||||
zip_int64_t _zip_cdir_write(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *);
|
||||
|
||||
struct zip_dirent *_zip_dirent_clone(const struct zip_dirent *);
|
||||
void _zip_dirent_free(struct zip_dirent *);
|
||||
void _zip_dirent_finalize(struct zip_dirent *);
|
||||
void _zip_dirent_init(struct zip_dirent *);
|
||||
int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **,
|
||||
zip_uint32_t *, int, struct zip_error *);
|
||||
int _zip_dirent_needs_zip64(const struct zip_dirent *, zip_flags_t);
|
||||
struct zip_dirent *_zip_dirent_new(void);
|
||||
int _zip_dirent_read(struct zip_dirent *, FILE *, const unsigned char **,
|
||||
zip_uint64_t *, int, struct zip_error *);
|
||||
zip_int32_t _zip_dirent_size(FILE *, zip_uint16_t, struct zip_error *);
|
||||
void _zip_dirent_torrent_normalize(struct zip_dirent *);
|
||||
int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *);
|
||||
int _zip_dirent_write(struct zip_dirent *, FILE *, zip_flags_t, struct zip_error *);
|
||||
|
||||
void _zip_entry_free(struct zip_entry *);
|
||||
void _zip_entry_init(struct zip *, int);
|
||||
struct zip_entry *_zip_entry_new(struct zip *);
|
||||
struct zip_extra_field *_zip_ef_clone(const struct zip_extra_field *, struct zip_error *);
|
||||
struct zip_extra_field *_zip_ef_delete_by_id(struct zip_extra_field *, zip_uint16_t, zip_uint16_t, zip_flags_t);
|
||||
void _zip_ef_free(struct zip_extra_field *);
|
||||
const zip_uint8_t *_zip_ef_get_by_id(const struct zip_extra_field *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, struct zip_error *);
|
||||
struct zip_extra_field *_zip_ef_merge(struct zip_extra_field *, struct zip_extra_field *);
|
||||
struct zip_extra_field *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t);
|
||||
struct zip_extra_field *_zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *);
|
||||
struct zip_extra_field *_zip_ef_remove_internal(struct zip_extra_field *);
|
||||
zip_uint16_t _zip_ef_size(const struct zip_extra_field *, zip_flags_t);
|
||||
void _zip_ef_write(const struct zip_extra_field *, zip_flags_t, FILE *);
|
||||
|
||||
void _zip_entry_finalize(struct zip_entry *);
|
||||
void _zip_entry_init(struct zip_entry *);
|
||||
|
||||
void _zip_error_clear(struct zip_error *);
|
||||
void _zip_error_copy(struct zip_error *, struct zip_error *);
|
||||
void _zip_error_copy(struct zip_error *, const struct zip_error *);
|
||||
void _zip_error_fini(struct zip_error *);
|
||||
void _zip_error_get(struct zip_error *, int *, int *);
|
||||
void _zip_error_get(const struct zip_error *, int *, int *);
|
||||
void _zip_error_init(struct zip_error *);
|
||||
void _zip_error_set(struct zip_error *, int, int);
|
||||
void _zip_error_set_from_source(struct zip_error *, struct zip_source *);
|
||||
const char *_zip_error_strerror(struct zip_error *);
|
||||
|
||||
const zip_uint8_t *_zip_extract_extra_field_by_id(struct zip_error *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *);
|
||||
|
||||
int _zip_file_extra_field_prepare_for_change(struct zip *, zip_uint64_t);
|
||||
int _zip_file_fillbuf(void *, size_t, struct zip_file *);
|
||||
unsigned int _zip_file_get_offset(struct zip *, int);
|
||||
zip_uint64_t _zip_file_get_offset(const struct zip *, zip_uint64_t, struct zip_error *);
|
||||
|
||||
int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *);
|
||||
|
||||
struct zip *_zip_open(const char *, FILE *, int, int, int *);
|
||||
struct zip_dirent *_zip_get_dirent(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *);
|
||||
|
||||
enum zip_encoding_type _zip_guess_encoding(struct zip_string *, enum zip_encoding_type);
|
||||
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 *, unsigned int, int *);
|
||||
|
||||
int _zip_read_local_ef(struct zip *, zip_uint64_t);
|
||||
|
||||
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, zip_flags_t,
|
||||
zip_uint64_t, zip_uint64_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_string_equal(const struct zip_string *, const struct zip_string *);
|
||||
void _zip_string_free(struct zip_string *);
|
||||
zip_uint32_t _zip_string_crc32(const struct zip_string *);
|
||||
const zip_uint8_t *_zip_string_get(struct zip_string *, zip_uint32_t *, zip_flags_t, struct zip_error *);
|
||||
zip_uint16_t _zip_string_length(const struct zip_string *);
|
||||
struct zip_string *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *);
|
||||
void _zip_string_write(const struct zip_string *, FILE *);
|
||||
|
||||
int _zip_changed(const struct zip *, zip_uint64_t *);
|
||||
const char *_zip_get_name(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *);
|
||||
int _zip_local_header_read(struct zip *, int);
|
||||
void *_zip_memdup(const void *, size_t, struct zip_error *);
|
||||
int _zip_name_locate(struct zip *, const char *, int, struct zip_error *);
|
||||
zip_int64_t _zip_name_locate(struct zip *, const char *, zip_flags_t, struct zip_error *);
|
||||
struct zip *_zip_new(struct zip_error *);
|
||||
unsigned short _zip_read2(unsigned char **);
|
||||
unsigned int _zip_read4(unsigned char **);
|
||||
zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *,
|
||||
struct zip_source *);
|
||||
int _zip_set_name(struct zip *, zip_uint64_t, const char *);
|
||||
void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
|
||||
zip_uint16_t _zip_read2(const zip_uint8_t **);
|
||||
zip_uint32_t _zip_read4(const zip_uint8_t **);
|
||||
zip_uint64_t _zip_read8(const zip_uint8_t **);
|
||||
zip_uint8_t *_zip_read_data(const zip_uint8_t **, FILE *, size_t, int, struct zip_error *);
|
||||
zip_int64_t _zip_file_replace(struct zip *, zip_uint64_t, const char *, struct zip_source *, zip_flags_t);
|
||||
int _zip_set_name(struct zip *, zip_uint64_t, const char *, zip_flags_t);
|
||||
void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *);
|
||||
int _zip_unchange(struct zip *, zip_uint64_t, int);
|
||||
void _zip_unchange_data(struct zip_entry *);
|
||||
|
||||
void _zip_poke4(zip_uint32_t, zip_uint8_t **);
|
||||
void _zip_poke8(zip_uint64_t, zip_uint8_t **);
|
||||
void _zip_write2(zip_uint16_t, FILE *);
|
||||
void _zip_write4(zip_uint32_t, FILE *);
|
||||
void _zip_write8(zip_uint64_t, FILE *);
|
||||
|
||||
|
||||
#endif /* zipint.h */
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "ext/pcre/php_pcre.h"
|
||||
#include "ext/standard/php_filestat.h"
|
||||
#include "php_zip.h"
|
||||
#include "lib/zip.h"
|
||||
#include "lib/zipint.h"
|
||||
|
||||
/* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
|
||||
static PHP_NAMED_FUNCTION(zif_zip_open);
|
||||
|
@ -53,6 +51,24 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_close);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if PHP_VERSION_ID < 50400
|
||||
#define ARG_PATH "s"
|
||||
#define KEY_ARG_DC
|
||||
#define KEY_ARG_CC
|
||||
#else
|
||||
#define ARG_PATH "p"
|
||||
#define KEY_ARG_DC , const zend_literal *key
|
||||
#define KEY_ARG_CC , key
|
||||
#endif
|
||||
|
||||
#if PHP_VERSION_ID < 50500
|
||||
#define TYPE_ARG_DC
|
||||
#define TYPE_ARG_CC
|
||||
#else
|
||||
#define TYPE_ARG_DC , int type
|
||||
#define TYPE_ARG_CC , type
|
||||
#endif
|
||||
|
||||
/* {{{ Resource le */
|
||||
static int le_zip_dir;
|
||||
#define le_zip_dir_name "Zip Directory"
|
||||
|
@ -299,7 +315,6 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
|
|||
char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
struct zip_source *zs;
|
||||
int cur_idx;
|
||||
char resolved_path[MAXPATHLEN];
|
||||
zval exists_flag;
|
||||
|
||||
|
@ -321,25 +336,11 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
|
|||
if (!zs) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cur_idx = zip_name_locate(za, (const char *)entry_name, 0);
|
||||
/* TODO: fix _zip_replace */
|
||||
if (cur_idx<0) {
|
||||
/* reset the error */
|
||||
if (za->error.str) {
|
||||
_zip_error_fini(&za->error);
|
||||
}
|
||||
_zip_error_init(&za->error);
|
||||
} else {
|
||||
if (zip_delete(za, cur_idx) == -1) {
|
||||
zip_source_free(zs);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (zip_add(za, entry_name, zs) == -1) {
|
||||
if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) {
|
||||
zip_source_free(zs);
|
||||
return -1;
|
||||
} else {
|
||||
zip_error_clear(za);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -780,7 +781,11 @@ static const zend_function_entry zip_functions[] = {
|
|||
PHP_FE(zip_entry_name, arginfo_zip_entry_name)
|
||||
PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize)
|
||||
PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod)
|
||||
#ifdef PHP_FE_END
|
||||
PHP_FE_END
|
||||
#else
|
||||
{NULL,NULL,NULL}
|
||||
#endif
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
|
@ -869,7 +874,7 @@ static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zv
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member TYPE_ARG_DC KEY_ARG_DC TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_zip_object *obj;
|
||||
zval tmp_member;
|
||||
|
@ -884,24 +889,27 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type,
|
|||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
#if PHP_VERSION_ID >= 50400
|
||||
key = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = FAILURE;
|
||||
obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
if (obj->prop_handler != NULL) {
|
||||
#if PHP_VERSION_ID >= 50400
|
||||
if (key) {
|
||||
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ret == FAILURE) {
|
||||
std_hnd = zend_get_std_object_handlers();
|
||||
retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
|
||||
retval = std_hnd->get_property_ptr_ptr(object, member TYPE_ARG_CC KEY_ARG_CC TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (member == &tmp_member) {
|
||||
|
@ -911,7 +919,7 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type,
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zval* php_zip_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
static zval* php_zip_read_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_zip_object *obj;
|
||||
zval tmp_member;
|
||||
|
@ -925,18 +933,21 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z
|
|||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
#if PHP_VERSION_ID >= 50400
|
||||
key = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = FAILURE;
|
||||
obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
if (obj->prop_handler != NULL) {
|
||||
#if PHP_VERSION_ID >= 50400
|
||||
if (key) {
|
||||
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == SUCCESS) {
|
||||
|
@ -949,7 +960,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z
|
|||
}
|
||||
} else {
|
||||
std_hnd = zend_get_std_object_handlers();
|
||||
retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
|
||||
retval = std_hnd->read_property(object, member, type KEY_ARG_CC TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (member == &tmp_member) {
|
||||
|
@ -959,7 +970,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int php_zip_has_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||
static int php_zip_has_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_zip_object *obj;
|
||||
zval tmp_member;
|
||||
|
@ -972,18 +983,21 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend
|
|||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
member = &tmp_member;
|
||||
#if PHP_VERSION_ID >= 50400
|
||||
key = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = FAILURE;
|
||||
obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC);
|
||||
|
||||
if (obj->prop_handler != NULL) {
|
||||
#if PHP_VERSION_ID >= 50400
|
||||
if (key) {
|
||||
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == SUCCESS) {
|
||||
|
@ -1005,7 +1019,7 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend
|
|||
zval_ptr_dtor(&tmp);
|
||||
} else {
|
||||
std_hnd = zend_get_std_object_handlers();
|
||||
retval = std_hnd->has_property(object, member, type, key TSRMLS_CC);
|
||||
retval = std_hnd->has_property(object, member, type KEY_ARG_CC TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (member == &tmp_member) {
|
||||
|
@ -1059,7 +1073,8 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */
|
|||
}
|
||||
if (intern->za) {
|
||||
if (zip_close(intern->za) != 0) {
|
||||
_zip_free(intern->za);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context");
|
||||
return;
|
||||
}
|
||||
intern->za = NULL;
|
||||
}
|
||||
|
@ -1096,6 +1111,9 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */
|
|||
|
||||
static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
#if PHP_VERSION_ID < 50400
|
||||
zval *tmp;
|
||||
#endif
|
||||
ze_zip_object *intern;
|
||||
zend_object_value retval;
|
||||
|
||||
|
@ -1116,8 +1134,13 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_
|
|||
intern->zo.ce = class_type;
|
||||
#endif
|
||||
|
||||
object_properties_init(&intern->zo, class_type);
|
||||
|
||||
#if PHP_VERSION_ID < 50400
|
||||
zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,
|
||||
(void *) &tmp, sizeof(zval *));
|
||||
#else
|
||||
object_properties_init(&intern->zo, class_type);
|
||||
#endif
|
||||
retval.handle = zend_objects_store_put(intern,
|
||||
NULL,
|
||||
(zend_objects_free_object_storage_t) php_zip_object_free_storage,
|
||||
|
@ -1140,7 +1163,7 @@ static void php_zip_free_dir(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|||
if (zip_int) {
|
||||
if (zip_int->za) {
|
||||
if (zip_close(zip_int->za) != 0) {
|
||||
_zip_free(zip_int->za);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context");
|
||||
}
|
||||
zip_int->za = NULL;
|
||||
}
|
||||
|
@ -1159,13 +1182,7 @@ static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|||
|
||||
if (zr_rsrc) {
|
||||
if (zr_rsrc->zf) {
|
||||
if (zr_rsrc->zf->za) {
|
||||
zip_fclose(zr_rsrc->zf);
|
||||
} else {
|
||||
if (zr_rsrc->zf->src)
|
||||
zip_source_free(zr_rsrc->zf->src);
|
||||
free(zr_rsrc->zf);
|
||||
}
|
||||
zip_fclose(zr_rsrc->zf);
|
||||
zr_rsrc->zf = NULL;
|
||||
}
|
||||
efree(zr_rsrc);
|
||||
|
@ -1195,7 +1212,7 @@ zend_module_entry zip_module_entry = {
|
|||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(zip),
|
||||
PHP_ZIP_VERSION_STRING,
|
||||
PHP_ZIP_VERSION,
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
@ -1215,7 +1232,7 @@ static PHP_NAMED_FUNCTION(zif_zip_open)
|
|||
zip_rsrc *rsrc_int;
|
||||
int err = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1498,7 +1515,7 @@ static ZIPARCHIVE_METHOD(open)
|
|||
zval *this = getThis();
|
||||
ze_zip_object *ze_obj = NULL;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &flags) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &filename, &filename_len, &flags) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1523,7 +1540,8 @@ static ZIPARCHIVE_METHOD(open)
|
|||
if (ze_obj->za) {
|
||||
/* we already have an opened zip, free it */
|
||||
if (zip_close(ze_obj->za) != 0) {
|
||||
_zip_free(ze_obj->za);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ze_obj->za = NULL;
|
||||
}
|
||||
|
@ -1543,6 +1561,38 @@ static ZIPARCHIVE_METHOD(open)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource ZipArchive::setPassword(string password)
|
||||
Set the password for the active archive */
|
||||
static ZIPARCHIVE_METHOD(setPassword)
|
||||
{
|
||||
struct zip *intern;
|
||||
zval *this = getThis();
|
||||
char *password;
|
||||
int password_len;
|
||||
|
||||
if (!this) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &password, &password_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (password_len < 1) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
int res = zip_set_default_password(intern, (const char *)password);
|
||||
if (res == 0) {
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool ZipArchive::close()
|
||||
close the zip archive */
|
||||
static ZIPARCHIVE_METHOD(close)
|
||||
|
@ -1552,7 +1602,7 @@ static ZIPARCHIVE_METHOD(close)
|
|||
ze_zip_object *ze_obj;
|
||||
|
||||
if (!this) {
|
||||
RETURN_FALSE;
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
@ -1560,7 +1610,7 @@ static ZIPARCHIVE_METHOD(close)
|
|||
ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC);
|
||||
|
||||
if (zip_close(intern)) {
|
||||
RETURN_FALSE;
|
||||
zip_discard(intern);
|
||||
}
|
||||
|
||||
efree(ze_obj->filename);
|
||||
|
@ -1637,6 +1687,7 @@ static ZIPARCHIVE_METHOD(addEmptyDir)
|
|||
if (zip_add_dir(intern, (const char *)s) == -1) {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
zip_error_clear(intern);
|
||||
RETVAL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1654,7 +1705,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
|
|||
char *path = NULL;
|
||||
char *remove_path = NULL;
|
||||
char *add_path = NULL;
|
||||
int pattern_len, add_path_len = 0, remove_path_len = 0, path_len = 0;
|
||||
int pattern_len, add_path_len, remove_path_len = 0, path_len = 0;
|
||||
long remove_all_path = 0;
|
||||
long flags = 0;
|
||||
zval *options = NULL;
|
||||
|
@ -1667,12 +1718,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
|
|||
ZIP_FROM_OBJECT(intern, this);
|
||||
/* 1 == glob, 2==pcre */
|
||||
if (type == 1) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la",
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|la",
|
||||
&pattern, &pattern_len, &flags, &options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa",
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sa",
|
||||
&pattern, &pattern_len, &path, &path_len, &options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
@ -1703,13 +1754,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
|
|||
zval **zval_file = NULL;
|
||||
|
||||
for (i = 0; i < found; i++) {
|
||||
char *file, *file_stripped, *entry_name;
|
||||
char *file_stripped, *entry_name;
|
||||
size_t entry_name_len, file_stripped_len;
|
||||
char entry_name_buf[MAXPATHLEN];
|
||||
char *basename = NULL;
|
||||
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(return_value), i, (void **) &zval_file) == SUCCESS) {
|
||||
file = Z_STRVAL_PP(zval_file);
|
||||
if (remove_all_path) {
|
||||
php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0,
|
||||
&basename, (size_t *)&file_stripped_len TSRMLS_CC);
|
||||
|
@ -1786,7 +1836,7 @@ static ZIPARCHIVE_METHOD(addFile)
|
|||
|
||||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sll",
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sll",
|
||||
&filename, &filename_len, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
@ -1856,16 +1906,18 @@ static ZIPARCHIVE_METHOD(addFromString)
|
|||
/* TODO: fix _zip_replace */
|
||||
if (cur_idx >= 0) {
|
||||
if (zip_delete(intern, cur_idx) == -1) {
|
||||
goto fail;
|
||||
zip_source_free(zs);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (zip_add(intern, name, zs) != -1) {
|
||||
if (zip_add(intern, name, zs) == -1) {
|
||||
zip_source_free(zs);
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
zip_error_clear(intern);
|
||||
RETURN_TRUE;
|
||||
}
|
||||
fail:
|
||||
zip_source_free(zs);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -1886,7 +1938,7 @@ static ZIPARCHIVE_METHOD(statName)
|
|||
|
||||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l",
|
||||
&name, &name_len, &flags) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
@ -1942,7 +1994,7 @@ static ZIPARCHIVE_METHOD(locateName)
|
|||
|
||||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l",
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l",
|
||||
&name, &name_len, &flags) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
@ -2522,7 +2574,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
|
|||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
||||
if (type == 1) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|ll", &filename, &filename_len, &len, &flags) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb);
|
||||
|
@ -2598,7 +2650,7 @@ static ZIPARCHIVE_METHOD(getStream)
|
|||
|
||||
ZIP_FROM_OBJECT(intern, this);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2621,6 +2673,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
|
|||
ZEND_ARG_INFO(0, flags)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setpassword, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, password)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
@ -2733,6 +2789,7 @@ ZEND_END_ARG_INFO()
|
|||
/* {{{ ze_zip_object_class_functions */
|
||||
static const zend_function_entry zip_class_functions[] = {
|
||||
ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
|
||||
ZIPARCHIVE_ME(setPassword, arginfo_ziparchive_setpassword, ZEND_ACC_PUBLIC)
|
||||
ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
|
||||
ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
|
||||
ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
|
||||
|
@ -2875,7 +2932,7 @@ static PHP_MINFO_FUNCTION(zip)
|
|||
|
||||
php_info_print_table_row(2, "Zip", "enabled");
|
||||
php_info_print_table_row(2, "Extension Version","$Id$");
|
||||
php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING);
|
||||
php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION);
|
||||
php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
|
||||
|
||||
php_info_print_table_end();
|
||||
|
|
|
@ -28,9 +28,17 @@ extern zend_module_entry zip_module_entry;
|
|||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBZIP)
|
||||
#include <zip.h>
|
||||
#else
|
||||
#include "lib/zip.h"
|
||||
#endif
|
||||
|
||||
#define PHP_ZIP_VERSION_STRING "1.11.0"
|
||||
#ifndef ZIP_OVERWRITE
|
||||
#define ZIP_OVERWRITE ZIP_TRUNCATE
|
||||
#endif
|
||||
|
||||
#define PHP_ZIP_VERSION "1.12.3"
|
||||
|
||||
#if ((PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION >= 6)
|
||||
# define PHP_ZIP_USE_OO 1
|
||||
|
@ -67,8 +75,9 @@ typedef struct _ze_zip_read_rsrc {
|
|||
} zip_read_rsrc;
|
||||
|
||||
#ifdef PHP_ZIP_USE_OO
|
||||
#define ZIPARCHIVE_ME(name, arg_info, flags) ZEND_FENTRY(name, c_ziparchive_ ##name, arg_info, flags)
|
||||
#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_##name)
|
||||
#define ZIPARCHIVE_ME(name, arg_info, flags) {#name, c_ziparchive_ ##name, arg_info,(zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
|
||||
#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_ ##name)
|
||||
|
||||
|
||||
/* Extends zend object */
|
||||
typedef struct _ze_zip_object {
|
||||
|
|
16
ext/zip/tests/bug38943.inc
Normal file
16
ext/zip/tests/bug38943.inc
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
class myZip extends ZipArchive {
|
||||
private $test = 0;
|
||||
public $testp = 1;
|
||||
private $testarray = array();
|
||||
|
||||
public function __construct() {
|
||||
$this->testarray[] = 1;
|
||||
var_dump($this->testarray);
|
||||
}
|
||||
}
|
||||
|
||||
$z = new myZip;
|
||||
$z->testp = "foobar";
|
||||
var_dump($z);
|
||||
|
38
ext/zip/tests/bug38943_2.phpt
Normal file
38
ext/zip/tests/bug38943_2.phpt
Normal file
|
@ -0,0 +1,38 @@
|
|||
--TEST--
|
||||
#38943, properties in extended class cannot be set (5.3)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
/* $Id: bug38943_2.phpt 271800 2008-12-24 11:28:25Z pajoye $ */
|
||||
if(!extension_loaded('zip')) die('skip');
|
||||
if (version_compare(PHP_VERSION, "5.3", "<")) die('skip test for5.3+ only');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
include 'bug38943.inc';
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
object(myZip)#1 (%d) {
|
||||
["test":"myZip":private]=>
|
||||
int(0)
|
||||
["testp"]=>
|
||||
string(6) "foobar"
|
||||
["testarray":"myZip":private]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
["status"]=>
|
||||
int(0)
|
||||
["statusSys"]=>
|
||||
int(0)
|
||||
["numFiles"]=>
|
||||
int(0)
|
||||
["filename"]=>
|
||||
string(0) ""
|
||||
["comment"]=>
|
||||
string(0) ""
|
||||
}
|
43
ext/zip/tests/doubleclose.phpt
Normal file
43
ext/zip/tests/doubleclose.phpt
Normal file
|
@ -0,0 +1,43 @@
|
|||
--TEST--
|
||||
close() called twice
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded('zip')) die('skip');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo "Procedural\n";
|
||||
$zip = zip_open(dirname(__FILE__) . '/test.zip');
|
||||
if (!is_resource($zip)) {
|
||||
die("Failure");
|
||||
}
|
||||
var_dump(zip_close($zip));
|
||||
var_dump(zip_close($zip));
|
||||
|
||||
echo "Object\n";
|
||||
$zip = new ZipArchive();
|
||||
if (!$zip->open(dirname(__FILE__) . '/test.zip')) {
|
||||
die('Failure');
|
||||
}
|
||||
if ($zip->status == ZIPARCHIVE::ER_OK) {
|
||||
var_dump($zip->close());
|
||||
var_dump($zip->close());
|
||||
} else {
|
||||
die("Failure");
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Procedural
|
||||
NULL
|
||||
|
||||
Warning: zip_close(): %i is not a valid Zip Directory resource in %s
|
||||
bool(false)
|
||||
Object
|
||||
bool(true)
|
||||
|
||||
Warning: ZipArchive::close(): Invalid or uninitialized Zip object in %s
|
||||
bool(false)
|
||||
Done
|
24
ext/zip/tests/zip_entry_close.phpt
Normal file
24
ext/zip/tests/zip_entry_close.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
zip_entry_close() function: simple and double call
|
||||
--SKIPIF--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
if(!extension_loaded('zip')) die('skip');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$zip = zip_open(dirname(__FILE__)."/test_procedural.zip");
|
||||
$entry = zip_read($zip);
|
||||
echo "entry_open: "; var_dump(zip_entry_open($zip, $entry, "r"));
|
||||
echo "entry_close: "; var_dump(zip_entry_close($entry));
|
||||
echo "entry_close: "; var_dump(zip_entry_close($entry));
|
||||
zip_close($zip);
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
entry_open: bool(true)
|
||||
entry_close: bool(true)
|
||||
entry_close:
|
||||
Warning: zip_entry_close(): %d is not a valid Zip Entry resource in %s
|
||||
bool(false)
|
||||
Done
|
|
@ -1,3 +1,21 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Piere-Alain Joye <pierre@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
|
@ -6,8 +24,6 @@
|
|||
#if HAVE_ZIP
|
||||
#ifdef ZEND_ENGINE_2
|
||||
|
||||
#include "lib/zip.h"
|
||||
|
||||
#include "php_streams.h"
|
||||
#include "ext/standard/file.h"
|
||||
#include "ext/standard/php_string.h"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue