Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions azure/i386/job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ jobs:
- script: make -j$(/usr/bin/nproc) >/dev/null
displayName: 'Make Build'
- script: |
set -e
sudo make install
sudo mkdir /etc/php.d
sudo chmod 777 /etc/php.d
Expand All @@ -79,6 +80,8 @@ jobs:
echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini
displayName: 'Install Build'
- script: |
set -e
sudo service mysql start
mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test"
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
sudo -u postgres psql -c "CREATE DATABASE test;"
Expand Down
1 change: 1 addition & 0 deletions azure/install.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
steps:
- script: |
set -e
sudo make install
sudo mkdir /etc/php.d
sudo chmod 777 /etc/php.d
Expand Down
2 changes: 2 additions & 0 deletions azure/job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
displayName: 'Make Build'
- template: install.yml
- script: |
set -e
sudo service mysql start
mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test"
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
sudo -u postgres psql -c "CREATE DATABASE test;"
Expand Down
1 change: 1 addition & 0 deletions azure/msan_job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini
displayName: 'Install Build'
- script: |
sudo service mysql start
mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test"
displayName: 'Setup'
- template: test.yml
Expand Down
12 changes: 6 additions & 6 deletions ext/standard/tests/file/bug52820.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ if (!function_exists('zend_leak_variable'))
/* unfortunately no standard function does a cast to FILE*, so we need
* curl to test this */
if (!extension_loaded("curl")) exit("skip curl extension not loaded");
$handle=curl_init('http://127.0.0.1:37349/');
$handle=curl_init('file:///i_dont_exist/');
curl_setopt($handle, CURLOPT_VERBOSE, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
if (!@curl_setopt($handle, CURLOPT_STDERR, fopen("php://memory", "w+")))
die("skip fopencookie not supported on this platform");
--FILE--
<?php
function do_stuff($url) {
$handle=curl_init('http://127.0.0.1:37349/');
$handle=curl_init('file:///i_dont_exist/');
curl_setopt($handle, CURLOPT_VERBOSE, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_STDERR, $o = fopen($url, "w+"));
Expand All @@ -42,22 +42,22 @@ echo "\nDone.\n";
--EXPECTF--
temp stream (close after):
About to rewind!
* %ATrying 127.0.0.1...%AConnection refused%A
* Couldn't open file /i_dont_exist/
* Closing connection%A%d

memory stream (close after):
About to rewind!
* %ATrying 127.0.0.1...%AConnection refused%A
* Couldn't open file /i_dont_exist/
* Closing connection%A%d

temp stream (leak):
About to rewind!
* %ATrying 127.0.0.1...%AConnection refused%A
* Couldn't open file /i_dont_exist/
* Closing connection%A%d

memory stream (leak):
About to rewind!
* %ATrying 127.0.0.1...%AConnection refused%A
* Couldn't open file /i_dont_exist/
* Closing connection%A%d

Done.
119 changes: 87 additions & 32 deletions ext/zip/php_zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,18 +331,60 @@ static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t fil
}
/* }}} */

static int php_zip_parse_options(zval *options, zend_long *remove_all_path,
char **remove_path, size_t *remove_path_len,
char **add_path, size_t *add_path_len,
zend_long *flags
) /* {{{ */
typedef struct {
zend_long remove_all_path;
char *remove_path;
size_t remove_path_len;
char *add_path;
size_t add_path_len;
zip_flags_t flags;
zip_int32_t comp_method;
zip_uint32_t comp_flags;
#ifdef HAVE_ENCRYPTION
zip_int16_t enc_method;
char *enc_password;
#endif
} zip_options;

static int php_zip_parse_options(zval *options, zip_options *opts)
/* {{{ */
{
zval *option;

/* default values */
memset(opts, 0, sizeof(zip_options));
opts->flags = ZIP_FL_OVERWRITE;
opts->comp_method = -1; /* -1 to not change default */
#ifdef HAVE_ENCRYPTION
opts->enc_method = -1; /* -1 to not change default */
#endif

if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) {
*remove_all_path = zval_get_long(option);
opts->remove_all_path = zval_get_long(option);
}

if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "comp_method", sizeof("comp_method") - 1)) != NULL) {
opts->comp_method = zval_get_long(option);

if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "comp_flags", sizeof("comp_flags") - 1)) != NULL) {
opts->comp_flags = zval_get_long(option);
}
}

#ifdef HAVE_ENCRYPTION
if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "enc_method", sizeof("enc_method") - 1)) != NULL) {
opts->enc_method = zval_get_long(option);

if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "enc_password", sizeof("enc_password") - 1)) != NULL) {
if (Z_TYPE_P(option) != IS_STRING) {
php_error_docref(NULL, E_WARNING, "enc_password option expected to be a string");
return -1;
}
opts->enc_password = Z_STRVAL_P(option);
}
}
#endif

/* If I add more options, it would make sense to create a nice static struct and loop over it. */
if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_path", sizeof("remove_path") - 1)) != NULL) {
if (Z_TYPE_P(option) != IS_STRING) {
php_error_docref(NULL, E_WARNING, "remove_path option expected to be a string");
Expand All @@ -359,8 +401,8 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path,
MAXPATHLEN - 1, Z_STRLEN_P(option));
return -1;
}
*remove_path_len = Z_STRLEN_P(option);
*remove_path = Z_STRVAL_P(option);
opts->remove_path_len = Z_STRLEN_P(option);
opts->remove_path = Z_STRVAL_P(option);
}

if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "add_path", sizeof("add_path") - 1)) != NULL) {
Expand All @@ -379,16 +421,16 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path,
MAXPATHLEN - 1, Z_STRLEN_P(option));
return -1;
}
*add_path_len = Z_STRLEN_P(option);
*add_path = Z_STRVAL_P(option);
opts->add_path_len = Z_STRLEN_P(option);
opts->add_path = Z_STRVAL_P(option);
}

if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "flags", sizeof("flags") - 1)) != NULL) {
if (Z_TYPE_P(option) != IS_LONG) {
php_error_docref(NULL, E_WARNING, "flags option expected to be a integer");
return -1;
}
*flags = Z_LVAL_P(option);
opts->flags = Z_LVAL_P(option);
}

return 1;
Expand Down Expand Up @@ -1652,13 +1694,10 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
{
zval *self = ZEND_THIS;
char *path = ".";
char *remove_path = NULL;
char *add_path = NULL;
size_t add_path_len, remove_path_len = 0, path_len = 1;
zend_long remove_all_path = 0;
size_t path_len = 1;
zend_long glob_flags = 0;
zend_long zip_flags = ZIP_FL_OVERWRITE;
zval *options = NULL;
zip_options opts;
int found;
zend_string *pattern;

Expand All @@ -1679,8 +1718,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
php_error_docref(NULL, E_NOTICE, "Empty string as pattern");
RETURN_FALSE;
}
if (options && (php_zip_parse_options(options, &remove_all_path, &remove_path, &remove_path_len,
&add_path, &add_path_len, &zip_flags) < 0)) {
if (options && (php_zip_parse_options(options, &opts) < 0)) {
RETURN_FALSE;
}

Expand All @@ -1693,6 +1731,9 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
if (found > 0) {
int i;
zval *zval_file;
ze_zip_object *ze_obj;

ze_obj = Z_ZIP_P(self);

for (i = 0; i < found; i++) {
char *file_stripped, *entry_name;
Expand All @@ -1701,31 +1742,31 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
zend_string *basename = NULL;

if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(return_value), i)) != NULL) {
if (remove_all_path) {
if (opts.remove_all_path) {
basename = php_basename(Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), NULL, 0);
file_stripped = ZSTR_VAL(basename);
file_stripped_len = ZSTR_LEN(basename);
} else if (remove_path && strstr(Z_STRVAL_P(zval_file), remove_path) != NULL) {
if (IS_SLASH(Z_STRVAL_P(zval_file)[remove_path_len])) {
file_stripped = Z_STRVAL_P(zval_file) + remove_path_len + 1;
file_stripped_len = Z_STRLEN_P(zval_file) - remove_path_len - 1;
} else if (opts.remove_path && strstr(Z_STRVAL_P(zval_file), opts.remove_path) != NULL) {
if (IS_SLASH(Z_STRVAL_P(zval_file)[opts.remove_path_len])) {
file_stripped = Z_STRVAL_P(zval_file) + opts.remove_path_len + 1;
file_stripped_len = Z_STRLEN_P(zval_file) - opts.remove_path_len - 1;
} else {
file_stripped = Z_STRVAL_P(zval_file) + remove_path_len;
file_stripped_len = Z_STRLEN_P(zval_file) - remove_path_len;
file_stripped = Z_STRVAL_P(zval_file) + opts.remove_path_len;
file_stripped_len = Z_STRLEN_P(zval_file) - opts.remove_path_len;
}
} else {
file_stripped = Z_STRVAL_P(zval_file);
file_stripped_len = Z_STRLEN_P(zval_file);
}

if (add_path) {
if ((add_path_len + file_stripped_len) > MAXPATHLEN) {
if (opts.add_path) {
if ((opts.add_path_len + file_stripped_len) > MAXPATHLEN) {
php_error_docref(NULL, E_WARNING, "Entry name too long (max: %d, %zd given)",
MAXPATHLEN - 1, (add_path_len + file_stripped_len));
MAXPATHLEN - 1, (opts.add_path_len + file_stripped_len));
zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE;
}
snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped);
snprintf(entry_name_buf, MAXPATHLEN, "%s%s", opts.add_path, file_stripped);
} else {
snprintf(entry_name_buf, MAXPATHLEN, "%s", file_stripped);
}
Expand All @@ -1737,11 +1778,25 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
basename = NULL;
}

if (php_zip_add_file(Z_ZIP_P(self), Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
entry_name, entry_name_len, 0, 0, -1, zip_flags) < 0) {
if (php_zip_add_file(ze_obj, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
entry_name, entry_name_len, 0, 0, -1, opts.flags) < 0) {
zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE;
}
if (opts.comp_method >= 0) {
if (zip_set_file_compression(ze_obj->za, ze_obj->last_id, opts.comp_method, opts.comp_flags)) {
zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE;
}
}
#ifdef HAVE_ENCRYPTION
if (opts.enc_method >= 0) {
if (zip_file_set_encryption(ze_obj->za, ze_obj->last_id, opts.enc_method, opts.enc_password)) {
zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE;
}
}
#endif
}
}
}
Expand Down
65 changes: 65 additions & 0 deletions ext/zip/tests/oo_addglob2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
--TEST--
ZipArchive::addGlob() method with more compression and encryption
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
if (!method_exists('ZipArchive', 'setEncryptionName')) die('skip encrytion not supported');
?>
--FILE--
<?php
$dirname = __DIR__ . '/';
include $dirname . 'utils.inc';

$dirname = __DIR__ . '/__tmp_oo_addglob2/';
$file = $dirname . 'test.zip';

@mkdir($dirname);
copy(__FILE__, $dirname . 'foo.txt');
copy(__FILE__, $dirname . 'bar.txt');

$zip = new ZipArchive();
if (!$zip->open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
exit('failed');
}
$options = [
'remove_all_path' => true,
];
if (!$zip->addGlob($dirname . 'foo.*', GLOB_BRACE, $options)) {
echo "failed 1\n";
}

$options = [
'remove_all_path' => true,
'comp_method' => ZipArchive::CM_STORE,
'comp_password' => 5,
'enc_method' => ZipArchive::EM_AES_256,
'enc_password' => 'secret',
];
if (!$zip->addGlob($dirname . 'bar.*', GLOB_BRACE, $options)) {
echo "failed 2\n";
}
if ($zip->status == ZIPARCHIVE::ER_OK) {
$zip->close();

$zip = new ZipArchive();
$zip->open($file);
for($i=0; $i<$zip->numFiles; $i++) {
$sb = $zip->statIndex($i);
echo "$i: " . $sb['name'] .
", comp=" . $sb['comp_method'] .
", enc=" . $sb['encryption_method'] . "\n";
}
} else {
echo "failed 3\n";
}
?>
--CLEAN--
<?php
$dirname = __DIR__ . '/';
include $dirname . 'utils.inc';
rmdir_rf(__DIR__ . '/__tmp_oo_addglob2/');
?>
--EXPECTF--
0: foo.txt, comp=8, enc=0
1: bar.txt, comp=0, enc=259