mirror of
https://github.com/php/php-src.git
synced 2026-04-27 18:23:26 +02:00
throw exceptions from Phar object, and errors from stream wrapper
# we need to account for uncaught exceptions in shutdown, 2 tests leak because of this
This commit is contained in:
+2
-2
@@ -23,8 +23,8 @@ Version 1.0.0
|
||||
to Phar class [Greg]
|
||||
X add PharFileInfo::setMetaData($metadata) [Marcus]
|
||||
X add PharFileInfo::getMetaData() [Marcus]
|
||||
* always throw exceptions from the Phar object, and E_RECOVERABLE_ERROR from
|
||||
streams interface
|
||||
X always throw exceptions from the Phar object, and E_RECOVERABLE_ERROR from
|
||||
streams interface [Greg]
|
||||
X Phar archive metadata Phar::setMetaData($metadata) Phar::getMetaData() [Greg]
|
||||
X support rename() in stream wrapper [Greg]
|
||||
|
||||
|
||||
+342
-211
@@ -192,32 +192,40 @@ static void destroy_phar_manifest(void *pDest) /* {{{ */
|
||||
* Looks up a phar archive in the filename map, connecting it to the alias
|
||||
* (if any) or returns null
|
||||
*/
|
||||
static phar_archive_data * phar_get_archive(char *fname, int fname_len, char *alias, int alias_len TSRMLS_DC) /* {{{ */
|
||||
static int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
phar_archive_data *fd, **fd_ptr;
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
if (alias && alias_len) {
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
|
||||
if (fname && (fname_len != (*fd_ptr)->fname_len || strncmp(fname, (*fd_ptr)->fname, fname_len))) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname);
|
||||
return NULL;
|
||||
if (error) {
|
||||
spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
return *fd_ptr;
|
||||
*archive = *fd_ptr;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
if (fname && fname_len) {
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void**)&fd_ptr)) {
|
||||
*archive = *fd_ptr;
|
||||
fd = *fd_ptr;
|
||||
if (alias && alias_len) {
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&fd, sizeof(phar_archive_data*), NULL);
|
||||
}
|
||||
return fd;
|
||||
return SUCCESS;
|
||||
}
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), fname, fname_len, (void**)&fd_ptr)) {
|
||||
return *fd_ptr;
|
||||
*archive = *fd_ptr;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -283,97 +291,98 @@ static int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
if ((phar = phar_get_archive(fname, fname_len, NULL, 0 TSRMLS_CC)) != NULL) {
|
||||
if ((entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC)) != NULL) {
|
||||
if (entry->is_modified && !for_write) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
if (entry->fp_refcount && for_write) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
if (entry->is_deleted) {
|
||||
if (!for_create) {
|
||||
return FAILURE;
|
||||
}
|
||||
entry->is_deleted = 0;
|
||||
}
|
||||
*ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
|
||||
(*ret)->position = 0;
|
||||
(*ret)->phar = phar;
|
||||
(*ret)->internal_file = entry;
|
||||
if (entry->fp) {
|
||||
/* make a copy */
|
||||
if (for_trunc) {
|
||||
#if PHP_VERSION_ID < 50202
|
||||
if (php_stream_is(entry->fp, PHP_STREAM_IS_TEMP)) {
|
||||
if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_MEMORY)) {
|
||||
php_stream *inner = *(php_stream**)entry->fp->abstract;
|
||||
php_stream_memory_data *memfp = (php_stream_memory_data*)inner->abstract;
|
||||
memfp->fpos = 0;
|
||||
memfp->fsize = 0;
|
||||
} else if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_STDIO)) {
|
||||
php_stream_truncate_set_size(*(php_stream**)entry->fp->abstract, 0);
|
||||
} else {
|
||||
efree(*ret);
|
||||
*ret = NULL;
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, no truncate support", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
} else if (php_stream_is(entry->fp, PHP_STREAM_IS_STDIO)) {
|
||||
php_stream_truncate_set_size(entry->fp, 0);
|
||||
} else {
|
||||
efree(*ret);
|
||||
*ret = NULL;
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, no truncate support", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
#else
|
||||
php_stream_truncate_set_size(entry->fp, 0);
|
||||
#endif
|
||||
entry->is_modified = 1;
|
||||
phar->is_modified = 1;
|
||||
/* reset file size */
|
||||
entry->uncompressed_filesize = 0;
|
||||
entry->compressed_filesize = 0;
|
||||
entry->crc32 = 0;
|
||||
} else if (for_append) {
|
||||
php_stream_seek(entry->fp, 0, SEEK_END);
|
||||
}
|
||||
(*ret)->fp = entry->fp;
|
||||
} else {
|
||||
(*ret)->fp = 0;
|
||||
if (for_write) {
|
||||
/* open a new temp file for writing */
|
||||
entry->fp = php_stream_fopen_tmpfile();
|
||||
(*ret)->fp = entry->fp;
|
||||
entry->is_modified = 1;
|
||||
phar->is_modified = 1;
|
||||
/* reset file size */
|
||||
entry->uncompressed_filesize = 0;
|
||||
entry->compressed_filesize = 0;
|
||||
entry->crc32 = 0;
|
||||
entry->flags = PHAR_ENT_PERM_DEF_FILE;
|
||||
}
|
||||
}
|
||||
entry->fp_refcount++;
|
||||
entry->phar->refcount++;
|
||||
return SUCCESS;
|
||||
}
|
||||
if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error TSRMLS_CC)) {
|
||||
return FAILURE;
|
||||
}
|
||||
if ((entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC)) == NULL) {
|
||||
if (for_create && !PHAR_G(readonly)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
return FAILURE;
|
||||
if (entry->is_modified && !for_write) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
if (entry->fp_refcount && for_write) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
if (entry->is_deleted) {
|
||||
if (!for_create) {
|
||||
return FAILURE;
|
||||
}
|
||||
entry->is_deleted = 0;
|
||||
}
|
||||
*ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
|
||||
(*ret)->position = 0;
|
||||
(*ret)->phar = phar;
|
||||
(*ret)->internal_file = entry;
|
||||
if (entry->fp) {
|
||||
/* make a copy */
|
||||
if (for_trunc) {
|
||||
#if PHP_VERSION_ID < 50202
|
||||
if (php_stream_is(entry->fp, PHP_STREAM_IS_TEMP)) {
|
||||
if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_MEMORY)) {
|
||||
php_stream *inner = *(php_stream**)entry->fp->abstract;
|
||||
php_stream_memory_data *memfp = (php_stream_memory_data*)inner->abstract;
|
||||
memfp->fpos = 0;
|
||||
memfp->fsize = 0;
|
||||
} else if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_STDIO)) {
|
||||
php_stream_truncate_set_size(*(php_stream**)entry->fp->abstract, 0);
|
||||
} else {
|
||||
efree(*ret);
|
||||
*ret = NULL;
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, no truncate support", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
} else if (php_stream_is(entry->fp, PHP_STREAM_IS_STDIO)) {
|
||||
php_stream_truncate_set_size(entry->fp, 0);
|
||||
} else {
|
||||
efree(*ret);
|
||||
*ret = NULL;
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: file \"%s\" cannot opened for writing, no truncate support", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
#else
|
||||
php_stream_truncate_set_size(entry->fp, 0);
|
||||
#endif
|
||||
entry->is_modified = 1;
|
||||
phar->is_modified = 1;
|
||||
/* reset file size */
|
||||
entry->uncompressed_filesize = 0;
|
||||
entry->compressed_filesize = 0;
|
||||
entry->crc32 = 0;
|
||||
} else if (for_append) {
|
||||
php_stream_seek(entry->fp, 0, SEEK_END);
|
||||
}
|
||||
(*ret)->fp = entry->fp;
|
||||
} else {
|
||||
(*ret)->fp = 0;
|
||||
if (for_write) {
|
||||
/* open a new temp file for writing */
|
||||
entry->fp = php_stream_fopen_tmpfile();
|
||||
(*ret)->fp = entry->fp;
|
||||
entry->is_modified = 1;
|
||||
phar->is_modified = 1;
|
||||
/* reset file size */
|
||||
entry->uncompressed_filesize = 0;
|
||||
entry->compressed_filesize = 0;
|
||||
entry->crc32 = 0;
|
||||
entry->flags = PHAR_ENT_PERM_DEF_FILE;
|
||||
}
|
||||
}
|
||||
entry->fp_refcount++;
|
||||
entry->phar->refcount++;
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -395,10 +404,10 @@ int phar_entry_delref(phar_entry_data *idata TSRMLS_DC) /* {{{ */
|
||||
/**
|
||||
* Removes an entry, either by actually removingit or by marking it.
|
||||
*/
|
||||
void phar_entry_remove(phar_entry_data *idata TSRMLS_DC) /* {{{ */
|
||||
void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (!idata->phar->donotflush) {
|
||||
phar_flush(idata->internal_file->phar, 0, 0 TSRMLS_CC);
|
||||
phar_flush(idata->internal_file->phar, 0, 0, error TSRMLS_CC);
|
||||
}
|
||||
if (idata->internal_file->fp_refcount < 2) {
|
||||
if (idata->fp && idata->fp != idata->internal_file->fp) {
|
||||
@@ -423,7 +432,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
|
||||
phar_entry_info *entry, etemp;
|
||||
phar_entry_data *ret;
|
||||
|
||||
if ((phar = phar_get_archive(fname, fname_len, NULL, 0 TSRMLS_CC)) == NULL) {
|
||||
if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error TSRMLS_CC)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -464,7 +473,9 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
|
||||
|
||||
#define MAPPHAR_ALLOC_FAIL(msg) \
|
||||
php_stream_close(fp);\
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, msg, fname);\
|
||||
if (error) {\
|
||||
spprintf(error, 0, msg, fname);\
|
||||
}\
|
||||
return FAILURE;
|
||||
|
||||
#define MAPPHAR_FAIL(msg) \
|
||||
@@ -500,11 +511,11 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
|
||||
/**
|
||||
* Open an already loaded phar
|
||||
*/
|
||||
static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC) /* {{{ */
|
||||
static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
phar_archive_data *phar;
|
||||
|
||||
if ((phar = phar_get_archive(fname, fname_len, alias, alias_len TSRMLS_CC)) != NULL
|
||||
if (SUCCESS == phar_get_archive(&phar, fname, fname_len, alias, alias_len, error TSRMLS_CC)
|
||||
&& fname_len == phar->fname_len
|
||||
&& !strncmp(fname, phar->fname, fname_len)
|
||||
) {
|
||||
@@ -517,7 +528,11 @@ static int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_l
|
||||
*pphar = NULL;
|
||||
}
|
||||
if (phar && alias && (options & REPORT_ERRORS)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname);
|
||||
if (error) {
|
||||
if (*error) {
|
||||
spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -566,7 +581,7 @@ static int phar_parse_metadata(php_stream *fp, char **buffer, char *endbuffer, z
|
||||
* This is used by phar_open_filename to process the manifest, but can be called
|
||||
* directly.
|
||||
*/
|
||||
int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int alias_len, long halt_offset, phar_archive_data** pphar TSRMLS_DC) /* {{{ */
|
||||
int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int alias_len, long halt_offset, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char b32[4], *buffer, *endbuffer, *savebuf;
|
||||
phar_archive_data *mydata = NULL;
|
||||
@@ -580,6 +595,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
if (pphar) {
|
||||
*pphar = NULL;
|
||||
}
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
/* check for ?>\n and increment accordingly */
|
||||
if (-1 == php_stream_seek(fp, halt_offset, SEEK_SET)) {
|
||||
@@ -644,7 +662,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
if ((manifest_ver & PHAR_API_VER_MASK) < PHAR_API_MIN_READ) {
|
||||
efree(savebuf);
|
||||
php_stream_close(fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar \"%s\" is API version %1.u.%1.u.%1.u, and cannot be processed", fname, manifest_ver >> 12, (manifest_ver >> 8) & 0xF, (manifest_ver >> 4) & 0x0F);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar \"%s\" is API version %1.u.%1.u.%1.u, and cannot be processed", fname, manifest_ver >> 12, (manifest_ver >> 8) & 0xF, (manifest_ver >> 4) & 0x0F);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -666,7 +686,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
|| memcmp(sig_buf+4, "GBMB", 4)) {
|
||||
efree(savebuf);
|
||||
php_stream_close(fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar \"%s\" has a broken signature", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar \"%s\" has a broken signature", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
PHAR_GET_32(sig_ptr, sig_flags);
|
||||
@@ -697,7 +719,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
|| memcmp(digest, saved, sizeof(digest))) {
|
||||
efree(savebuf);
|
||||
php_stream_close(fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar \"%s\" has a broken signature", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar \"%s\" has a broken signature", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -736,7 +760,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
|| memcmp(digest, saved, sizeof(digest))) {
|
||||
efree(savebuf);
|
||||
php_stream_close(fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar \"%s\" has a broken signature", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar \"%s\" has a broken signature", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -752,13 +778,17 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
default:
|
||||
efree(savebuf);
|
||||
php_stream_close(fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar \"%s\" has a broken signature", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar \"%s\" has a broken signature", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
} else if (PHAR_G(require_hash)) {
|
||||
efree(savebuf);
|
||||
php_stream_close(fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar \"%s\" does not have a signature", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar \"%s\" does not have a signature", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
} else {
|
||||
sig_flags = 0;
|
||||
@@ -784,7 +814,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
if (signature) {
|
||||
efree(signature);
|
||||
}
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "cannot load phar \"%s\" with implicit alias \"%s\" under different alias \"%s\"", fname, buffer, alias);
|
||||
if (error) {
|
||||
spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%s\" under different alias \"%s\"", fname, buffer, alias);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
alias_len = tmp_len;
|
||||
@@ -914,7 +946,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
/**
|
||||
* Create or open a phar for writing
|
||||
*/
|
||||
int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC) /* {{{ */
|
||||
int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
phar_archive_data *mydata;
|
||||
int register_alias;
|
||||
@@ -923,8 +955,11 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
|
||||
if (!pphar) {
|
||||
pphar = &mydata;
|
||||
}
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
if (phar_open_loaded(fname, fname_len, alias, alias_len, options, pphar TSRMLS_CC) == SUCCESS) {
|
||||
if (phar_open_loaded(fname, fname_len, alias, alias_len, options, pphar, 0 TSRMLS_CC) == SUCCESS) {
|
||||
if (!PHAR_G(readonly)) {
|
||||
(*pphar)->is_writeable = 1;
|
||||
}
|
||||
@@ -943,7 +978,7 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
|
||||
|
||||
fp = php_stream_open_wrapper(fname, PHAR_G(readonly)?"rb":"r+b", IGNORE_URL|STREAM_MUST_SEEK|0, NULL);
|
||||
|
||||
if (fp && phar_open_fp(fp, fname, fname_len, alias, alias_len, options, pphar TSRMLS_CC) == SUCCESS) {
|
||||
if (fp && phar_open_fp(fp, fname, fname_len, alias, alias_len, options, pphar, 0 TSRMLS_CC) == SUCCESS) {
|
||||
if (!PHAR_G(readonly)) {
|
||||
(*pphar)->is_writeable = 1;
|
||||
}
|
||||
@@ -952,7 +987,9 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
if (options & REPORT_ERRORS) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "creating archive \"%s\" disabled by INI setting", fname);
|
||||
if (*error) {
|
||||
spprintf(error, 0, "creating archive \"%s\" disabled by INI setting", fname);
|
||||
}
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -997,12 +1034,18 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
|
||||
* that the manifest is proper, then pass it to phar_open_file(). SUCCESS
|
||||
* or FAILURE is returned and pphar is set to a pointer to the phar's manifest
|
||||
*/
|
||||
int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC) /* {{{ */
|
||||
int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_stream *fp;
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
if (phar_open_loaded(fname, fname_len, alias, alias_len, options, pphar TSRMLS_CC) == SUCCESS) {
|
||||
if (phar_open_loaded(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC) == SUCCESS) {
|
||||
return SUCCESS;
|
||||
} else if (*error) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 6
|
||||
@@ -1019,12 +1062,14 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i
|
||||
|
||||
if (!fp) {
|
||||
if (options & REPORT_ERRORS) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open phar for reading \"%s\"", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to open phar for reading \"%s\"", fname);
|
||||
}
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return phar_open_fp(fp, fname, fname_len, alias, alias_len, options, pphar TSRMLS_CC);
|
||||
return phar_open_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
|
||||
}
|
||||
/* }}}*/
|
||||
|
||||
@@ -1033,7 +1078,7 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i
|
||||
* that the manifest is proper, then pass it to phar_open_file(). SUCCESS
|
||||
* or FAILURE is returned and pphar is set to a pointer to the phar's manifest
|
||||
*/
|
||||
static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC) /* {{{ */
|
||||
static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
const char token[] = "__HALT_COMPILER();";
|
||||
char *pos, buffer[1024 + sizeof(token)];
|
||||
@@ -1044,6 +1089,9 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias,
|
||||
/* Maybe it's better to compile the file instead of just searching, */
|
||||
/* but we only want the offset. So we want a .re scanner to find it. */
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
if (-1 == php_stream_rewind(fp)) {
|
||||
MAPPHAR_ALLOC_FAIL("cannot rewind phar \"%s\"")
|
||||
}
|
||||
@@ -1057,7 +1105,7 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias,
|
||||
}
|
||||
if ((pos = strstr(buffer, token)) != NULL) {
|
||||
halt_offset += (pos - buffer); /* no -tokenlen+tokenlen here */
|
||||
return phar_open_file(fp, fname, fname_len, alias, alias_len, halt_offset, pphar TSRMLS_CC);
|
||||
return phar_open_file(fp, fname, fname_len, alias, alias_len, halt_offset, pphar, error TSRMLS_CC);
|
||||
}
|
||||
|
||||
halt_offset += readsize;
|
||||
@@ -1128,7 +1176,7 @@ int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_le
|
||||
static php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode, int options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_url *resource;
|
||||
char *arch, *entry;
|
||||
char *arch, *entry, *error;
|
||||
int arch_len, entry_len;
|
||||
|
||||
if (!strncasecmp(filename, "phar://", 7)) {
|
||||
@@ -1165,14 +1213,22 @@ static php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
if (phar_open_or_create_filename(resource->host, arch_len, NULL, 0, options, NULL TSRMLS_CC) == FAILURE)
|
||||
if (phar_open_or_create_filename(resource->host, arch_len, NULL, 0, options, NULL, &error TSRMLS_CC) == FAILURE)
|
||||
{
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (phar_open_filename(resource->host, arch_len, NULL, 0, options, NULL TSRMLS_CC) == FAILURE)
|
||||
if (phar_open_filename(resource->host, arch_len, NULL, 0, options, NULL, &error TSRMLS_CC) == FAILURE)
|
||||
{
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1188,7 +1244,7 @@ static php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char
|
||||
* Invoked when a user calls Phar::mapPhar() from within an executing .phar
|
||||
* to set up its manifest directly
|
||||
*/
|
||||
int phar_open_compiled_file(char *alias, int alias_len TSRMLS_DC) /* {{{ */
|
||||
int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char *fname;
|
||||
long halt_offset;
|
||||
@@ -1196,23 +1252,30 @@ int phar_open_compiled_file(char *alias, int alias_len TSRMLS_DC) /* {{{ */
|
||||
php_stream *fp;
|
||||
int fname_len;
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
fname = zend_get_executed_filename(TSRMLS_C);
|
||||
|
||||
fname_len = strlen(fname);
|
||||
|
||||
if (alias && phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL TSRMLS_CC) == SUCCESS) {
|
||||
if (alias && phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (!strcmp(fname, "[no active file]")) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "cannot initialize a phar outside of PHP execution");
|
||||
if (error) {
|
||||
spprintf(error, 0, "cannot initialize a phar outside of PHP execution");
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(halt_constant);
|
||||
if (0 == zend_get_constant("__COMPILER_HALT_OFFSET__", 24, halt_constant TSRMLS_CC)) {
|
||||
FREE_ZVAL(halt_constant);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "__HALT_COMPILER(); must be declared in a phar");
|
||||
if (error) {
|
||||
spprintf(error, 0, "__HALT_COMPILER(); must be declared in a phar");
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
halt_offset = Z_LVAL(*halt_constant);
|
||||
@@ -1221,11 +1284,13 @@ int phar_open_compiled_file(char *alias, int alias_len TSRMLS_DC) /* {{{ */
|
||||
fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
|
||||
|
||||
if (!fp) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open phar for reading \"%s\"", fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to open phar for reading \"%s\"", fname);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return phar_open_file(fp, fname, fname_len, alias, alias_len, halt_offset, NULL TSRMLS_CC);
|
||||
return phar_open_file(fp, fname, fname_len, alias, alias_len, halt_offset, NULL, error TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1703,7 +1768,7 @@ static size_t phar_stream_write(php_stream *stream, const char *buf, size_t coun
|
||||
|
||||
php_stream_seek(data->fp, data->position, SEEK_SET);
|
||||
if (count != php_stream_write(data->fp, buf, count)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar error: Could not write %d characters to \"%s\" in phar \"%s\"", (int) count, data->internal_file->filename, data->phar->fname);
|
||||
php_stream_wrapper_log_error(stream->wrapper, stream->flags TSRMLS_CC, "phar error: Could not write %d characters to \"%s\" in phar \"%s\"", (int) count, data->internal_file->filename, data->phar->fname);
|
||||
return -1;
|
||||
}
|
||||
data->position = php_stream_tell(data->fp);
|
||||
@@ -1769,7 +1834,7 @@ static int phar_flush_clean_deleted_apply(void *data TSRMLS_DC) /* {{{ */
|
||||
* user_stub contains either a string, or a resource pointer, if len is a negative length.
|
||||
* user_stub and len should be both 0 if the default or existing stub should be used
|
||||
*/
|
||||
int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC) /* {{{ */
|
||||
int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
static const char newstub[] = "<?php __HALT_COMPILER();";
|
||||
phar_entry_info *entry;
|
||||
@@ -1790,6 +1855,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
if (archive->fp && !archive->is_brandnew) {
|
||||
oldfile = archive->fp;
|
||||
closeoldfile = 0;
|
||||
@@ -1808,7 +1876,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to read resource to copy stub to new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to read resource to copy stub to new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
if (len == -1) {
|
||||
@@ -1822,7 +1892,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to copy stub from resource to new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to copy stub from resource to new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
archive->halt_offset = offset;
|
||||
@@ -1832,7 +1904,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to create stub from string in new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to create stub from string in new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
archive->halt_offset = len;
|
||||
@@ -1844,7 +1918,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to copy stub of old phar to new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to copy stub of old phar to new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
} else {
|
||||
@@ -1855,7 +1931,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to create stub in new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to create stub in new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
@@ -1928,9 +2006,13 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to gzip compress file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to gzip compress file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
}
|
||||
efree(buf);
|
||||
return EOF;
|
||||
@@ -1946,7 +2028,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
read = php_stream_read(file, buf, 8192);
|
||||
if (read) {
|
||||
if (read != php_stream_write(entry->cfp, buf, read)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write to file \"%s\" while creating new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write to file \"%s\" while creating new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
efree(buf);
|
||||
php_stream_filter_remove(filter, 1 TSRMLS_CC);
|
||||
php_stream_close(entry->cfp);
|
||||
@@ -2000,7 +2084,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
archive->alias_len = restore_alias_len;
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write manifest header of new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
@@ -2017,7 +2103,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
archive->alias_len = restore_alias_len;
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write manifest meta-data of new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
} else {
|
||||
@@ -2028,7 +2116,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
archive->alias_len = restore_alias_len;
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write manifest header of new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
@@ -2055,7 +2145,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
/* set the manifest meta-data:
|
||||
@@ -2087,7 +2179,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
smart_str_free(&metadata_str);
|
||||
@@ -2116,7 +2210,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
file = oldfile;
|
||||
@@ -2131,7 +2227,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write contents of file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
entry->is_modified = 0;
|
||||
@@ -2226,7 +2324,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
archive->fp = php_stream_open_wrapper(archive->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
|
||||
if (!archive->fp) {
|
||||
archive->fp = newfile;
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open new phar \"%s\" for writing", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to open new phar \"%s\" for writing", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
php_stream_copy_to_stream(newfile, archive->fp, PHP_STREAM_COPY_ALL);
|
||||
@@ -2235,7 +2335,9 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
}
|
||||
|
||||
if (-1 == php_stream_seek(archive->fp, archive->halt_offset, SEEK_SET)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", archive->fname);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
@@ -2248,8 +2350,15 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC)
|
||||
*/
|
||||
static int phar_stream_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char *error;
|
||||
int ret;
|
||||
if (stream->mode[0] == 'w' || (stream->mode[0] == 'r' && stream->mode[1] == '+')) {
|
||||
return phar_flush(((phar_entry_data *)stream->abstract)->internal_file->phar, 0, 0 TSRMLS_CC);
|
||||
ret = phar_flush(((phar_entry_data *)stream->abstract)->internal_file->phar, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(stream->wrapper, REPORT_ERRORS TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return EOF;
|
||||
}
|
||||
@@ -2375,7 +2484,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
|
||||
php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_url *resource = NULL;
|
||||
char *internal_file, *key;
|
||||
char *internal_file, *key, *error;
|
||||
uint keylen;
|
||||
ulong unused;
|
||||
phar_archive_data *phar;
|
||||
@@ -2402,38 +2511,47 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
|
||||
|
||||
internal_file = resource->path + 1; /* strip leading "/" */
|
||||
/* find the phar in our trusty global hash indexed by alias (host of phar://blah.phar/file.whatever) */
|
||||
if ((phar = phar_get_archive(resource->host, strlen(resource->host), NULL, 0 TSRMLS_CC)) != NULL) {
|
||||
if (*internal_file == '\0') {
|
||||
/* root directory requested */
|
||||
phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
if (FAILURE == phar_get_archive(&phar, resource->host, strlen(resource->host), NULL, 0, &error TSRMLS_CC)) {
|
||||
php_url_free(resource);
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, flags TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
if (!phar->manifest.arBuckets) {
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
}
|
||||
/* search through the manifest of files, and if we have an exact match, it's a file */
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) {
|
||||
phar_dostat(phar, entry, ssb, 0, phar->alias, phar->alias_len TSRMLS_CC);
|
||||
} else {
|
||||
/* search for directory (partial match of a file) */
|
||||
zend_hash_internal_pointer_reset(&phar->manifest);
|
||||
while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
|
||||
if (HASH_KEY_NON_EXISTANT !=
|
||||
zend_hash_get_current_key_ex(
|
||||
&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
|
||||
if (0 == memcmp(internal_file, key, strlen(internal_file))) {
|
||||
/* directory found, all dirs have the same stat */
|
||||
if (key[strlen(internal_file)] == '/') {
|
||||
phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (error) {
|
||||
efree(error);
|
||||
}
|
||||
if (*internal_file == '\0') {
|
||||
/* root directory requested */
|
||||
phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
}
|
||||
if (!phar->manifest.arBuckets) {
|
||||
php_url_free(resource);
|
||||
return 0;
|
||||
}
|
||||
/* search through the manifest of files, and if we have an exact match, it's a file */
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) {
|
||||
phar_dostat(phar, entry, ssb, 0, phar->alias, phar->alias_len TSRMLS_CC);
|
||||
} else {
|
||||
/* search for directory (partial match of a file) */
|
||||
zend_hash_internal_pointer_reset(&phar->manifest);
|
||||
while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
|
||||
if (HASH_KEY_NON_EXISTANT !=
|
||||
zend_hash_get_current_key_ex(
|
||||
&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
|
||||
if (0 == memcmp(internal_file, key, strlen(internal_file))) {
|
||||
/* directory found, all dirs have the same stat */
|
||||
if (key[strlen(internal_file)] == '/') {
|
||||
phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2646,7 +2764,11 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio
|
||||
}
|
||||
php_url_free(resource);
|
||||
efree(internal_file);
|
||||
phar_entry_remove(idata TSRMLS_CC);
|
||||
phar_entry_remove(idata, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -2805,7 +2927,7 @@ static php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path
|
||||
{
|
||||
php_url *resource = NULL;
|
||||
php_stream *ret;
|
||||
char *internal_file, *key;
|
||||
char *internal_file, *key, *error;
|
||||
uint keylen;
|
||||
ulong unused;
|
||||
phar_archive_data *phar;
|
||||
@@ -2836,40 +2958,49 @@ static php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path
|
||||
}
|
||||
|
||||
internal_file = resource->path + 1; /* strip leading "/" */
|
||||
if ((phar = phar_get_archive(resource->host, strlen(resource->host), NULL, 0 TSRMLS_CC)) != NULL) {
|
||||
if (*internal_file == '\0') {
|
||||
/* root directory requested */
|
||||
internal_file = estrndup(internal_file - 1, 1);
|
||||
ret = phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC);
|
||||
php_url_free(resource);
|
||||
return ret;
|
||||
if (FAILURE == phar_get_archive(&phar, resource->host, strlen(resource->host), NULL, 0, &error TSRMLS_CC)) {
|
||||
if (error) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
if (!phar->manifest.arBuckets) {
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) {
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
} else {
|
||||
/* search for directory */
|
||||
zend_hash_internal_pointer_reset(&phar->manifest);
|
||||
while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
|
||||
if (HASH_KEY_NON_EXISTANT !=
|
||||
zend_hash_get_current_key_ex(
|
||||
&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
|
||||
if (0 == memcmp(key, internal_file, strlen(internal_file))) {
|
||||
/* directory found */
|
||||
internal_file = estrndup(internal_file,
|
||||
strlen(internal_file));
|
||||
php_url_free(resource);
|
||||
return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
if (error) {
|
||||
efree(error);
|
||||
}
|
||||
if (*internal_file == '\0') {
|
||||
/* root directory requested */
|
||||
internal_file = estrndup(internal_file - 1, 1);
|
||||
ret = phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC);
|
||||
php_url_free(resource);
|
||||
return ret;
|
||||
}
|
||||
if (!phar->manifest.arBuckets) {
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
}
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) {
|
||||
php_url_free(resource);
|
||||
return NULL;
|
||||
} else {
|
||||
/* search for directory */
|
||||
zend_hash_internal_pointer_reset(&phar->manifest);
|
||||
while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
|
||||
if (HASH_KEY_NON_EXISTANT !=
|
||||
zend_hash_get_current_key_ex(
|
||||
&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
|
||||
if (0 == memcmp(key, internal_file, strlen(internal_file))) {
|
||||
/* directory found */
|
||||
internal_file = estrndup(internal_file,
|
||||
strlen(internal_file));
|
||||
php_url_free(resource);
|
||||
return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -214,13 +214,13 @@ BEGIN_EXTERN_C()
|
||||
|
||||
void phar_object_init(TSRMLS_D);
|
||||
|
||||
int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC);
|
||||
int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC);
|
||||
int phar_open_compiled_file(char *alias, int alias_len TSRMLS_DC);
|
||||
int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
|
||||
int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
|
||||
int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC);
|
||||
|
||||
#ifdef PHAR_MAIN
|
||||
|
||||
static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC);
|
||||
static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
|
||||
|
||||
static php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode, int options TSRMLS_DC);
|
||||
|
||||
@@ -253,7 +253,7 @@ int phar_entry_delref(phar_entry_data *idata TSRMLS_DC);
|
||||
|
||||
phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len TSRMLS_DC);
|
||||
phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char **error TSRMLS_DC);
|
||||
int phar_flush(phar_archive_data *archive, char *user_stub, long len TSRMLS_DC);
|
||||
int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC);
|
||||
int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len TSRMLS_DC);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
+116
-34
@@ -22,6 +22,7 @@
|
||||
#include "phar_internal.h"
|
||||
|
||||
static zend_class_entry *phar_ce_archive;
|
||||
static zend_class_entry *phar_ce_PharException;
|
||||
|
||||
#if HAVE_SPL
|
||||
static zend_class_entry *phar_ce_entry;
|
||||
@@ -31,26 +32,34 @@ static zend_class_entry *phar_ce_entry;
|
||||
* Reads the currently executed file (a phar) and registers its manifest */
|
||||
PHP_METHOD(Phar, mapPhar)
|
||||
{
|
||||
char * alias = NULL;
|
||||
char *alias = NULL, *error;
|
||||
int alias_len = 0;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &alias, &alias_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
RETURN_BOOL(phar_open_compiled_file(alias, alias_len TSRMLS_CC) == SUCCESS);
|
||||
RETVAL_BOOL(phar_open_compiled_file(alias, alias_len, &error TSRMLS_CC) == SUCCESS);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto mixed Phar::loadPhar(string filename [, string alias])
|
||||
* Loads any phar archive with an alias */
|
||||
PHP_METHOD(Phar, loadPhar)
|
||||
{
|
||||
char *fname, *alias = NULL;
|
||||
char *fname, *alias = NULL, *error;
|
||||
int fname_len, alias_len = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &fname, &fname_len, &alias, &alias_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
RETURN_BOOL(phar_open_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL TSRMLS_CC) == SUCCESS);
|
||||
RETVAL_BOOL(phar_open_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, &error TSRMLS_CC) == SUCCESS);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto string apiVersion()
|
||||
@@ -117,7 +126,7 @@ PHP_METHOD(Phar, __construct)
|
||||
#if !HAVE_SPL
|
||||
zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Cannot instantiate Phar object without SPL extension");
|
||||
#else
|
||||
char *fname, *alias = NULL;
|
||||
char *fname, *alias = NULL, *error;
|
||||
int fname_len, alias_len = 0;
|
||||
long flags = 0;
|
||||
phar_archive_object *phar_obj;
|
||||
@@ -135,9 +144,15 @@ PHP_METHOD(Phar, __construct)
|
||||
return;
|
||||
}
|
||||
|
||||
if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, &phar_data TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s' with alias '%s'", fname, alias);
|
||||
if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
|
||||
if (error) {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s' with alias '%s': %s", fname, alias, error);
|
||||
efree(error);
|
||||
} else {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s' with alias '%s'", fname, alias);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -215,6 +230,7 @@ PHP_METHOD(Phar, begin)
|
||||
*/
|
||||
PHP_METHOD(Phar, commit)
|
||||
{
|
||||
char *error;
|
||||
PHAR_ARCHIVE_OBJECT();
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
@@ -224,7 +240,11 @@ PHP_METHOD(Phar, commit)
|
||||
|
||||
phar_obj->arc.archive->donotflush = 0;
|
||||
|
||||
phar_flush(phar_obj->arc.archive, 0, 0 TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -234,7 +254,7 @@ PHP_METHOD(Phar, commit)
|
||||
PHP_METHOD(Phar, setStub)
|
||||
{
|
||||
zval *zstub;
|
||||
char *stub;
|
||||
char *stub, *error;
|
||||
int stub_len;
|
||||
long len = -1;
|
||||
php_stream *stream;
|
||||
@@ -252,14 +272,22 @@ PHP_METHOD(Phar, setStub)
|
||||
} else {
|
||||
len = -1;
|
||||
}
|
||||
phar_flush(phar_obj->arc.archive, (char *) &zstub, len TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, (char *) &zstub, len, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot change stub, unable to read from input stream");
|
||||
}
|
||||
} else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &stub, &stub_len) == SUCCESS) {
|
||||
phar_flush(phar_obj->arc.archive, stub, stub_len TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, stub, stub_len, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
@@ -358,23 +386,30 @@ static int pharobj_cancompress(HashTable *manifest TSRMLS_DC) /* {{{ */
|
||||
*/
|
||||
PHP_METHOD(Phar, compressAllFilesGZ)
|
||||
{
|
||||
#if HAVE_ZLIB
|
||||
char *error;
|
||||
#endif
|
||||
PHAR_ARCHIVE_OBJECT();
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Phar is readonly, cannot change compression");
|
||||
}
|
||||
#if HAVE_ZLIB
|
||||
if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Cannot compress all files as Gzip, some are compressed as bzip2 and cannot be uncompressed");
|
||||
}
|
||||
pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_GZ TSRMLS_CC);
|
||||
phar_obj->arc.archive->is_modified = 1;
|
||||
|
||||
phar_flush(phar_obj->arc.archive, 0, 0 TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
#else
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Cannot compress with Gzip compression, zlib extension is not enabled");
|
||||
#endif
|
||||
}
|
||||
@@ -385,23 +420,30 @@ PHP_METHOD(Phar, compressAllFilesGZ)
|
||||
*/
|
||||
PHP_METHOD(Phar, compressAllFilesBZIP2)
|
||||
{
|
||||
#if HAVE_BZ2
|
||||
char *error;
|
||||
#endif
|
||||
PHAR_ARCHIVE_OBJECT();
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Phar is readonly, cannot change compression");
|
||||
}
|
||||
#if HAVE_BZ2
|
||||
if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Cannot compress all files as Bzip2, some are compressed as gzip and cannot be uncompressed");
|
||||
}
|
||||
pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_BZ2 TSRMLS_CC);
|
||||
phar_obj->arc.archive->is_modified = 1;
|
||||
|
||||
phar_flush(phar_obj->arc.archive, 0, 0 TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
#else
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Cannot compress with Bzip2 compression, bz2 extension is not enabled");
|
||||
#endif
|
||||
}
|
||||
@@ -412,20 +454,25 @@ PHP_METHOD(Phar, compressAllFilesBZIP2)
|
||||
*/
|
||||
PHP_METHOD(Phar, uncompressAllFiles)
|
||||
{
|
||||
char *error;
|
||||
PHAR_ARCHIVE_OBJECT();
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Phar is readonly, cannot change compression");
|
||||
}
|
||||
if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
|
||||
"Cannot uncompress all files, some are compressed as bzip2 or gzip and cannot be uncompressed");
|
||||
}
|
||||
pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_NONE TSRMLS_CC);
|
||||
phar_obj->arc.archive->is_modified = 1;
|
||||
|
||||
phar_flush(phar_obj->arc.archive, 0, 0 TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -536,8 +583,12 @@ PHP_METHOD(Phar, offsetSet)
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname);
|
||||
}
|
||||
}
|
||||
phar_flush(phar_obj->arc.archive, 0, 0 TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
|
||||
phar_entry_delref(data TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -547,7 +598,7 @@ PHP_METHOD(Phar, offsetSet)
|
||||
*/
|
||||
PHP_METHOD(Phar, offsetUnset)
|
||||
{
|
||||
char *fname;
|
||||
char *fname, *error;
|
||||
int fname_len;
|
||||
phar_entry_info *entry;
|
||||
PHAR_ARCHIVE_OBJECT();
|
||||
@@ -570,7 +621,11 @@ PHP_METHOD(Phar, offsetUnset)
|
||||
entry->is_modified = 0;
|
||||
entry->is_deleted = 1;
|
||||
/* we need to "flush" the stream to save the newly deleted file on disk */
|
||||
phar_flush(phar_obj->arc.archive, 0, 0 TSRMLS_CC);
|
||||
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
} else {
|
||||
@@ -663,7 +718,7 @@ PHP_METHOD(Phar, setMetadata)
|
||||
*/
|
||||
PHP_METHOD(PharFileInfo, __construct)
|
||||
{
|
||||
char *fname, *arch, *entry;
|
||||
char *fname, *arch, *entry, *error;
|
||||
int fname_len, arch_len, entry_len;
|
||||
phar_entry_object *entry_obj;
|
||||
phar_entry_info *entry_info;
|
||||
@@ -689,11 +744,17 @@ PHP_METHOD(PharFileInfo, __construct)
|
||||
return;
|
||||
}
|
||||
|
||||
if (phar_open_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data TSRMLS_CC) == FAILURE) {
|
||||
if (phar_open_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
|
||||
efree(arch);
|
||||
efree(entry);
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s'", fname);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s': %s", fname, error);
|
||||
efree(error);
|
||||
} else {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s'", fname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -849,6 +910,7 @@ PHP_METHOD(PharFileInfo, setMetadata)
|
||||
PHP_METHOD(PharFileInfo, setCompressedGZ)
|
||||
{
|
||||
#if HAVE_ZLIB
|
||||
char *error;
|
||||
PHAR_ENTRY_OBJECT();
|
||||
|
||||
if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) {
|
||||
@@ -868,7 +930,11 @@ PHP_METHOD(PharFileInfo, setCompressedGZ)
|
||||
entry_obj->ent.entry->phar->is_modified = 1;
|
||||
entry_obj->ent.entry->is_modified = 1;
|
||||
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0 TSRMLS_CC);
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
#else
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
@@ -883,6 +949,7 @@ PHP_METHOD(PharFileInfo, setCompressedGZ)
|
||||
PHP_METHOD(PharFileInfo, setCompressedBZIP2)
|
||||
{
|
||||
#if HAVE_BZ2
|
||||
char *error;
|
||||
PHAR_ENTRY_OBJECT();
|
||||
|
||||
if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
|
||||
@@ -902,7 +969,11 @@ PHP_METHOD(PharFileInfo, setCompressedBZIP2)
|
||||
entry_obj->ent.entry->phar->is_modified = 1;
|
||||
entry_obj->ent.entry->is_modified = 1;
|
||||
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0 TSRMLS_CC);
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
#else
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
|
||||
@@ -916,7 +987,7 @@ PHP_METHOD(PharFileInfo, setCompressedBZIP2)
|
||||
*/
|
||||
PHP_METHOD(PharFileInfo, setUncompressed)
|
||||
{
|
||||
char *fname;
|
||||
char *fname, *error;
|
||||
int fname_len;
|
||||
PHAR_ENTRY_OBJECT();
|
||||
|
||||
@@ -953,7 +1024,11 @@ PHP_METHOD(PharFileInfo, setUncompressed)
|
||||
entry_obj->ent.entry->phar->is_modified = 1;
|
||||
entry_obj->ent.entry->is_modified = 1;
|
||||
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0 TSRMLS_CC);
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -1060,6 +1135,10 @@ zend_function_entry php_entry_methods[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
#endif
|
||||
|
||||
zend_function_entry phar_exception_methods[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#define REGISTER_PHAR_CLASS_CONST_LONG(class_name, const_name, value) \
|
||||
@@ -1069,6 +1148,9 @@ void phar_object_init(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PharException", phar_exception_methods);
|
||||
phar_ce_PharException = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
||||
|
||||
#if HAVE_SPL
|
||||
INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods);
|
||||
phar_ce_archive = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL TSRMLS_CC);
|
||||
|
||||
@@ -4,12 +4,16 @@ Phar::mapPhar truncated manifest/improper params
|
||||
<?php if (!extension_loaded("phar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
Phar::mapPhar(5, 5);
|
||||
Phar::mapPhar(5, 'hio');
|
||||
Phar::mapPhar(5, 'hio', 'hi');
|
||||
|
||||
Phar::mapPhar();
|
||||
Phar::mapPhar(5);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
__HALT_COMPILER(); ?>
|
||||
--EXPECTF--
|
||||
Warning: Phar::mapPhar() expects at most 1 parameter, 2 given in %s002.php on line %d
|
||||
@@ -17,5 +21,4 @@ Warning: Phar::mapPhar() expects at most 1 parameter, 2 given in %s002.php on li
|
||||
Warning: Phar::mapPhar() expects at most 1 parameter, 2 given in %s002.php on line %d
|
||||
|
||||
Warning: Phar::mapPhar() expects at most 1 parameter, 3 given in %s002.php on line %d
|
||||
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s" (truncated manifest) in %s on line %d
|
||||
internal corruption of phar "%s002.php" (truncated manifest)
|
||||
@@ -4,7 +4,11 @@ Phar::mapPhar no __HALT_COMPILER();
|
||||
<?php if (!extension_loaded("phar")) print "skip";?>
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
Phar::mapPhar('hio');
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): __HALT_COMPILER(); must be declared in a phar in %s on line %d
|
||||
__HALT_COMPILER(); must be declared in a phar
|
||||
|
||||
@@ -4,7 +4,11 @@ Phar::mapPhar truncated manifest (none)
|
||||
<?php if (!extension_loaded("phar")) print "skip";?>
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
Phar::mapPhar('hio');
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
__HALT_COMPILER(); ?>()
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s" (truncated manifest) in %s on line %d
|
||||
internal corruption of phar "%s" (truncated manifest)
|
||||
|
||||
@@ -4,7 +4,11 @@ Phar::mapPhar truncated manifest (manifest length truncated)
|
||||
<?php if (!extension_loaded("phar")) print "skip";?>
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
Phar::mapPhar('hio');
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
__HALT_COMPILER(); ?>
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s" (truncated manifest) in %s on line %d
|
||||
internal corruption of phar "%s" (truncated manifest)
|
||||
|
||||
@@ -4,7 +4,11 @@ Phar::mapPhar manifest too big
|
||||
<?php if (!extension_loaded("phar")) print "skip";?>
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
Phar::mapPhar('hio');
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
__HALT_COMPILER(); ?>~~~~
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): manifest cannot be larger than 1 MB in phar "%s" in %s on line %d
|
||||
manifest cannot be larger than 1 MB in phar "%s"
|
||||
|
||||
@@ -9,9 +9,13 @@ Phar::mapPhar('hio');
|
||||
__HALT_COMPILER(); ?>";
|
||||
$file .= pack('V', 500) . 'notenough';
|
||||
file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file);
|
||||
try {
|
||||
include dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s" (truncated manifest) in %s on line %d
|
||||
internal corruption of phar "%s" (truncated manifest)
|
||||
|
||||
@@ -11,9 +11,13 @@ Phar::mapPhar('hio');
|
||||
__HALT_COMPILER(); ?>";
|
||||
$file .= pack('VVnVVV', 500, 500, 0x1000, 0x00000000, 0, 0) . str_repeat('A', 500);
|
||||
file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file);
|
||||
try {
|
||||
include dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s009.phar.php" (too many manifest entries for size of manifest) in %s on line %d
|
||||
internal corruption of phar "%s009.phar.php" (too many manifest entries for size of manifest)
|
||||
|
||||
@@ -16,10 +16,14 @@ $manifest = pack('V', 1) . 'a' . pack('VVVVVV', 0, time(), 0, crc32(''), 0x00000
|
||||
$file .= pack('VVnVV', strlen($manifest), 1, 0x1000, 0x00000000, 3) . 'hio' . pack('V', 0) . $manifest;
|
||||
|
||||
file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file);
|
||||
try {
|
||||
include dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
|
||||
echo file_get_contents('phar://hio/a');
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s" (too many manifest entries for size of manifest) in %s on line %d
|
||||
internal corruption of phar "%s" (too many manifest entries for size of manifest)
|
||||
|
||||
@@ -17,11 +17,14 @@ __HALT_COMPILER(); ?>";
|
||||
$files = array();
|
||||
$files['a'] = array('cont'=>'a','ulen'=>1,'clen'=>2);;
|
||||
include 'phar_test.inc';
|
||||
|
||||
try {
|
||||
include $fname;
|
||||
echo file_get_contents('phar://hio/a');
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
|
||||
--EXPECTF--
|
||||
%satal error: Phar::mapPhar(): internal corruption of phar "%s" (compressed and uncompressed size does not match for uncompressed entry) in %s on line %d
|
||||
internal corruption of phar "%s" (compressed and uncompressed size does not match for uncompressed entry)
|
||||
|
||||
@@ -25,7 +25,11 @@ file_put_contents($fname2, $file);
|
||||
|
||||
var_dump(Phar::loadPhar($fname1, 'hio'));
|
||||
var_dump(Phar::loadPhar($fname1, 'copy'));
|
||||
try {
|
||||
var_dump(Phar::loadPhar($fname2, 'copy'));
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
@@ -38,4 +42,4 @@ unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar.php
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
%satal error: Phar::loadPhar(): alias "copy" is already used for archive "%s029.1.phar.php" cannot be overloaded with "%s029.2.phar.php" in %s029.php on line %d
|
||||
alias "copy" is already used for archive "%s029.1.phar.php" cannot be overloaded with "%s029.2.phar.php"===DONE===
|
||||
@@ -11,7 +11,11 @@ $pharconfig = 0;
|
||||
|
||||
require_once 'phar_oo_test.inc';
|
||||
|
||||
try {
|
||||
Phar::loadPhar($fname);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
@@ -22,4 +26,4 @@ __halt_compiler();
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Catchable fatal error: Phar::loadPhar(): phar "%sphar_oo_test.phar.php" does not have a signature in %s032.php on line %d
|
||||
phar "%sphar_oo_test.phar.php" does not have a signature===DONE===
|
||||
Reference in New Issue
Block a user