mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
- ws/cs, macros, code that only affects other branches
- some unsynced changes need valgrind testing before they can go into this branch, see PECL/HEAD
This commit is contained in:
parent
821bab83a3
commit
4e5280a7a2
@ -5,14 +5,12 @@
|
||||
* @ingroup Phar
|
||||
* @brief class Phar Pre Command
|
||||
* @author Marcus Boerger
|
||||
* @date 2007 - 2007
|
||||
* @date 2007 - 2008
|
||||
*
|
||||
* Phar Command
|
||||
*/
|
||||
foreach(array("SPL", "Reflection", "Phar") as $ext)
|
||||
{
|
||||
if (!extension_loaded($ext))
|
||||
{
|
||||
foreach(array("SPL", "Reflection", "Phar") as $ext) {
|
||||
if (!extension_loaded($ext)) {
|
||||
echo "$argv[0] requires PHP extension $ext.\n";
|
||||
exit(1);
|
||||
}
|
||||
@ -28,14 +26,12 @@ $classes = array(
|
||||
'PharCommand',
|
||||
);
|
||||
|
||||
foreach($classes as $name)
|
||||
{
|
||||
foreach($classes as $name) {
|
||||
echo "if (!class_exists('$name', 0))\n{\n";
|
||||
$f = file(dirname(__FILE__) . '/phar/' . strtolower($name) . '.inc');
|
||||
unset($f[0]);
|
||||
$c = count($f);
|
||||
while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n"))
|
||||
{
|
||||
while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n")) {
|
||||
unset($f[$c--]);
|
||||
}
|
||||
if (substr($f[$c], -2) == "\r\n") {
|
||||
@ -47,8 +43,7 @@ foreach($classes as $name)
|
||||
if (substr($f[$c], -2) == '?>') {
|
||||
$f[$c] = substr($f[$c], 0,-2);
|
||||
}
|
||||
while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n"))
|
||||
{
|
||||
while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n")) {
|
||||
unset($f[$c--]);
|
||||
}
|
||||
echo join('', $f);
|
||||
|
@ -45,13 +45,13 @@ static int phar_dir_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{
|
||||
{
|
||||
HashTable *data = (HashTable *)stream->abstract;
|
||||
|
||||
if (data && data->arBuckets)
|
||||
{
|
||||
if (data && data->arBuckets) {
|
||||
zend_hash_destroy(data);
|
||||
data->arBuckets = 0;
|
||||
FREE_HASHTABLE(data);
|
||||
stream->abstract = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
@ -63,14 +63,15 @@ static int phar_dir_seek(php_stream *stream, off_t offset, int whence, off_t *ne
|
||||
{
|
||||
HashTable *data = (HashTable *)stream->abstract;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
if (!data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (whence == SEEK_END) {
|
||||
whence = SEEK_SET;
|
||||
offset = zend_hash_num_elements(data) + offset;
|
||||
}
|
||||
|
||||
if (whence == SEEK_SET) {
|
||||
zend_hash_internal_pointer_reset(data);
|
||||
}
|
||||
@ -102,15 +103,19 @@ static size_t phar_dir_read(php_stream *stream, char *buf, size_t count TSRMLS_D
|
||||
if (FAILURE == zend_hash_has_more_elements(data)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(data, &key, &keylen, &unused, 0, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PHAR_STR(key, str_key);
|
||||
zend_hash_move_forward(data);
|
||||
to_read = MIN(keylen, count);
|
||||
|
||||
if (to_read == 0 || count < keylen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(php_stream_dirent));
|
||||
memcpy(((php_stream_dirent *) buf)->d_name, str_key, to_read);
|
||||
((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0';
|
||||
@ -159,10 +164,9 @@ static int phar_compare_dir_name(const void *a, const void *b TSRMLS_DC) /* {{{
|
||||
Bucket *f;
|
||||
Bucket *s;
|
||||
int result;
|
||||
|
||||
|
||||
f = *((Bucket **) a);
|
||||
s = *((Bucket **) b);
|
||||
|
||||
#if (PHP_MAJOR_VERSION < 6)
|
||||
result = zend_binary_strcmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
|
||||
#else
|
||||
@ -202,12 +206,16 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
|
||||
efree(dir);
|
||||
return php_stream_alloc(&phar_dir_ops, data, NULL, "r");
|
||||
}
|
||||
|
||||
zend_hash_internal_pointer_reset(manifest);
|
||||
|
||||
while (FAILURE != zend_hash_has_more_elements(manifest)) {
|
||||
if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
PHAR_STR(key, str_key);
|
||||
|
||||
if (keylen <= (uint)dirlen) {
|
||||
if (keylen < (uint)dirlen || !strncmp(str_key, dir, dirlen)) {
|
||||
if (SUCCESS != zend_hash_move_forward(manifest)) {
|
||||
@ -216,6 +224,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (*dir == '/') {
|
||||
/* root directory */
|
||||
if (keylen >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) {
|
||||
@ -225,6 +234,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL != (found = (char *) memchr(str_key, '/', keylen))) {
|
||||
/* the entry has a path separator and is a subdirectory */
|
||||
entry = (char *) safe_emalloc(found - str_key, 1, 1);
|
||||
@ -236,6 +246,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
|
||||
memcpy(entry, str_key, keylen);
|
||||
entry[keylen] = '\0';
|
||||
}
|
||||
|
||||
goto PHAR_ADD_ENTRY;
|
||||
} else {
|
||||
if (0 != memcmp(str_key, dir, dirlen)) {
|
||||
@ -253,8 +264,10 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save = str_key;
|
||||
save += dirlen + 1; /* seek to just past the path separator */
|
||||
|
||||
if (NULL != (found = (char *) memchr(save, '/', keylen - dirlen - 1))) {
|
||||
/* is subdirectory */
|
||||
save -= dirlen + 1;
|
||||
@ -274,11 +287,14 @@ PHAR_ADD_ENTRY:
|
||||
if (keylen) {
|
||||
phar_add_empty(data, entry, keylen);
|
||||
}
|
||||
|
||||
efree(entry);
|
||||
|
||||
if (SUCCESS != zend_hash_move_forward(manifest)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILURE != zend_hash_has_more_elements(data)) {
|
||||
efree(dir);
|
||||
if (zend_hash_sort(data, zend_qsort, phar_compare_dir_name, 0 TSRMLS_CC) == FAILURE) {
|
||||
@ -296,8 +312,7 @@ PHAR_ADD_ENTRY:
|
||||
/**
|
||||
* Open a directory handle within a phar archive
|
||||
*/
|
||||
php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char *mode,
|
||||
int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
|
||||
php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_url *resource = NULL;
|
||||
php_stream *ret;
|
||||
@ -334,8 +349,8 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char
|
||||
|
||||
host_len = strlen(resource->host);
|
||||
phar_request_initialize(TSRMLS_C);
|
||||
|
||||
internal_file = resource->path + 1; /* strip leading "/" */
|
||||
|
||||
if (FAILURE == phar_get_archive(&phar, resource->host, host_len, NULL, 0, &error TSRMLS_CC)) {
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
|
||||
@ -346,9 +361,11 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
efree(error);
|
||||
}
|
||||
|
||||
if (*internal_file == '\0') {
|
||||
/* root directory requested */
|
||||
internal_file = estrndup(internal_file - 1, 1);
|
||||
@ -356,10 +373,12 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char
|
||||
php_url_free(resource);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!phar->manifest.arBuckets) {
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry) && !entry->is_dir) {
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
@ -389,6 +408,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char
|
||||
return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
}
|
||||
@ -417,11 +437,14 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\", no phar archive specified", url_from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
|
||||
phar = NULL;
|
||||
}
|
||||
|
||||
efree(arch);
|
||||
efree(entry2);
|
||||
|
||||
if (PHAR_G(readonly) && (!phar || !phar->is_data)) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\", write operations disabled", url_from);
|
||||
return 0;
|
||||
@ -463,18 +486,21 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", resource->path+1, resource->host, error);
|
||||
efree(error);
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((e = phar_get_entry_info_dir(phar, resource->path + 1, strlen(resource->path + 1), 0, &error, 1 TSRMLS_CC))) {
|
||||
/* entry exists as a file */
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", file already exists", resource->path+1, resource->host);
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", resource->path+1, resource->host, error);
|
||||
efree(error);
|
||||
@ -494,11 +520,14 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in
|
||||
if (phar->is_zip) {
|
||||
entry.is_zip = 1;
|
||||
}
|
||||
|
||||
entry.filename = estrdup(resource->path + 1);
|
||||
|
||||
if (phar->is_tar) {
|
||||
entry.is_tar = 1;
|
||||
entry.tar_type = TAR_DIR;
|
||||
}
|
||||
|
||||
entry.filename_len = strlen(resource->path + 1);
|
||||
php_url_free(resource);
|
||||
entry.is_dir = 1;
|
||||
@ -507,19 +536,23 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in
|
||||
entry.is_crc_checked = 1;
|
||||
entry.flags = PHAR_ENT_PERM_DEF_DIR;
|
||||
entry.old_flags = PHAR_ENT_PERM_DEF_DIR;
|
||||
|
||||
if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", entry.filename, phar->fname);
|
||||
efree(error);
|
||||
efree(entry.filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
phar_flush(phar, 0, 0, 0, &error TSRMLS_CC);
|
||||
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", entry.filename, phar->fname, error);
|
||||
zend_hash_del(&phar->manifest, entry.filename, entry.filename_len);
|
||||
efree(error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
phar_add_virtual_dirs(phar, entry.filename, entry.filename_len TSRMLS_CC);
|
||||
return 1;
|
||||
}
|
||||
@ -547,11 +580,14 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
|
||||
phar = NULL;
|
||||
}
|
||||
|
||||
efree(arch);
|
||||
efree(entry2);
|
||||
|
||||
if (PHAR_G(readonly) && (!phar || !phar->is_data)) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rmdir directory \"%s\", write operations disabled", url);
|
||||
return 0;
|
||||
@ -584,7 +620,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
|
||||
}
|
||||
|
||||
path_len = strlen(resource->path+1);
|
||||
|
||||
|
||||
if (!(entry = phar_get_entry_info_dir(phar, resource->path + 1, path_len, 2, &error, 1 TSRMLS_CC))) {
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", resource->path+1, resource->host, error);
|
||||
@ -604,13 +640,13 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
|
||||
}
|
||||
|
||||
for (zend_hash_internal_pointer_reset(&phar->manifest);
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL));
|
||||
zend_hash_move_forward(&phar->manifest)) {
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL));
|
||||
zend_hash_move_forward(&phar->manifest)) {
|
||||
|
||||
if (!entry->is_deleted &&
|
||||
key_len > path_len &&
|
||||
memcmp(key, resource->path+1, path_len) == 0 &&
|
||||
IS_SLASH(key[path_len])) {
|
||||
if (!entry->is_deleted &&
|
||||
key_len > path_len &&
|
||||
memcmp(key, resource->path+1, path_len) == 0 &&
|
||||
IS_SLASH(key[path_len])) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty");
|
||||
if (entry->is_temp_dir) {
|
||||
efree(entry->filename);
|
||||
@ -622,13 +658,13 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
|
||||
}
|
||||
|
||||
for (zend_hash_internal_pointer_reset(&phar->virtual_dirs);
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL));
|
||||
zend_hash_move_forward(&phar->virtual_dirs)) {
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL));
|
||||
zend_hash_move_forward(&phar->virtual_dirs)) {
|
||||
|
||||
if (!entry->is_deleted &&
|
||||
key_len > path_len &&
|
||||
memcmp(key, resource->path+1, path_len) == 0 &&
|
||||
IS_SLASH(key[path_len])) {
|
||||
if (!entry->is_deleted &&
|
||||
key_len > path_len &&
|
||||
memcmp(key, resource->path+1, path_len) == 0 &&
|
||||
IS_SLASH(key[path_len])) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty");
|
||||
if (entry->is_temp_dir) {
|
||||
efree(entry->filename);
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2007 The PHP Group |
|
||||
| Copyright (c) 2006-2008 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 |
|
||||
|
@ -37,6 +37,7 @@ PHAR_FUNC(phar_opendir) /* {{{ */
|
||||
&& !cached_phars.arBuckets) {
|
||||
goto skip_phar;
|
||||
}
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &filename, &filename_len, &zcontext) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
@ -110,10 +111,12 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
|
||||
&& !cached_phars.arBuckets) {
|
||||
goto skip_phar;
|
||||
}
|
||||
|
||||
/* Parse arguments */
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
|
||||
goto skip_phar;
|
||||
}
|
||||
|
||||
if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
|
||||
char *arch, *entry, *fname;
|
||||
int arch_len, entry_len, fname_len;
|
||||
@ -783,7 +786,7 @@ statme_baby:
|
||||
if (!phar->is_writeable) {
|
||||
sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777);
|
||||
}
|
||||
|
||||
|
||||
sb.st_nlink = 1;
|
||||
sb.st_rdev = -1;
|
||||
/* this is only for APC, so use /dev/null device - no chance of conflict there! */
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2007 The PHP Group |
|
||||
| Copyright (c) 2006-2008 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 |
|
||||
|
@ -34,7 +34,7 @@ $stub = '/*
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension generated stub |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2005-' . date('Y') . ' The PHP Group |
|
||||
| Copyright (c) 2005-' . date('Y') . ' 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 |
|
||||
|
735
ext/phar/phar.c
735
ext/phar/phar.c
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2007 The PHP Group |
|
||||
| Copyright (c) 2006-2008 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 |
|
||||
@ -163,7 +163,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phar)
|
||||
int has_bz2;
|
||||
zend_bool readonly_orig;
|
||||
zend_bool require_hash_orig;
|
||||
zend_bool intercepted;
|
||||
zend_bool intercepted;
|
||||
int request_init;
|
||||
int require_hash;
|
||||
int request_done;
|
||||
@ -493,8 +493,8 @@ union _phar_archive_object {
|
||||
zend_object std;
|
||||
spl_filesystem_object spl;
|
||||
struct {
|
||||
zend_object std;
|
||||
phar_archive_data *archive;
|
||||
zend_object std;
|
||||
phar_archive_data *archive;
|
||||
} arc;
|
||||
};
|
||||
#endif
|
||||
@ -505,8 +505,8 @@ union _phar_entry_object {
|
||||
zend_object std;
|
||||
spl_filesystem_object spl;
|
||||
struct {
|
||||
zend_object std;
|
||||
phar_entry_info *entry;
|
||||
zend_object std;
|
||||
phar_entry_info *entry;
|
||||
} ent;
|
||||
};
|
||||
#endif
|
||||
@ -520,11 +520,15 @@ extern char *(*phar_save_resolve_path)(const char *filename, int filename_len TS
|
||||
#if PHP_VERSION_ID >= 60000
|
||||
typedef zstr phar_zstr;
|
||||
#define PHAR_STR(a, b) \
|
||||
spprintf(&b, 0, "%r", a.s);
|
||||
spprintf(&b, 0, "%s", a.s);
|
||||
#define PHAR_ZSTR(a, b) \
|
||||
b = ZSTR(a);
|
||||
#else
|
||||
typedef char *phar_zstr;
|
||||
#define PHAR_STR(a, b) \
|
||||
b = a;
|
||||
#define PHAR_ZSTR(a, b) \
|
||||
b = a;
|
||||
#endif
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2007 The PHP Group |
|
||||
| Copyright (c) 2007-2008 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 |
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2007 The PHP Group |
|
||||
| Copyright (c) 2007-2008 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 |
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2005 The PHP Group |
|
||||
| Copyright (c) 2005-2008 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 |
|
||||
@ -22,7 +22,7 @@
|
||||
#ifndef PHP_PHAR_H
|
||||
#define PHP_PHAR_H
|
||||
|
||||
#define PHP_PHAR_VERSION "2.0.0b2-dev"
|
||||
#define PHP_PHAR_VERSION "2.0.0b2-dev"
|
||||
|
||||
#include "ext/standard/basic_functions.h"
|
||||
extern zend_module_entry phar_module_entry;
|
||||
@ -34,7 +34,7 @@ extern zend_module_entry phar_module_entry;
|
||||
#define PHP_PHAR_API
|
||||
#endif
|
||||
|
||||
#endif /* PHP_PHAR_H */
|
||||
#endif /* PHP_PHAR_H */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -3,293 +3,293 @@
|
||||
$web = '000';
|
||||
|
||||
if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
|
||||
Phar::interceptFileFuncs();
|
||||
set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
|
||||
Phar::webPhar(null, $web);
|
||||
include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
|
||||
return;
|
||||
Phar::interceptFileFuncs();
|
||||
set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
|
||||
Phar::webPhar(null, $web);
|
||||
include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
|
||||
return;
|
||||
}
|
||||
|
||||
if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
|
||||
Extract_Phar::go(true);
|
||||
$mimes = array(
|
||||
'phps' => 2,
|
||||
'c' => 'text/plain',
|
||||
'cc' => 'text/plain',
|
||||
'cpp' => 'text/plain',
|
||||
'c++' => 'text/plain',
|
||||
'dtd' => 'text/plain',
|
||||
'h' => 'text/plain',
|
||||
'log' => 'text/plain',
|
||||
'rng' => 'text/plain',
|
||||
'txt' => 'text/plain',
|
||||
'xsd' => 'text/plain',
|
||||
'php' => 1,
|
||||
'inc' => 1,
|
||||
'avi' => 'video/avi',
|
||||
'bmp' => 'image/bmp',
|
||||
'css' => 'text/css',
|
||||
'gif' => 'image/gif',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'htmls' => 'text/html',
|
||||
'ico' => 'image/x-ico',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'js' => 'application/x-javascript',
|
||||
'midi' => 'audio/midi',
|
||||
'mid' => 'audio/midi',
|
||||
'mod' => 'audio/mod',
|
||||
'mov' => 'movie/quicktime',
|
||||
'mp3' => 'audio/mp3',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'pdf' => 'application/pdf',
|
||||
'png' => 'image/png',
|
||||
'swf' => 'application/shockwave-flash',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'wav' => 'audio/wav',
|
||||
'xbm' => 'image/xbm',
|
||||
'xml' => 'text/xml',
|
||||
);
|
||||
Extract_Phar::go(true);
|
||||
$mimes = array(
|
||||
'phps' => 2,
|
||||
'c' => 'text/plain',
|
||||
'cc' => 'text/plain',
|
||||
'cpp' => 'text/plain',
|
||||
'c++' => 'text/plain',
|
||||
'dtd' => 'text/plain',
|
||||
'h' => 'text/plain',
|
||||
'log' => 'text/plain',
|
||||
'rng' => 'text/plain',
|
||||
'txt' => 'text/plain',
|
||||
'xsd' => 'text/plain',
|
||||
'php' => 1,
|
||||
'inc' => 1,
|
||||
'avi' => 'video/avi',
|
||||
'bmp' => 'image/bmp',
|
||||
'css' => 'text/css',
|
||||
'gif' => 'image/gif',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'htmls' => 'text/html',
|
||||
'ico' => 'image/x-ico',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'js' => 'application/x-javascript',
|
||||
'midi' => 'audio/midi',
|
||||
'mid' => 'audio/midi',
|
||||
'mod' => 'audio/mod',
|
||||
'mov' => 'movie/quicktime',
|
||||
'mp3' => 'audio/mp3',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'pdf' => 'application/pdf',
|
||||
'png' => 'image/png',
|
||||
'swf' => 'application/shockwave-flash',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'wav' => 'audio/wav',
|
||||
'xbm' => 'image/xbm',
|
||||
'xml' => 'text/xml',
|
||||
);
|
||||
|
||||
header("Cache-Control: no-cache, must-revalidate");
|
||||
header("Pragma: no-cache");
|
||||
header("Cache-Control: no-cache, must-revalidate");
|
||||
header("Pragma: no-cache");
|
||||
|
||||
$basename = basename(__FILE__);
|
||||
if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
|
||||
chdir(Extract_Phar::$temp);
|
||||
include $web;
|
||||
return;
|
||||
}
|
||||
$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
|
||||
if (!$pt || $pt == '/') {
|
||||
$pt = $web;
|
||||
header('HTTP/1.1 301 Moved Permanently');
|
||||
header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
|
||||
exit;
|
||||
}
|
||||
$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
|
||||
if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
echo "<html>\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File ", $pt, " Not Found</h1>\n </body>\n</html>";
|
||||
exit;
|
||||
}
|
||||
$b = pathinfo($a);
|
||||
if (!isset($b['extension'])) {
|
||||
header('Content-Type: text/plain');
|
||||
header('Content-Length: ' . filesize($a));
|
||||
readfile($a);
|
||||
exit;
|
||||
}
|
||||
if (isset($mimes[$b['extension']])) {
|
||||
if ($mimes[$b['extension']] === 1) {
|
||||
include $a;
|
||||
exit;
|
||||
}
|
||||
if ($mimes[$b['extension']] === 2) {
|
||||
highlight_file($a);
|
||||
exit;
|
||||
}
|
||||
header('Content-Type: ' .$mimes[$b['extension']]);
|
||||
header('Content-Length: ' . filesize($a));
|
||||
readfile($a);
|
||||
exit;
|
||||
}
|
||||
$basename = basename(__FILE__);
|
||||
if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
|
||||
chdir(Extract_Phar::$temp);
|
||||
include $web;
|
||||
return;
|
||||
}
|
||||
$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
|
||||
if (!$pt || $pt == '/') {
|
||||
$pt = $web;
|
||||
header('HTTP/1.1 301 Moved Permanently');
|
||||
header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
|
||||
exit;
|
||||
}
|
||||
$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
|
||||
if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
echo "<html>\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File ", $pt, " Not Found</h1>\n </body>\n</html>";
|
||||
exit;
|
||||
}
|
||||
$b = pathinfo($a);
|
||||
if (!isset($b['extension'])) {
|
||||
header('Content-Type: text/plain');
|
||||
header('Content-Length: ' . filesize($a));
|
||||
readfile($a);
|
||||
exit;
|
||||
}
|
||||
if (isset($mimes[$b['extension']])) {
|
||||
if ($mimes[$b['extension']] === 1) {
|
||||
include $a;
|
||||
exit;
|
||||
}
|
||||
if ($mimes[$b['extension']] === 2) {
|
||||
highlight_file($a);
|
||||
exit;
|
||||
}
|
||||
header('Content-Type: ' .$mimes[$b['extension']]);
|
||||
header('Content-Length: ' . filesize($a));
|
||||
readfile($a);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
class Extract_Phar
|
||||
{
|
||||
static $temp;
|
||||
static $origdir;
|
||||
const GZ = 0x1000;
|
||||
const BZ2 = 0x2000;
|
||||
const MASK = 0x3000;
|
||||
const START = 'index.php';
|
||||
const LEN = XXXX;
|
||||
static $temp;
|
||||
static $origdir;
|
||||
const GZ = 0x1000;
|
||||
const BZ2 = 0x2000;
|
||||
const MASK = 0x3000;
|
||||
const START = 'index.php';
|
||||
const LEN = XXXX;
|
||||
|
||||
static function go($return = false)
|
||||
{
|
||||
$fp = fopen(__FILE__, 'rb');
|
||||
fseek($fp, self::LEN);
|
||||
$L = unpack('V', $a = (binary)fread($fp, 4));
|
||||
$m = (binary)'';
|
||||
static function go($return = false)
|
||||
{
|
||||
$fp = fopen(__FILE__, 'rb');
|
||||
fseek($fp, self::LEN);
|
||||
$L = unpack('V', $a = (binary)fread($fp, 4));
|
||||
$m = (binary)'';
|
||||
|
||||
do {
|
||||
$read = 8192;
|
||||
if ($L[1] - strlen($m) < 8192) {
|
||||
$read = $L[1] - strlen($m);
|
||||
}
|
||||
$last = (binary)fread($fp, $read);
|
||||
$m .= $last;
|
||||
} while (strlen($last) && strlen($m) < $L[1]);
|
||||
do {
|
||||
$read = 8192;
|
||||
if ($L[1] - strlen($m) < 8192) {
|
||||
$read = $L[1] - strlen($m);
|
||||
}
|
||||
$last = (binary)fread($fp, $read);
|
||||
$m .= $last;
|
||||
} while (strlen($last) && strlen($m) < $L[1]);
|
||||
|
||||
if (strlen($m) < $L[1]) {
|
||||
die('ERROR: manifest length read was "' .
|
||||
strlen($m) .'" should be "' .
|
||||
$L[1] . '"');
|
||||
}
|
||||
if (strlen($m) < $L[1]) {
|
||||
die('ERROR: manifest length read was "' .
|
||||
strlen($m) .'" should be "' .
|
||||
$L[1] . '"');
|
||||
}
|
||||
|
||||
$info = self::_unpack($m);
|
||||
$f = $info['c'];
|
||||
$info = self::_unpack($m);
|
||||
$f = $info['c'];
|
||||
|
||||
if ($f & self::GZ) {
|
||||
if (!function_exists('gzinflate')) {
|
||||
die('Error: zlib extension is not enabled -' .
|
||||
' gzinflate() function needed for zlib-compressed .phars');
|
||||
}
|
||||
}
|
||||
if ($f & self::GZ) {
|
||||
if (!function_exists('gzinflate')) {
|
||||
die('Error: zlib extension is not enabled -' .
|
||||
' gzinflate() function needed for zlib-compressed .phars');
|
||||
}
|
||||
}
|
||||
|
||||
if ($f & self::BZ2) {
|
||||
if (!function_exists('bzdecompress')) {
|
||||
die('Error: bzip2 extension is not enabled -' .
|
||||
' bzdecompress() function needed for bz2-compressed .phars');
|
||||
}
|
||||
}
|
||||
if ($f & self::BZ2) {
|
||||
if (!function_exists('bzdecompress')) {
|
||||
die('Error: bzip2 extension is not enabled -' .
|
||||
' bzdecompress() function needed for bz2-compressed .phars');
|
||||
}
|
||||
}
|
||||
|
||||
$temp = self::tmpdir();
|
||||
$temp = self::tmpdir();
|
||||
|
||||
if (!$temp || !is_writable($temp)) {
|
||||
$sessionpath = session_save_path();
|
||||
if (strpos ($sessionpath, ";") !== false)
|
||||
$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
|
||||
if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
|
||||
die('Could not locate temporary directory to extract phar');
|
||||
}
|
||||
$temp = $sessionpath;
|
||||
}
|
||||
if (!$temp || !is_writable($temp)) {
|
||||
$sessionpath = session_save_path();
|
||||
if (strpos ($sessionpath, ";") !== false)
|
||||
$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
|
||||
if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
|
||||
die('Could not locate temporary directory to extract phar');
|
||||
}
|
||||
$temp = $sessionpath;
|
||||
}
|
||||
|
||||
$temp .= '/pharextract/'.basename(__FILE__, '.phar');
|
||||
self::$temp = $temp;
|
||||
self::$origdir = getcwd();
|
||||
@mkdir($temp, 0777, true);
|
||||
$temp = realpath($temp);
|
||||
$temp .= '/pharextract/'.basename(__FILE__, '.phar');
|
||||
self::$temp = $temp;
|
||||
self::$origdir = getcwd();
|
||||
@mkdir($temp, 0777, true);
|
||||
$temp = realpath($temp);
|
||||
|
||||
if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
|
||||
self::_removeTmpFiles($temp, getcwd());
|
||||
@mkdir($temp, 0777, true);
|
||||
@file_put_contents($temp . '/' . md5_file(__FILE__), '');
|
||||
if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
|
||||
self::_removeTmpFiles($temp, getcwd());
|
||||
@mkdir($temp, 0777, true);
|
||||
@file_put_contents($temp . '/' . md5_file(__FILE__), '');
|
||||
|
||||
foreach ($info['m'] as $path => $file) {
|
||||
$a = !file_exists(dirname($temp . '/' . $path));
|
||||
@mkdir(dirname($temp . '/' . $path), 0777, true);
|
||||
clearstatcache();
|
||||
foreach ($info['m'] as $path => $file) {
|
||||
$a = !file_exists(dirname($temp . '/' . $path));
|
||||
@mkdir(dirname($temp . '/' . $path), 0777, true);
|
||||
clearstatcache();
|
||||
|
||||
if ($path[strlen($path) - 1] == '/') {
|
||||
@mkdir($temp . '/' . $path, 0777);
|
||||
} else {
|
||||
file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
|
||||
@chmod($temp . '/' . $path, 0666);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($path[strlen($path) - 1] == '/') {
|
||||
@mkdir($temp . '/' . $path, 0777);
|
||||
} else {
|
||||
file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
|
||||
@chmod($temp . '/' . $path, 0666);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chdir($temp);
|
||||
chdir($temp);
|
||||
|
||||
if (!$return) {
|
||||
include self::START;
|
||||
}
|
||||
}
|
||||
if (!$return) {
|
||||
include self::START;
|
||||
}
|
||||
}
|
||||
|
||||
static function tmpdir()
|
||||
{
|
||||
if (strpos(PHP_OS, 'WIN') !== false) {
|
||||
if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
|
||||
return $var;
|
||||
}
|
||||
if (is_dir('/temp') || mkdir('/temp')) {
|
||||
return realpath('/temp');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ($var = getenv('TMPDIR')) {
|
||||
return $var;
|
||||
}
|
||||
return realpath('/tmp');
|
||||
}
|
||||
static function tmpdir()
|
||||
{
|
||||
if (strpos(PHP_OS, 'WIN') !== false) {
|
||||
if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
|
||||
return $var;
|
||||
}
|
||||
if (is_dir('/temp') || mkdir('/temp')) {
|
||||
return realpath('/temp');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ($var = getenv('TMPDIR')) {
|
||||
return $var;
|
||||
}
|
||||
return realpath('/tmp');
|
||||
}
|
||||
|
||||
static function _unpack($m)
|
||||
{
|
||||
$info = unpack('V', substr($m, 0, 4));
|
||||
// skip API version, phar flags, alias, metadata
|
||||
$l = unpack('V', substr($m, 10, 4));
|
||||
$m = substr($m, 14 + $l[1]);
|
||||
$s = unpack('V', substr($m, 0, 4));
|
||||
$o = 0;
|
||||
$start = 4 + $s[1];
|
||||
$ret['c'] = 0;
|
||||
static function _unpack($m)
|
||||
{
|
||||
$info = unpack('V', substr($m, 0, 4));
|
||||
// skip API version, phar flags, alias, metadata
|
||||
$l = unpack('V', substr($m, 10, 4));
|
||||
$m = substr($m, 14 + $l[1]);
|
||||
$s = unpack('V', substr($m, 0, 4));
|
||||
$o = 0;
|
||||
$start = 4 + $s[1];
|
||||
$ret['c'] = 0;
|
||||
|
||||
for ($i = 0; $i < $info[1]; $i++) {
|
||||
// length of the file name
|
||||
$len = unpack('V', substr($m, $start, 4));
|
||||
$start += 4;
|
||||
// file name
|
||||
$savepath = substr($m, $start, $len[1]);
|
||||
$start += $len[1];
|
||||
// retrieve manifest data:
|
||||
// 0 = size, 1 = timestamp, 2 = compressed size, 3 = crc32, 4 = flags
|
||||
// 5 = metadata length
|
||||
$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
|
||||
$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
|
||||
& 0xffffffff);
|
||||
$ret['m'][$savepath][7] = $o;
|
||||
$o += $ret['m'][$savepath][2];
|
||||
$start += 24 + $ret['m'][$savepath][5];
|
||||
$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
for ($i = 0; $i < $info[1]; $i++) {
|
||||
// length of the file name
|
||||
$len = unpack('V', substr($m, $start, 4));
|
||||
$start += 4;
|
||||
// file name
|
||||
$savepath = substr($m, $start, $len[1]);
|
||||
$start += $len[1];
|
||||
// retrieve manifest data:
|
||||
// 0 = size, 1 = timestamp, 2 = compressed size, 3 = crc32, 4 = flags
|
||||
// 5 = metadata length
|
||||
$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
|
||||
$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
|
||||
& 0xffffffff);
|
||||
$ret['m'][$savepath][7] = $o;
|
||||
$o += $ret['m'][$savepath][2];
|
||||
$start += 24 + $ret['m'][$savepath][5];
|
||||
$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function extractFile($path, $entry, $fp)
|
||||
{
|
||||
$data = '';
|
||||
$c = $entry[2];
|
||||
static function extractFile($path, $entry, $fp)
|
||||
{
|
||||
$data = '';
|
||||
$c = $entry[2];
|
||||
|
||||
while ($c) {
|
||||
if ($c < 8192) {
|
||||
$data .= @fread($fp, $c);
|
||||
$c = 0;
|
||||
} else {
|
||||
$c -= 8192;
|
||||
$data .= @fread($fp, 8192);
|
||||
}
|
||||
}
|
||||
while ($c) {
|
||||
if ($c < 8192) {
|
||||
$data .= @fread($fp, $c);
|
||||
$c = 0;
|
||||
} else {
|
||||
$c -= 8192;
|
||||
$data .= @fread($fp, 8192);
|
||||
}
|
||||
}
|
||||
|
||||
if ($entry[4] & self::GZ) {
|
||||
$data = gzinflate($data);
|
||||
} elseif ($entry[4] & self::BZ2) {
|
||||
$data = bzdecompress($data);
|
||||
}
|
||||
if ($entry[4] & self::GZ) {
|
||||
$data = gzinflate($data);
|
||||
} elseif ($entry[4] & self::BZ2) {
|
||||
$data = bzdecompress($data);
|
||||
}
|
||||
|
||||
if (strlen($data) != $entry[0]) {
|
||||
die("Invalid internal .phar file (size error " . strlen($data) . " != " .
|
||||
$stat[7] . ")");
|
||||
}
|
||||
if (strlen($data) != $entry[0]) {
|
||||
die("Invalid internal .phar file (size error " . strlen($data) . " != " .
|
||||
$stat[7] . ")");
|
||||
}
|
||||
|
||||
if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
|
||||
die("Invalid internal .phar file (checksum error)");
|
||||
}
|
||||
if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
|
||||
die("Invalid internal .phar file (checksum error)");
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
static function _removeTmpFiles($temp, $origdir)
|
||||
{
|
||||
chdir($temp);
|
||||
static function _removeTmpFiles($temp, $origdir)
|
||||
{
|
||||
chdir($temp);
|
||||
|
||||
foreach (glob('*') as $f) {
|
||||
if (file_exists($f)) {
|
||||
is_dir($f) ? @rmdir($f) : @unlink($f);
|
||||
if (file_exists($f) && is_dir($f)) {
|
||||
self::_removeTmpFiles($f, getcwd());
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (glob('*') as $f) {
|
||||
if (file_exists($f)) {
|
||||
is_dir($f) ? @rmdir($f) : @unlink($f);
|
||||
if (file_exists($f) && is_dir($f)) {
|
||||
self::_removeTmpFiles($f, getcwd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@rmdir($temp);
|
||||
clearstatcache();
|
||||
chdir($origdir);
|
||||
}
|
||||
@rmdir($temp);
|
||||
clearstatcache();
|
||||
chdir($origdir);
|
||||
}
|
||||
}
|
||||
|
@ -35,22 +35,22 @@ php_stream_ops phar_ops = {
|
||||
};
|
||||
|
||||
php_stream_wrapper_ops phar_stream_wops = {
|
||||
phar_wrapper_open_url,
|
||||
NULL, /* phar_wrapper_close */
|
||||
NULL, /* phar_wrapper_stat, */
|
||||
phar_wrapper_stat, /* stat_url */
|
||||
phar_wrapper_open_dir, /* opendir */
|
||||
"phar",
|
||||
phar_wrapper_unlink, /* unlink */
|
||||
phar_wrapper_rename, /* rename */
|
||||
phar_wrapper_mkdir, /* create directory */
|
||||
phar_wrapper_rmdir, /* remove directory */
|
||||
phar_wrapper_open_url,
|
||||
NULL, /* phar_wrapper_close */
|
||||
NULL, /* phar_wrapper_stat, */
|
||||
phar_wrapper_stat, /* stat_url */
|
||||
phar_wrapper_open_dir, /* opendir */
|
||||
"phar",
|
||||
phar_wrapper_unlink, /* unlink */
|
||||
phar_wrapper_rename, /* rename */
|
||||
phar_wrapper_mkdir, /* create directory */
|
||||
phar_wrapper_rmdir, /* remove directory */
|
||||
};
|
||||
|
||||
php_stream_wrapper php_stream_phar_wrapper = {
|
||||
&phar_stream_wops,
|
||||
NULL,
|
||||
0 /* is_url */
|
||||
php_stream_wrapper php_stream_phar_wrapper = {
|
||||
&phar_stream_wops,
|
||||
NULL,
|
||||
0 /* is_url */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -69,8 +69,8 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, char *filename, char *mode,
|
||||
if (!(options & PHP_STREAM_URL_STAT_QUIET)) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: open mode append not supported");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (phar_split_fname(filename, strlen(filename), &arch, &arch_len, &entry, &entry_len, 2, (mode[0] == 'w' ? 2 : 0) TSRMLS_CC) == FAILURE) {
|
||||
if (!(options & PHP_STREAM_URL_STAT_QUIET)) {
|
||||
if (arch && !entry) {
|
||||
@ -147,7 +147,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, char *filename, char *mode,
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
/* }}} */
|
||||
@ -296,7 +296,6 @@ idata_error:
|
||||
}
|
||||
}
|
||||
php_url_free(resource);
|
||||
|
||||
#if MBO_0
|
||||
fprintf(stderr, "Pharname: %s\n", idata->phar->filename);
|
||||
fprintf(stderr, "Filename: %s\n", internal_file);
|
||||
@ -366,7 +365,7 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
{
|
||||
phar_entry_data *data = (phar_entry_data *)stream->abstract;
|
||||
size_t got;
|
||||
|
||||
|
||||
if (data->internal_file->is_deleted) {
|
||||
stream->eof = 1;
|
||||
return 0;
|
||||
@ -379,7 +378,6 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
data->position = php_stream_tell(data->fp) - data->zero;
|
||||
stream->eof = (data->position == (off_t) data->internal_file->uncompressed_filesize);
|
||||
|
||||
|
||||
return got;
|
||||
}
|
||||
/* }}} */
|
||||
@ -629,7 +627,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
|
||||
}
|
||||
PHAR_STR(key, str_key);
|
||||
if ((int)keylen >= internal_file_len || strncmp(str_key, internal_file, keylen)) {
|
||||
zend_hash_move_forward_ex(&phar->mounted_dirs, &pos);
|
||||
zend_hash_move_forward_ex(&phar->mounted_dirs, &pos);
|
||||
continue;
|
||||
} else {
|
||||
char *test;
|
||||
@ -646,7 +644,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
|
||||
test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, internal_file + keylen);
|
||||
if (SUCCESS != php_stream_stat_path(test, &ssbi)) {
|
||||
efree(test);
|
||||
zend_hash_move_forward_ex(&phar->mounted_dirs, &pos);
|
||||
zend_hash_move_forward_ex(&phar->mounted_dirs, &pos);
|
||||
continue;
|
||||
}
|
||||
/* mount the file/directory just in time */
|
||||
@ -664,7 +662,6 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_resource:
|
||||
php_url_free(resource);
|
||||
return FAILURE;
|
||||
@ -730,7 +727,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio
|
||||
efree(error);
|
||||
}
|
||||
if (idata->internal_file->fp_refcount > 1) {
|
||||
/* more than just our fp resource is open for this file */
|
||||
/* more than just our fp resource is open for this file */
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot unlink", internal_file, resource->host);
|
||||
efree(internal_file);
|
||||
php_url_free(resource);
|
||||
@ -807,7 +804,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", url_from, url_to, url_from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!resource_to->scheme || !resource_to->host || !resource_to->path) {
|
||||
php_url_free(resource_from);
|
||||
php_url_free(resource_to);
|
||||
@ -895,14 +892,14 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
|
||||
uint to_len = strlen(resource_to->path+1);
|
||||
|
||||
for (zend_hash_internal_pointer_reset(&phar->manifest);
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL)) &&
|
||||
SUCCESS == zend_hash_get_current_data(&phar->manifest, (void **) &entry);
|
||||
zend_hash_move_forward(&phar->manifest)) {
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL)) &&
|
||||
SUCCESS == zend_hash_get_current_data(&phar->manifest, (void **) &entry);
|
||||
zend_hash_move_forward(&phar->manifest)) {
|
||||
|
||||
if (!entry->is_deleted &&
|
||||
key_len > from_len &&
|
||||
memcmp(key, resource_from->path+1, from_len) == 0 &&
|
||||
IS_SLASH(key[from_len])) {
|
||||
key_len > from_len &&
|
||||
memcmp(key, resource_from->path+1, from_len) == 0 &&
|
||||
IS_SLASH(key[from_len])) {
|
||||
|
||||
new_key_len = key_len + to_len - from_len;
|
||||
new_key = emalloc(new_key_len+1);
|
||||
@ -916,15 +913,15 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
|
||||
entry->filename_len = new_key_len;
|
||||
zend_hash_update_current_key_ex(&phar->manifest, key_type, new_key, new_key_len, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (zend_hash_internal_pointer_reset(&phar->virtual_dirs);
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL));
|
||||
zend_hash_move_forward(&phar->virtual_dirs)) {
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL));
|
||||
zend_hash_move_forward(&phar->virtual_dirs)) {
|
||||
|
||||
if (key_len >= from_len &&
|
||||
memcmp(key, resource_from->path+1, from_len) == 0 &&
|
||||
(key_len == from_len || IS_SLASH(key[from_len]))) {
|
||||
memcmp(key, resource_from->path+1, from_len) == 0 &&
|
||||
(key_len == from_len || IS_SLASH(key[from_len]))) {
|
||||
|
||||
new_key_len = key_len + to_len - from_len;
|
||||
new_key = emalloc(new_key_len+1);
|
||||
@ -937,13 +934,13 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
|
||||
}
|
||||
|
||||
for (zend_hash_internal_pointer_reset(&phar->mounted_dirs);
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &key_len, &unused, 0, NULL)) &&
|
||||
SUCCESS == zend_hash_get_current_data(&phar->mounted_dirs, (void **) &entry);
|
||||
zend_hash_move_forward(&phar->mounted_dirs)) {
|
||||
HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &key_len, &unused, 0, NULL)) &&
|
||||
SUCCESS == zend_hash_get_current_data(&phar->mounted_dirs, (void **) &entry);
|
||||
zend_hash_move_forward(&phar->mounted_dirs)) {
|
||||
|
||||
if (key_len >= from_len &&
|
||||
memcmp(key, resource_from->path+1, from_len) == 0 &&
|
||||
(key_len == from_len || IS_SLASH(key[from_len]))) {
|
||||
memcmp(key, resource_from->path+1, from_len) == 0 &&
|
||||
(key_len == from_len || IS_SLASH(key[from_len]))) {
|
||||
|
||||
new_key_len = key_len + to_len - from_len;
|
||||
new_key = emalloc(new_key_len+1);
|
||||
@ -969,6 +966,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
|
||||
|
||||
php_url_free(resource_from);
|
||||
php_url_free(resource_to);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| phar php single-file executable PHP extension |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2006-2007 The PHP Group |
|
||||
| Copyright (c) 2006-2008 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 |
|
||||
|
115
ext/phar/tar.c
115
ext/phar/tar.c
@ -27,19 +27,19 @@ static php_uint32 phar_tar_number(char *buf, int len) /* {{{ */
|
||||
while (i < len && buf[i] == ' ') {
|
||||
++i;
|
||||
}
|
||||
while (i < len &&
|
||||
buf[i] >= '0' &&
|
||||
buf[i] <= '7') {
|
||||
|
||||
while (i < len && buf[i] >= '0' && buf[i] <= '7') {
|
||||
num = num * 8 + (buf[i] - '0');
|
||||
++i;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* adapted from format_octal() in libarchive
|
||||
*
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2003-2008 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -176,6 +176,7 @@ int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRMLS_DC)
|
||||
php_stream_seek(fp, save, SEEK_SET);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (entry->filename_len == sizeof(".phar/.metadata.bin")-1 && !memcmp(entry->filename, ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1)) {
|
||||
entry->phar->metadata = entry->metadata;
|
||||
entry->metadata = NULL;
|
||||
@ -184,6 +185,7 @@ int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRMLS_DC)
|
||||
mentry->metadata = entry->metadata;
|
||||
entry->metadata = NULL;
|
||||
}
|
||||
|
||||
efree(metadata);
|
||||
php_stream_seek(fp, save, SEEK_SET);
|
||||
return SUCCESS;
|
||||
@ -207,6 +209,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
|
||||
totalsize = php_stream_tell(fp);
|
||||
php_stream_seek(fp, 0, SEEK_SET);
|
||||
read = php_stream_read(fp, buf, sizeof(buf));
|
||||
|
||||
if (read != sizeof(buf)) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: \"%s\" is not a tar file or is truncated", fname);
|
||||
@ -214,6 +217,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
|
||||
php_stream_close(fp);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
hdr = (tar_header*)buf;
|
||||
old = (memcmp(hdr->magic, "ustar", sizeof("ustar")-1) != 0);
|
||||
|
||||
@ -234,6 +238,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
|
||||
entry.is_crc_checked = 1;
|
||||
entry.phar = myphar;
|
||||
pos += sizeof(buf);
|
||||
|
||||
do {
|
||||
phar_entry_info *newentry;
|
||||
|
||||
@ -298,7 +303,9 @@ bail:
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
read = php_stream_read(fp, buf, sizeof(buf));
|
||||
|
||||
if (read != sizeof(buf)) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
|
||||
@ -307,16 +314,21 @@ bail:
|
||||
phar_destroy_phar_data(myphar TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
hdr = (tar_header*) buf;
|
||||
sum1 = phar_tar_number(hdr->checksum, sizeof(hdr->checksum));
|
||||
|
||||
if (sum1 == 0 && phar_tar_checksum(buf, sizeof(buf)) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: \"%s\" has entries after signature, invalid phar", fname);
|
||||
}
|
||||
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (!old && hdr->prefix[0] != 0) {
|
||||
char name[256];
|
||||
|
||||
@ -327,7 +339,9 @@ bail:
|
||||
} else {
|
||||
strcat(name, hdr->name);
|
||||
}
|
||||
|
||||
entry.filename_len = strlen(hdr->prefix) + 100;
|
||||
|
||||
if (name[entry.filename_len - 1] == '/') {
|
||||
/* some tar programs store directories with trailing slash */
|
||||
entry.filename_len--;
|
||||
@ -336,13 +350,16 @@ bail:
|
||||
} else {
|
||||
entry.filename = pestrdup(hdr->name, myphar->is_persistent);
|
||||
entry.filename_len = strlen(entry.filename);
|
||||
|
||||
if (entry.filename[entry.filename_len - 1] == '/') {
|
||||
/* some tar programs store directories with trailing slash */
|
||||
entry.filename[entry.filename_len - 1] = '\0';
|
||||
entry.filename_len--;
|
||||
}
|
||||
}
|
||||
|
||||
phar_add_virtual_dirs(myphar, entry.filename, entry.filename_len TSRMLS_CC);
|
||||
|
||||
if (sum1 != sum2) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (checksum mismatch of file \"%s\")", fname, entry.filename);
|
||||
@ -359,13 +376,13 @@ bail:
|
||||
entry.flags = phar_tar_number(hdr->mode, sizeof(hdr->mode)) & PHAR_ENT_PERM_MASK;
|
||||
entry.timestamp = phar_tar_number(hdr->mtime, sizeof(hdr->mtime));
|
||||
entry.is_persistent = myphar->is_persistent;
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
if (old && entry.tar_type == TAR_FILE && S_ISDIR(entry.flags)) {
|
||||
entry.tar_type = TAR_DIR;
|
||||
}
|
||||
|
||||
if (entry.tar_type == TAR_DIR) {
|
||||
entry.is_dir = 1;
|
||||
} else {
|
||||
@ -373,6 +390,7 @@ bail:
|
||||
}
|
||||
|
||||
entry.link = NULL;
|
||||
|
||||
if (entry.tar_type == TAR_LINK) {
|
||||
if (!zend_hash_exists(&myphar->manifest, hdr->linkname, strlen(hdr->linkname))) {
|
||||
if (error) {
|
||||
@ -389,7 +407,11 @@ bail:
|
||||
}
|
||||
phar_set_inode(&entry TSRMLS_CC);
|
||||
zend_hash_add(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry);
|
||||
if (entry.is_persistent) ++entry.manifest_pos;
|
||||
|
||||
if (entry.is_persistent) {
|
||||
++entry.manifest_pos;
|
||||
}
|
||||
|
||||
if (entry.filename_len >= sizeof(".phar/.metadata")-1 && !memcmp(entry.filename, ".phar/.metadata", sizeof(".phar/.metadata")-1)) {
|
||||
if (FAILURE == phar_tar_process_metadata(newentry, fp TSRMLS_CC)) {
|
||||
if (error) {
|
||||
@ -400,6 +422,7 @@ bail:
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
|
||||
size_t read;
|
||||
/* found explicit alias */
|
||||
@ -411,7 +434,9 @@ bail:
|
||||
phar_destroy_phar_data(myphar TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
read = php_stream_read(fp, buf, size);
|
||||
|
||||
if (read == size) {
|
||||
buf[size] = '\0';
|
||||
if (!phar_validate_alias(buf, size)) {
|
||||
@ -421,13 +446,16 @@ bail:
|
||||
buf[52] = '.';
|
||||
buf[53] = '\0';
|
||||
}
|
||||
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: invalid alias \"%s\" in tar-based phar \"%s\"", buf, fname);
|
||||
}
|
||||
|
||||
php_stream_close(fp);
|
||||
phar_destroy_phar_data(myphar TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
actual_alias = pestrndup(buf, size, myphar->is_persistent);
|
||||
myphar->alias = actual_alias;
|
||||
myphar->alias_len = size;
|
||||
@ -436,12 +464,15 @@ bail:
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: Unable to read alias from tar-based phar \"%s\"", fname);
|
||||
}
|
||||
|
||||
php_stream_close(fp);
|
||||
phar_destroy_phar_data(myphar TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
size = (size+511)&~511;
|
||||
|
||||
if (((hdr->typeflag == 0) || (hdr->typeflag == TAR_FILE)) && size > 0) {
|
||||
/* this is not good enough - seek succeeds even on truncated tars */
|
||||
php_stream_seek(fp, size, SEEK_CUR);
|
||||
@ -454,7 +485,9 @@ bail:
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
read = php_stream_read(fp, buf, sizeof(buf));
|
||||
|
||||
if (read != sizeof(buf)) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
|
||||
@ -488,6 +521,7 @@ bail:
|
||||
} else {
|
||||
myphar->is_data = 1;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p);
|
||||
if (myphar->ext == p) {
|
||||
@ -497,7 +531,9 @@ bail:
|
||||
myphar->ext_len = (myphar->fname + fname_len) - myphar->ext;
|
||||
}
|
||||
}
|
||||
|
||||
phar_request_initialize(TSRMLS_C);
|
||||
|
||||
if (SUCCESS != zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*), (void **)&actual)) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\" to phar registry", fname);
|
||||
@ -506,11 +542,14 @@ bail:
|
||||
phar_destroy_phar_data(myphar TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
myphar = *actual;
|
||||
|
||||
if (actual_alias) {
|
||||
phar_archive_data **fd_ptr;
|
||||
|
||||
myphar->is_temporary_alias = 0;
|
||||
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void **)&fd_ptr)) {
|
||||
if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, myphar->alias_len TSRMLS_CC)) {
|
||||
if (error) {
|
||||
@ -520,6 +559,7 @@ bail:
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
|
||||
} else {
|
||||
phar_archive_data **fd_ptr;
|
||||
@ -541,11 +581,14 @@ bail:
|
||||
myphar->alias = pestrndup(myphar->fname, fname_len, myphar->is_persistent);
|
||||
myphar->alias_len = fname_len;
|
||||
}
|
||||
|
||||
myphar->is_temporary_alias = 1;
|
||||
}
|
||||
|
||||
if (pphar) {
|
||||
*pphar = myphar;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@ -569,6 +612,7 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
if (entry->is_mounted) {
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
|
||||
if (entry->is_deleted) {
|
||||
if (entry->fp_refcount <= 0) {
|
||||
return ZEND_HASH_APPLY_REMOVE;
|
||||
@ -579,6 +623,7 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
|
||||
memset((char *) &header, 0, sizeof(header));
|
||||
|
||||
if (entry->filename_len > 100) {
|
||||
if (entry->filename_len > 255) {
|
||||
if (fp->error) {
|
||||
@ -591,28 +636,35 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
} else {
|
||||
memcpy(header.name, entry->filename, entry->filename_len);
|
||||
}
|
||||
|
||||
phar_tar_octal(header.mode, entry->flags & PHAR_ENT_PERM_MASK, sizeof(header.mode)-1);
|
||||
|
||||
if (FAILURE == phar_tar_octal(header.size, entry->uncompressed_filesize, sizeof(header.size)-1)) {
|
||||
if (fp->error) {
|
||||
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too large for tar file format", entry->phar->fname, entry->filename);
|
||||
}
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (FAILURE == phar_tar_octal(header.mtime, entry->timestamp, sizeof(header.mtime)-1)) {
|
||||
if (fp->error) {
|
||||
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, file modification time of file \"%s\" is too large for tar file format", entry->phar->fname, entry->filename);
|
||||
}
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
/* calc checksum */
|
||||
header.typeflag = entry->tar_type;
|
||||
|
||||
if (entry->link) {
|
||||
strncpy(header.linkname, entry->link, strlen(entry->link));
|
||||
}
|
||||
|
||||
strncpy(header.magic, "ustar", sizeof("ustar")-1);
|
||||
strncpy(header.version, "00", sizeof("00")-1);
|
||||
strncpy(header.checksum, " ", sizeof(" ")-1);
|
||||
entry->crc32 = phar_tar_checksum((char *)&header, sizeof(header));
|
||||
|
||||
if (FAILURE == phar_tar_octal(header.checksum, entry->crc32, sizeof(header.checksum)-1)) {
|
||||
if (fp->error) {
|
||||
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, checksum of file \"%s\" is too large for tar file format", entry->phar->fname, entry->filename);
|
||||
@ -622,12 +674,14 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
|
||||
/* write header */
|
||||
entry->header_offset = php_stream_tell(fp->new);
|
||||
|
||||
if (sizeof(header) != php_stream_write(fp->new, (char *) &header, sizeof(header))) {
|
||||
if (fp->error) {
|
||||
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, header for file \"%s\" could not be written", entry->phar->fname, entry->filename);
|
||||
}
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
pos = php_stream_tell(fp->new); /* save start of file within tar */
|
||||
|
||||
/* write contents */
|
||||
@ -635,22 +689,25 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
if (FAILURE == phar_open_entry_fp(entry, fp->error, 0 TSRMLS_CC)) {
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
|
||||
if (fp->error) {
|
||||
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", entry->phar->fname, entry->filename);
|
||||
}
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), fp->new, entry->uncompressed_filesize)) {
|
||||
if (fp->error) {
|
||||
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", entry->phar->fname, entry->filename);
|
||||
}
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
|
||||
memset(padding, 0, 512);
|
||||
php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize);
|
||||
}
|
||||
|
||||
if (!entry->is_modified && entry->fp_refcount) {
|
||||
/* open file pointers refer to this fp, do not free the stream */
|
||||
switch (entry->fp_type) {
|
||||
@ -665,12 +722,14 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
|
||||
entry->is_modified = 0;
|
||||
|
||||
if (entry->fp_type == PHAR_MOD && entry->fp != entry->phar->fp && entry->fp != entry->phar->ufp) {
|
||||
if (!entry->fp_refcount) {
|
||||
php_stream_close(entry->fp);
|
||||
}
|
||||
entry->fp = NULL;
|
||||
}
|
||||
|
||||
entry->fp_type = PHAR_FP;
|
||||
|
||||
/* note new location within tar */
|
||||
@ -686,24 +745,29 @@ int phar_tar_setmetadata(zval *metadata, phar_entry_info *entry, char **error, p
|
||||
if (entry->metadata_str.c) {
|
||||
smart_str_free(&entry->metadata_str);
|
||||
}
|
||||
|
||||
entry->metadata_str.c = 0;
|
||||
entry->metadata_str.len = 0;
|
||||
PHP_VAR_SERIALIZE_INIT(metadata_hash);
|
||||
php_var_serialize(&entry->metadata_str, &metadata, &metadata_hash TSRMLS_CC);
|
||||
PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
|
||||
entry->uncompressed_filesize = entry->compressed_filesize = entry->metadata_str.len;
|
||||
|
||||
if (entry->fp && entry->fp_type == PHAR_MOD) {
|
||||
php_stream_close(entry->fp);
|
||||
}
|
||||
|
||||
entry->fp_type = PHAR_MOD;
|
||||
entry->is_modified = 1;
|
||||
entry->fp = php_stream_fopen_tmpfile();
|
||||
entry->offset = entry->offset_abs = 0;
|
||||
|
||||
if (entry->metadata_str.len != php_stream_write(entry->fp, entry->metadata_str.c, entry->metadata_str.len)) {
|
||||
spprintf(error, 0, "phar tar error: unable to write metadata to magic metadata file \"%s\"", entry->filename);
|
||||
zend_hash_del(&(entry->phar->manifest), entry->filename, entry->filename_len);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
@ -732,13 +796,16 @@ int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{ */
|
||||
if (!entry->is_modified) {
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
|
||||
/* now we are dealing with regular files, so look for metadata */
|
||||
lookfor_len = spprintf(&lookfor, 0, ".phar/.metadata/%s/.metadata.bin", entry->filename);
|
||||
|
||||
if (!entry->metadata) {
|
||||
zend_hash_del(&(entry->phar->manifest), lookfor, lookfor_len);
|
||||
efree(lookfor);
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
|
||||
if (SUCCESS == zend_hash_find(&(entry->phar->manifest), lookfor, lookfor_len, (void **)&metadata)) {
|
||||
int ret;
|
||||
ret = phar_tar_setmetadata(entry->metadata, metadata, error, fp TSRMLS_CC);
|
||||
@ -786,6 +853,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (phar->is_data) {
|
||||
goto nostub;
|
||||
}
|
||||
@ -795,13 +863,16 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
|
||||
entry.filename_len = sizeof(".phar/alias.txt")-1;
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
|
||||
if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
entry.uncompressed_filesize = phar->alias_len;
|
||||
|
||||
if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
|
||||
@ -839,8 +910,8 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
} else {
|
||||
free_user_stub = 0;
|
||||
}
|
||||
if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL)
|
||||
{
|
||||
|
||||
if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
@ -849,6 +920,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
len = pos - user_stub + 18;
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
entry.uncompressed_filesize = len + 5;
|
||||
@ -864,9 +936,11 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
php_stream_close(entry.fp);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
|
||||
entry.filename_len = sizeof(".phar/stub.php")-1;
|
||||
zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
|
||||
|
||||
if (free_user_stub) {
|
||||
efree(user_stub);
|
||||
}
|
||||
@ -911,9 +985,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nostub:
|
||||
|
||||
if (phar->fp && !phar->is_brandnew) {
|
||||
oldfile = phar->fp;
|
||||
closeoldfile = 0;
|
||||
@ -922,7 +994,9 @@ nostub:
|
||||
oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL);
|
||||
closeoldfile = oldfile != NULL;
|
||||
}
|
||||
|
||||
newfile = php_stream_fopen_tmpfile();
|
||||
|
||||
if (!newfile) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to create temporary file");
|
||||
@ -964,6 +1038,7 @@ nostub:
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error, oldfile TSRMLS_CC)) {
|
||||
zend_hash_del(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1);
|
||||
if (closeoldfile) {
|
||||
@ -973,12 +1048,14 @@ nostub:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zend_hash_apply_with_argument(&phar->manifest, (apply_func_arg_t) phar_tar_setupmetadata, (void *) &pass TSRMLS_CC);
|
||||
|
||||
if (error && *error) {
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
|
||||
/* on error in the hash iterator above, error is set */
|
||||
php_stream_close(newfile);
|
||||
return EOF;
|
||||
@ -994,12 +1071,15 @@ nostub:
|
||||
spprintf(error, 0, "phar error: unable to write signature to tar-based phar: %s", save);
|
||||
efree(save);
|
||||
}
|
||||
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
|
||||
php_stream_close(newfile);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
entry.filename = ".phar/signature.bin";
|
||||
entry.filename_len = sizeof(".phar/signature.bin")-1;
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
@ -1008,26 +1088,28 @@ nostub:
|
||||
# define PHAR_SET_32(var, buffer) \
|
||||
*(php_uint32 *)(var) = (((((unsigned char*)(buffer))[3]) << 24) \
|
||||
| ((((unsigned char*)(buffer))[2]) << 16) \
|
||||
| ((((unsigned char*)(buffer))[1]) << 8) \
|
||||
| ((((unsigned char*)(buffer))[1]) << 8) \
|
||||
| (((unsigned char*)(buffer))[0]))
|
||||
#else
|
||||
# define PHAR_SET_32(var, buffer) *(php_uint32 *)(var) = (php_uint32) (buffer)
|
||||
#endif
|
||||
PHAR_SET_32(sigbuf, phar->sig_flags);
|
||||
PHAR_SET_32(sigbuf + 4, signature_length);
|
||||
|
||||
if (8 != (int)php_stream_write(entry.fp, sigbuf, 8) || signature_length != (int)php_stream_write(entry.fp, signature, signature_length)) {
|
||||
efree(signature);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", phar->fname);
|
||||
}
|
||||
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
return EOF;
|
||||
}
|
||||
efree(signature);
|
||||
|
||||
efree(signature);
|
||||
entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8;
|
||||
/* throw out return value and write the signature */
|
||||
entry.filename_len = phar_tar_writeheaders((void *)&entry, (void *)&pass TSRMLS_CC);
|
||||
@ -1050,14 +1132,17 @@ nostub:
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
|
||||
/* on error in the hash iterator above, error is set */
|
||||
if (error && *error) {
|
||||
php_stream_close(newfile);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (phar->fp && pass.free_fp) {
|
||||
php_stream_close(phar->fp);
|
||||
}
|
||||
|
||||
if (phar->ufp) {
|
||||
if (pass.free_ufp) {
|
||||
php_stream_close(phar->ufp);
|
||||
@ -1066,7 +1151,6 @@ nostub:
|
||||
}
|
||||
|
||||
phar->is_brandnew = 0;
|
||||
|
||||
php_stream_rewind(newfile);
|
||||
|
||||
if (phar->donotflush) {
|
||||
@ -1081,6 +1165,7 @@ nostub:
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (phar->flags & PHAR_FILE_COMPRESSED_GZ) {
|
||||
php_stream_filter *filter;
|
||||
/* to properly compress, we have to tell zlib to add a zlib header */
|
||||
@ -1094,6 +1179,7 @@ nostub:
|
||||
add_assoc_long(&filterparams, "window", MAX_WBITS + 16);
|
||||
filter = php_stream_filter_create("zlib.deflate", &filterparams, php_stream_is_persistent(phar->fp) TSRMLS_CC);
|
||||
zval_dtor(&filterparams);
|
||||
|
||||
if (!filter) {
|
||||
/* copy contents uncompressed rather than lose them */
|
||||
php_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL);
|
||||
@ -1103,6 +1189,7 @@ nostub:
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
php_stream_filter_append(&phar->fp->writefilters, filter);
|
||||
php_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL);
|
||||
php_stream_filter_flush(filter, 1);
|
||||
|
283
ext/phar/util.c
283
ext/phar/util.c
File diff suppressed because it is too large
Load Diff
180
ext/phar/zip.c
180
ext/phar/zip.c
@ -46,30 +46,38 @@ static int phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, php_ui
|
||||
if (sizeof(h.header) != php_stream_read(fp, (char *) &h.header, sizeof(h.header))) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (h.header.tag[0] != 'n' || h.header.tag[1] != 'u') {
|
||||
/* skip to next header */
|
||||
php_stream_seek(fp, PHAR_GET_16(h.header.size), SEEK_CUR);
|
||||
len -= PHAR_GET_16(h.header.size) + 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* unix3 header found */
|
||||
read = php_stream_read(fp, (char *) &(h.unix3.crc32), sizeof(h.unix3) - sizeof(h.header));
|
||||
len -= read + 4;
|
||||
|
||||
if (sizeof(h.unix3) - sizeof(h.header) != read) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (PHAR_GET_16(h.unix3.size) > sizeof(h.unix3) - 4) {
|
||||
/* skip symlink filename - we may add this support in later */
|
||||
php_stream_seek(fp, h.unix3.size - sizeof(h.unix3.size), SEEK_CUR);
|
||||
}
|
||||
|
||||
/* set permissions */
|
||||
entry->flags &= PHAR_ENT_COMPRESSION_MASK;
|
||||
|
||||
if (entry->is_dir) {
|
||||
entry->flags |= PHAR_GET_16(h.unix3.perms) & PHAR_ENT_PERM_MASK;
|
||||
} else {
|
||||
entry->flags |= PHAR_GET_16(h.unix3.perms) & PHAR_ENT_PERM_MASK;
|
||||
}
|
||||
|
||||
} while (len);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@ -94,7 +102,7 @@ static int phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, php_ui
|
||||
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
|
||||
@ -109,38 +117,38 @@ static int phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, php_ui
|
||||
*/
|
||||
static time_t phar_zip_d2u_time(int dtime, int ddate) /* {{{ */
|
||||
{
|
||||
struct tm *tm, tmbuf;
|
||||
time_t now;
|
||||
struct tm *tm, tmbuf;
|
||||
time_t now;
|
||||
|
||||
now = time(NULL);
|
||||
tm = php_localtime_r(&now, &tmbuf);
|
||||
|
||||
tm->tm_year = ((ddate>>9)&127) + 1980 - 1900;
|
||||
tm->tm_mon = ((ddate>>5)&15) - 1;
|
||||
tm->tm_mday = ddate&31;
|
||||
now = time(NULL);
|
||||
tm = php_localtime_r(&now, &tmbuf);
|
||||
|
||||
tm->tm_hour = (dtime>>11)&31;
|
||||
tm->tm_min = (dtime>>5)&63;
|
||||
tm->tm_sec = (dtime<<1)&62;
|
||||
tm->tm_year = ((ddate>>9)&127) + 1980 - 1900;
|
||||
tm->tm_mon = ((ddate>>5)&15) - 1;
|
||||
tm->tm_mday = ddate&31;
|
||||
|
||||
return mktime(tm);
|
||||
tm->tm_hour = (dtime>>11)&31;
|
||||
tm->tm_min = (dtime>>5)&63;
|
||||
tm->tm_sec = (dtime<<1)&62;
|
||||
|
||||
return mktime(tm);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void phar_zip_u2d_time(time_t time, php_uint16 *dtime, php_uint16 *ddate) /* {{{ */
|
||||
{
|
||||
struct tm *tm, tmbuf;
|
||||
struct tm *tm, tmbuf;
|
||||
|
||||
tm = php_localtime_r(&time, &tmbuf);
|
||||
*ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday;
|
||||
*dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1);
|
||||
tm = php_localtime_r(&time, &tmbuf);
|
||||
*ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday;
|
||||
*dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/**
|
||||
* Does not check for a previously opened phar in the cache.
|
||||
*
|
||||
* Parse a new one and add it to the cache, returning either SUCCESS or
|
||||
* Parse a new one and add it to the cache, returning either SUCCESS or
|
||||
* FAILURE, and setting pphar to the pointer to the manifest entry
|
||||
*
|
||||
* This is used by phar_open_from_fp to process a zip-based phar, but can be called
|
||||
@ -158,6 +166,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
char *p = buf, *ext, *actual_alias = NULL;
|
||||
|
||||
size = php_stream_tell(fp);
|
||||
|
||||
if (size > sizeof(locator) + 65536) {
|
||||
/* seek to max comment length + end of central directory record */
|
||||
size = sizeof(locator) + 65536;
|
||||
@ -171,6 +180,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
} else {
|
||||
php_stream_seek(fp, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
if (!(read = php_stream_read(fp, buf, size))) {
|
||||
php_stream_close(fp);
|
||||
if (error) {
|
||||
@ -178,6 +188,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
while ((p=(char *) memchr(p + 1, 'P', (size_t) (size - (p + 1 - buf)))) != NULL) {
|
||||
if (!memcmp(p + 1, "K\5\6", 3)) {
|
||||
memcpy((void *)&locator, (void *) p, sizeof(locator));
|
||||
@ -189,6 +200,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (locator.counthere != locator.count) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: corrupt zip archive, conflicting file count in end of central directory record in zip-based phar \"%s\"", fname);
|
||||
@ -196,6 +208,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
php_stream_close(fp);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
mydata = pecalloc(1, sizeof(phar_archive_data), PHAR_G(persist));
|
||||
mydata->is_persistent = PHAR_G(persist);
|
||||
|
||||
@ -204,6 +217,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
char *metadata;
|
||||
|
||||
metadata = p + sizeof(locator);
|
||||
|
||||
if (PHAR_GET_16(locator.comment_len) != size - (metadata - buf)) {
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: corrupt zip archive, zip file comment truncated in zip-based phar \"%s\"", fname);
|
||||
@ -212,7 +226,9 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
pefree(mydata, mydata->is_persistent);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
mydata->metadata_len = PHAR_GET_16(locator.comment_len);
|
||||
|
||||
if (phar_parse_metadata(&metadata, &mydata->metadata, PHAR_GET_16(locator.comment_len) TSRMLS_CC) == FAILURE) {
|
||||
mydata->metadata_len = 0;
|
||||
/* if not valid serialized data, it is a regular string */
|
||||
@ -230,13 +246,17 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
|
||||
} else {
|
||||
mydata->metadata = NULL;
|
||||
}
|
||||
|
||||
goto foundit;
|
||||
}
|
||||
}
|
||||
|
||||
php_stream_close(fp);
|
||||
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar error: end of central directory not found in zip-based phar \"%s\"", fname);
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
foundit:
|
||||
mydata->fname = pestrndup(fname, fname_len, mydata->is_persistent);
|
||||
@ -246,6 +266,7 @@ foundit:
|
||||
mydata->is_zip = 1;
|
||||
mydata->fname_len = fname_len;
|
||||
ext = strrchr(mydata->fname, '/');
|
||||
|
||||
if (ext) {
|
||||
mydata->ext = memchr(ext, '.', (mydata->fname + fname_len) - ext);
|
||||
if (mydata->ext == ext) {
|
||||
@ -255,6 +276,7 @@ foundit:
|
||||
mydata->ext_len = (mydata->fname + fname_len) - mydata->ext;
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up on big-endian systems */
|
||||
/* seek to central directory */
|
||||
php_stream_seek(fp, PHAR_GET_32(locator.cdir_offset), SEEK_SET);
|
||||
@ -297,12 +319,17 @@ foundit:
|
||||
if (sizeof(zipentry) != php_stream_read(fp, (char *) &zipentry, sizeof(zipentry))) {
|
||||
PHAR_ZIP_FAIL("unable to read central directory entry, truncated");
|
||||
}
|
||||
|
||||
/* clean up for bigendian systems */
|
||||
if (memcmp("PK\1\2", zipentry.signature, 4)) {
|
||||
/* corrupted entry */
|
||||
PHAR_ZIP_FAIL("corrupted central directory entry, no magic signature");
|
||||
}
|
||||
if (entry.is_persistent) entry.manifest_pos = i;
|
||||
|
||||
if (entry.is_persistent) {
|
||||
entry.manifest_pos = i;
|
||||
}
|
||||
|
||||
entry.compressed_filesize = PHAR_GET_32(zipentry.compsize);
|
||||
entry.uncompressed_filesize = PHAR_GET_32(zipentry.uncompsize);
|
||||
entry.crc32 = PHAR_GET_32(zipentry.crc32);
|
||||
@ -312,19 +339,25 @@ foundit:
|
||||
entry.header_offset = PHAR_GET_32(zipentry.offset);
|
||||
entry.offset = entry.offset_abs = PHAR_GET_32(zipentry.offset) + sizeof(phar_zip_file_header) + PHAR_GET_16(zipentry.filename_len) +
|
||||
PHAR_GET_16(zipentry.extra_len);
|
||||
|
||||
if (PHAR_GET_16(zipentry.flags) & PHAR_ZIP_FLAG_ENCRYPTED) {
|
||||
PHAR_ZIP_FAIL("Cannot process encrypted zip files");
|
||||
}
|
||||
|
||||
if (!PHAR_GET_16(zipentry.filename_len)) {
|
||||
PHAR_ZIP_FAIL("Cannot process zips created from stdin (zero-length filename)");
|
||||
}
|
||||
|
||||
entry.filename_len = PHAR_GET_16(zipentry.filename_len);
|
||||
entry.filename = (char *) pemalloc(entry.filename_len + 1, entry.is_persistent);
|
||||
|
||||
if (entry.filename_len != php_stream_read(fp, entry.filename, entry.filename_len)) {
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to read in filename from central directory, truncated");
|
||||
}
|
||||
|
||||
entry.filename[entry.filename_len] = '\0';
|
||||
|
||||
if (entry.filename[entry.filename_len - 1] == '/') {
|
||||
entry.is_dir = 1;
|
||||
entry.filename_len--;
|
||||
@ -332,7 +365,9 @@ foundit:
|
||||
} else {
|
||||
entry.is_dir = 0;
|
||||
}
|
||||
|
||||
phar_add_virtual_dirs(mydata, entry.filename, entry.filename_len TSRMLS_CC);
|
||||
|
||||
if (PHAR_GET_16(zipentry.extra_len)) {
|
||||
off_t loc = php_stream_tell(fp);
|
||||
if (FAILURE == phar_zip_process_extra(fp, &entry, PHAR_GET_16(zipentry.extra_len) TSRMLS_CC)) {
|
||||
@ -341,6 +376,7 @@ foundit:
|
||||
}
|
||||
php_stream_seek(fp, loc + PHAR_GET_16(zipentry.extra_len), SEEK_SET);
|
||||
}
|
||||
|
||||
switch (zipentry.compressed) {
|
||||
case PHAR_ZIP_COMP_NONE :
|
||||
/* compression flag already set */
|
||||
@ -399,14 +435,17 @@ foundit:
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unsupported compression method (unknown) used in this zip");
|
||||
}
|
||||
|
||||
/* get file metadata */
|
||||
if (zipentry.comment_len) {
|
||||
if (PHAR_GET_16(zipentry.comment_len) != php_stream_read(fp, buf, PHAR_GET_16(zipentry.comment_len))) {
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to read in file comment, truncated");
|
||||
}
|
||||
|
||||
p = buf;
|
||||
entry.metadata_len = zipentry.comment_len;
|
||||
|
||||
if (phar_parse_metadata(&p, &(entry.metadata), PHAR_GET_16(zipentry.comment_len) TSRMLS_CC) == FAILURE) {
|
||||
entry.metadata_len = 0;
|
||||
/* if not valid serialized data, it is a regular string */
|
||||
@ -423,41 +462,51 @@ foundit:
|
||||
} else {
|
||||
entry.metadata = NULL;
|
||||
}
|
||||
|
||||
if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
|
||||
php_stream_filter *filter;
|
||||
off_t saveloc;
|
||||
|
||||
/* archive alias found, seek to file contents, do not validate local header. Potentially risky, but
|
||||
not very. */
|
||||
/* archive alias found, seek to file contents, do not validate local header. Potentially risky, but not very. */
|
||||
saveloc = php_stream_tell(fp);
|
||||
php_stream_seek(fp, PHAR_GET_32(zipentry.offset) + sizeof(phar_zip_file_header) + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET);
|
||||
mydata->alias_len = entry.uncompressed_filesize;
|
||||
|
||||
if (entry.flags & PHAR_ENT_COMPRESSED_GZ) {
|
||||
filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
|
||||
|
||||
if (!filter) {
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to decompress alias, zlib filter creation failed");
|
||||
}
|
||||
|
||||
php_stream_filter_append(&fp->readfilters, filter);
|
||||
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to read in alias, truncated");
|
||||
}
|
||||
|
||||
php_stream_filter_flush(filter, 1);
|
||||
php_stream_filter_remove(filter, 1 TSRMLS_CC);
|
||||
|
||||
} else if (entry.flags & PHAR_ENT_COMPRESSED_BZ2) {
|
||||
php_stream_filter *filter;
|
||||
filter = php_stream_filter_create("bzip2.decompress", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
|
||||
|
||||
if (!filter) {
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to read in alias, bzip2 filter creation failed");
|
||||
}
|
||||
|
||||
php_stream_filter_append(&fp->readfilters, filter);
|
||||
php_stream_filter_append(&fp->readfilters, filter);
|
||||
|
||||
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
|
||||
pefree(entry.filename, entry.is_persistent);
|
||||
PHAR_ZIP_FAIL("unable to read in alias, truncated");
|
||||
}
|
||||
|
||||
php_stream_filter_flush(filter, 1);
|
||||
php_stream_filter_remove(filter, 1 TSRMLS_CC);
|
||||
} else {
|
||||
@ -470,16 +519,21 @@ foundit:
|
||||
/* return to central directory parsing */
|
||||
php_stream_seek(fp, saveloc, SEEK_SET);
|
||||
}
|
||||
|
||||
phar_set_inode(&entry TSRMLS_CC);
|
||||
zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry,sizeof(phar_entry_info), NULL);
|
||||
}
|
||||
|
||||
mydata->fp = fp;
|
||||
|
||||
if (zend_hash_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
|
||||
mydata->is_data = 0;
|
||||
} else {
|
||||
mydata->is_data = 1;
|
||||
}
|
||||
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
|
||||
if (actual_alias) {
|
||||
phar_archive_data **fd_ptr;
|
||||
|
||||
@ -491,7 +545,9 @@ foundit:
|
||||
zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
mydata->is_temporary_alias = 0;
|
||||
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void **)&fd_ptr)) {
|
||||
if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, mydata->alias_len TSRMLS_CC)) {
|
||||
if (error) {
|
||||
@ -502,10 +558,13 @@ foundit:
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias;
|
||||
|
||||
if (entry.is_persistent) {
|
||||
efree(actual_alias);
|
||||
}
|
||||
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
} else {
|
||||
phar_archive_data **fd_ptr;
|
||||
@ -520,6 +579,7 @@ foundit:
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
mydata->alias = pestrndup(alias, alias_len, mydata->is_persistent);
|
||||
mydata->alias_len = alias_len;
|
||||
@ -527,12 +587,14 @@ foundit:
|
||||
mydata->alias = pestrndup(mydata->fname, fname_len, mydata->is_persistent);
|
||||
mydata->alias_len = fname_len;
|
||||
}
|
||||
|
||||
mydata->is_temporary_alias = 1;
|
||||
}
|
||||
|
||||
if (pphar) {
|
||||
*pphar = mydata;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@ -570,6 +632,7 @@ int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_l
|
||||
if (error) {
|
||||
spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", fname);
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
@ -595,9 +658,11 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
|
||||
entry = (phar_entry_info *)data;
|
||||
p = (struct _phar_zip_pass*) arg;
|
||||
|
||||
if (entry->is_mounted) {
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
|
||||
if (entry->is_deleted) {
|
||||
if (entry->fp_refcount <= 0) {
|
||||
return ZEND_HASH_APPLY_REMOVE;
|
||||
@ -606,6 +671,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
memset(¢ral, 0, sizeof(central));
|
||||
memset(&perms, 0, sizeof(perms));
|
||||
@ -620,18 +686,22 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
CRC32(perms.crc32, (char)perms.perms & 0xFF);
|
||||
CRC32(perms.crc32, (char)perms.perms & 0xFF00 >> 8);
|
||||
perms.crc32 = PHAR_SET_32(~(perms.crc32));
|
||||
|
||||
if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
|
||||
local.compressed = central.compressed = PHAR_SET_16(PHAR_ZIP_COMP_DEFLATE);
|
||||
}
|
||||
|
||||
if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
|
||||
local.compressed = central.compressed = PHAR_SET_16(PHAR_ZIP_COMP_BZIP2);
|
||||
}
|
||||
|
||||
/* do not use PHAR_SET_16 on either field of the next line */
|
||||
phar_zip_u2d_time(entry->timestamp, &local.timestamp, &local.datestamp);
|
||||
central.timestamp = local.timestamp;
|
||||
central.datestamp = local.datestamp;
|
||||
central.filename_len = local.filename_len = PHAR_SET_16(entry->filename_len + (entry->is_dir ? 1 : 0));
|
||||
central.offset = PHAR_SET_32(php_stream_tell(p->filefp));
|
||||
|
||||
/* do extra field for perms later */
|
||||
if (entry->is_modified) {
|
||||
php_uint32 loc;
|
||||
@ -647,29 +717,36 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
goto continue_dir;
|
||||
}
|
||||
|
||||
if (FAILURE == phar_open_entry_fp(entry, p->error, 0 TSRMLS_CC)) {
|
||||
spprintf(p->error, 0, "unable to open file contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
|
||||
spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
efp = phar_get_efp(entry, 0 TSRMLS_CC);
|
||||
|
||||
efp = phar_get_efp(entry, 0 TSRMLS_CC);
|
||||
newcrc32 = ~0;
|
||||
|
||||
for (loc = 0;loc < entry->uncompressed_filesize; ++loc) {
|
||||
CRC32(newcrc32, php_stream_getc(efp));
|
||||
}
|
||||
|
||||
entry->crc32 = ~newcrc32;
|
||||
central.uncompsize = local.uncompsize = PHAR_SET_32(entry->uncompressed_filesize);
|
||||
|
||||
if (!(entry->flags & PHAR_ENT_COMPRESSION_MASK)) {
|
||||
/* not compressed */
|
||||
entry->compressed_filesize = entry->uncompressed_filesize;
|
||||
central.compsize = local.compsize = PHAR_SET_32(entry->compressed_filesize);
|
||||
goto not_compressed;
|
||||
}
|
||||
|
||||
filter = php_stream_filter_create(phar_compress_filter(entry, 0), NULL, 0 TSRMLS_CC);
|
||||
|
||||
if (!filter) {
|
||||
if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
|
||||
spprintf(p->error, 0, "unable to gzip compress file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
@ -683,20 +760,26 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
/* work around inability to specify freedom in write and strictness
|
||||
in read count */
|
||||
entry->cfp = php_stream_fopen_tmpfile();
|
||||
|
||||
if (!entry->cfp) {
|
||||
spprintf(p->error, 0, "unable to create temporary file for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
php_stream_flush(efp);
|
||||
|
||||
if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
|
||||
spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
php_stream_filter_append((&entry->cfp->writefilters), filter);
|
||||
|
||||
if (entry->uncompressed_filesize != php_stream_copy_to_stream(efp, entry->cfp, entry->uncompressed_filesize)) {
|
||||
spprintf(p->error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
php_stream_filter_flush(filter, 1);
|
||||
php_stream_flush(entry->cfp);
|
||||
php_stream_filter_remove(filter, 1 TSRMLS_CC);
|
||||
@ -710,6 +793,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
} else {
|
||||
central.uncompsize = local.uncompsize = PHAR_SET_32(entry->uncompressed_filesize);
|
||||
central.compsize = local.compsize = PHAR_SET_32(entry->compressed_filesize);
|
||||
|
||||
if (-1 == php_stream_seek(p->old, entry->offset_abs, SEEK_SET)) {
|
||||
spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
@ -732,29 +816,36 @@ continue_dir:
|
||||
PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
|
||||
central.comment_len = PHAR_SET_16(entry->metadata_str.len);
|
||||
}
|
||||
|
||||
entry->header_offset = php_stream_tell(p->filefp);
|
||||
offset = entry->header_offset + sizeof(local) + entry->filename_len + (entry->is_dir ? 1 : 0) + sizeof(perms);
|
||||
|
||||
if (sizeof(local) != php_stream_write(p->filefp, (char *)&local, sizeof(local))) {
|
||||
spprintf(p->error, 0, "unable to write local file header of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (sizeof(central) != php_stream_write(p->centralfp, (char *)¢ral, sizeof(central))) {
|
||||
spprintf(p->error, 0, "unable to write central directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (entry->is_dir) {
|
||||
if (entry->filename_len != php_stream_write(p->filefp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (1 != php_stream_write(p->filefp, "/", 1)) {
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (entry->filename_len != php_stream_write(p->centralfp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (1 != php_stream_write(p->centralfp, "/", 1)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
@ -764,40 +855,49 @@ continue_dir:
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (entry->filename_len != php_stream_write(p->centralfp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeof(perms) != php_stream_write(p->filefp, (char *)&perms, sizeof(perms))) {
|
||||
spprintf(p->error, 0, "unable to write local extra permissions file header of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (sizeof(perms) != php_stream_write(p->centralfp, (char *)&perms, sizeof(perms))) {
|
||||
spprintf(p->error, 0, "unable to write central extra permissions file header of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
if (entry->is_modified) {
|
||||
if (entry->cfp) {
|
||||
if (entry->compressed_filesize != php_stream_copy_to_stream(entry->cfp, p->filefp, entry->compressed_filesize)) {
|
||||
spprintf(p->error, 0, "unable to write compressed contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
php_stream_close(entry->cfp);
|
||||
entry->cfp = NULL;
|
||||
} else {
|
||||
if (FAILURE == phar_open_entry_fp(entry, p->error, 0 TSRMLS_CC)) {
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC);
|
||||
|
||||
if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), p->filefp, entry->uncompressed_filesize)) {
|
||||
spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->fp_type == PHAR_MOD && entry->fp != entry->phar->fp && entry->fp != entry->phar->ufp && entry->fp_refcount == 0) {
|
||||
php_stream_close(entry->fp);
|
||||
}
|
||||
|
||||
entry->is_modified = 0;
|
||||
} else {
|
||||
if (entry->fp_refcount) {
|
||||
@ -812,22 +912,27 @@ continue_dir:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry->is_dir && entry->compressed_filesize && entry->compressed_filesize != php_stream_copy_to_stream(p->old, p->filefp, entry->compressed_filesize)) {
|
||||
spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
entry->fp = NULL;
|
||||
entry->offset = entry->offset_abs = offset;
|
||||
entry->fp_type = PHAR_FP;
|
||||
|
||||
if (entry->metadata_str.c) {
|
||||
if (entry->metadata_str.len != php_stream_write(p->centralfp, entry->metadata_str.c, entry->metadata_str.len)) {
|
||||
spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
smart_str_free(&entry->metadata_str);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
|
||||
smart_str_free(&entry->metadata_str);
|
||||
}
|
||||
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
@ -859,6 +964,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (phar->is_data) {
|
||||
goto nostub;
|
||||
}
|
||||
@ -866,15 +972,18 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
/* set alias */
|
||||
if (!phar->is_temporary_alias && phar->alias_len) {
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
|
||||
if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
entry.uncompressed_filesize = entry.compressed_filesize = phar->alias_len;
|
||||
entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
|
||||
entry.filename_len = sizeof(".phar/alias.txt")-1;
|
||||
|
||||
if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
|
||||
@ -884,6 +993,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
} else {
|
||||
zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
|
||||
}
|
||||
|
||||
/* register alias */
|
||||
if (phar->alias_len) {
|
||||
if (FAILURE == phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, phar->alias_len, error TSRMLS_CC)) {
|
||||
@ -901,12 +1011,15 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
len = PHP_STREAM_COPY_ALL;
|
||||
} else {
|
||||
len = -len;
|
||||
}
|
||||
|
||||
user_stub = 0;
|
||||
|
||||
if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to read resource to copy stub to new zip-based phar \"%s\"", phar->fname);
|
||||
@ -917,6 +1030,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
} else {
|
||||
free_user_stub = 0;
|
||||
}
|
||||
|
||||
if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL)
|
||||
{
|
||||
if (error) {
|
||||
@ -927,6 +1041,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
len = pos - user_stub + 18;
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
entry.uncompressed_filesize = len + 5;
|
||||
@ -942,8 +1057,10 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
php_stream_close(entry.fp);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
|
||||
entry.filename_len = sizeof(".phar/stub.php")-1;
|
||||
|
||||
if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
|
||||
if (free_user_stub) {
|
||||
efree(user_stub);
|
||||
@ -953,6 +1070,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (free_user_stub) {
|
||||
efree(user_stub);
|
||||
}
|
||||
@ -997,9 +1115,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nostub:
|
||||
|
||||
if (phar->fp && !phar->is_brandnew) {
|
||||
oldfile = phar->fp;
|
||||
closeoldfile = 0;
|
||||
@ -1012,6 +1128,7 @@ nostub:
|
||||
/* save modified files to the zip */
|
||||
pass.old = oldfile;
|
||||
pass.filefp = php_stream_fopen_tmpfile();
|
||||
|
||||
if (!pass.filefp) {
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
@ -1021,7 +1138,9 @@ nostub:
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
pass.centralfp = php_stream_fopen_tmpfile();
|
||||
|
||||
if (!pass.centralfp) {
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
@ -1031,12 +1150,14 @@ nostub:
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
pass.free_fp = pass.free_ufp = 1;
|
||||
memset(&eocd, 0, sizeof(eocd));
|
||||
|
||||
strncpy(eocd.signature, "PK\5\6", 4);
|
||||
eocd.counthere = eocd.count = zend_hash_num_elements(&phar->manifest);
|
||||
zend_hash_apply_with_argument(&phar->manifest, phar_zip_changed_apply, (void *) &pass TSRMLS_CC);
|
||||
|
||||
if (temperr) {
|
||||
php_stream_close(pass.filefp);
|
||||
php_stream_close(pass.centralfp);
|
||||
@ -1054,6 +1175,7 @@ nostub:
|
||||
eocd.cdir_size = php_stream_tell(pass.centralfp);
|
||||
eocd.cdir_offset = php_stream_tell(pass.filefp);
|
||||
php_stream_seek(pass.centralfp, 0, SEEK_SET);
|
||||
|
||||
if (eocd.cdir_size != php_stream_copy_to_stream(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL)) {
|
||||
php_stream_close(pass.filefp);
|
||||
php_stream_close(pass.centralfp);
|
||||
@ -1065,13 +1187,16 @@ nostub:
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
php_stream_close(pass.centralfp);
|
||||
|
||||
if (phar->metadata) {
|
||||
/* set phar metadata */
|
||||
PHP_VAR_SERIALIZE_INIT(metadata_hash);
|
||||
php_var_serialize(&main_metadata_str, &phar->metadata, &metadata_hash TSRMLS_CC);
|
||||
PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
|
||||
eocd.comment_len = PHAR_SET_16(main_metadata_str.len);
|
||||
|
||||
if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) {
|
||||
php_stream_close(pass.filefp);
|
||||
if (error) {
|
||||
@ -1083,6 +1208,7 @@ nostub:
|
||||
smart_str_free(&main_metadata_str);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (main_metadata_str.len != php_stream_write(pass.filefp, main_metadata_str.c, main_metadata_str.len)) {
|
||||
php_stream_close(pass.filefp);
|
||||
if (error) {
|
||||
@ -1094,7 +1220,9 @@ nostub:
|
||||
smart_str_free(&main_metadata_str);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
smart_str_free(&main_metadata_str);
|
||||
|
||||
} else {
|
||||
if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) {
|
||||
php_stream_close(pass.filefp);
|
||||
@ -1107,17 +1235,21 @@ nostub:
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
if (phar->fp && pass.free_fp) {
|
||||
php_stream_close(phar->fp);
|
||||
}
|
||||
|
||||
if (phar->ufp) {
|
||||
if (pass.free_ufp) {
|
||||
php_stream_close(phar->ufp);
|
||||
}
|
||||
phar->ufp = NULL;
|
||||
}
|
||||
|
||||
/* re-open */
|
||||
phar->is_brandnew = 0;
|
||||
|
||||
if (phar->donotflush) {
|
||||
/* deferred flush */
|
||||
phar->fp = pass.filefp;
|
||||
|
Loading…
Reference in New Issue
Block a user