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