1
0
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:
Greg Beaver
2007-01-29 06:02:19 +00:00
parent ce8285d289
commit c7a5d062f5
15 changed files with 520 additions and 265 deletions
+2 -2
View File
@@ -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
View File
@@ -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;
}
}
}
+5 -5
View File
@@ -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
View File
@@ -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);
+5 -2
View File
@@ -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)
+5 -1
View File
@@ -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
+5 -1
View File
@@ -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)
+5 -1
View File
@@ -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)
+5 -1
View File
@@ -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"
+5 -1
View File
@@ -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)
+5 -1
View File
@@ -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)
+5 -1
View File
@@ -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)
+5 -2
View File
@@ -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)
+5 -1
View File
@@ -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===
+5 -1
View File
@@ -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===