this also resulted in a major fix for mounted directories, which were recycling the 'link' field which
could cause stupid conflicts with actual links, so move that to new 'tmp' field.
/*if (entry->is_mounted) {
external directory, TODO: construct an internal dirstream based on this actual dir's dirstream
php_url_free(resource);
- return php_stream_opendir(entry->link, options, context);
+ return php_stream_opendir(entry->tmp, options, context);
}*/
internal_file = estrdup(internal_file);
php_url_free(resource);
efree(entry->link);
entry->link = 0;
}
+ if (entry->tmp) {
+ efree(entry->tmp);
+ entry->tmp = 0;
+ }
}
/* }}} */
int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len, int executable, int for_create TSRMLS_DC) /* {{{ */
{
const char *ext_str;
+#ifdef PHP_WIN32
char *save;
+#endif
int ext_len, free_filename = 0;
if (!strncasecmp(filename, "phar://", 7)) {
if (ext_len != -1) {
if (!ext_str) {
/* no / detected, restore arch for error message */
+#ifdef PHP_WIN32
*arch = save;
+#else
+ *arch = filename;
+#endif
}
if (free_filename) {
efree(filename);
if ((oldfile && !entry->is_modified) || entry->is_dir) {
continue;
}
- if (!phar_get_efp(entry TSRMLS_CC)) {
+ if (!phar_get_efp(entry, 0 TSRMLS_CC)) {
/* re-open internal file pointer just-in-time */
newentry = phar_open_jit(phar, entry, oldfile, error, 0 TSRMLS_CC);
if (!newentry) {
}
entry = newentry;
}
- file = phar_get_efp(entry TSRMLS_CC);
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
+ file = phar_get_efp(entry, 0 TSRMLS_CC);
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1 TSRMLS_CC)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
return EOF;
}
php_stream_flush(file);
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
file = entry->cfp;
php_stream_rewind(file);
} else {
- file = phar_get_efp(entry TSRMLS_CC);
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
+ file = phar_get_efp(entry, 0 TSRMLS_CC);
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
/* this flag is used for mounted entries (external files mapped to location
inside a phar */
int is_mounted:1;
+ char *tmp;
/* used when iterating */
int is_temp_dir:1;
phar_archive_data *phar;
char **error, int for_write TSRMLS_DC);
int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC);
void destroy_phar_manifest_entry(void *pDest);
-int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position TSRMLS_DC);
-php_stream *phar_get_efp(phar_entry_info *entry TSRMLS_DC);
+int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC);
+php_stream *phar_get_efp(phar_entry_info *entry, int follow_links TSRMLS_DC);
int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error TSRMLS_DC);
-int phar_open_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC);
+int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links TSRMLS_DC);
+phar_entry_info *phar_get_link_source(phar_entry_info *entry TSRMLS_DC);
int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
int phar_separate_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC);
int phar_open_archive_fp(phar_archive_data *phar TSRMLS_DC);
}
/* prepare to output */
- if (!phar_get_efp(phar->internal_file TSRMLS_CC)) {
+ if (!phar_get_efp(phar->internal_file, 1 TSRMLS_CC)) {
char *error;
if (!phar_open_jit(phar->phar, phar->internal_file, phar->phar->fp, &error, 0 TSRMLS_CC)) {
if (error) {
}
return -1;
}
- phar->fp = phar_get_efp(phar->internal_file TSRMLS_CC);
+ phar->fp = phar_get_efp(phar->internal_file, 1 TSRMLS_CC);
phar->zero = phar->internal_file->offset;
}
- phar_seek_efp(phar->internal_file, 0, SEEK_SET, 0 TSRMLS_CC);
+ phar_seek_efp(phar->internal_file, 0, SEEK_SET, 0, 1 TSRMLS_CC);
do {
got = php_stream_read(phar->fp, buf, MIN(8192, phar->internal_file->uncompressed_filesize - phar->position));
PHPWRITE(buf, got);
{
char *error;
off_t offset;
+ phar_entry_info *link;
- if (FAILURE == phar_open_entry_fp(entry, &error TSRMLS_CC)) {
+ if (FAILURE == phar_open_entry_fp(entry, &error, 1 TSRMLS_CC)) {
if (error) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
"Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents: %s", entry->phar->fname, entry->filename, error);
return FAILURE;
}
/* copy old contents in entirety */
- phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC);
+ phar_seek_efp(entry, 0, SEEK_SET, 0, 1 TSRMLS_CC);
offset = php_stream_tell(fp);
- if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry TSRMLS_CC), fp, entry->uncompressed_filesize)) {
+ link = phar_get_link_source(entry TSRMLS_CC);
+ if (!link) {
+ link = entry;
+ }
+ if (link->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize)) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
"Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", entry->phar->fname, entry->filename);
return FAILURE;
{
char *error;
php_stream *fp;
+ phar_entry_info *link;
PHAR_ENTRY_OBJECT();
if (entry_obj->ent.entry->is_dir) {
"Phar error: Cannot retrieve contents, \"%s\" in phar \"%s\" is a directory", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
return;
}
- if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error TSRMLS_CC)) {
+ link = phar_get_link_source(entry_obj->ent.entry TSRMLS_CC);
+ if (!link) {
+ link = entry_obj->ent.entry;
+ }
+ if (SUCCESS != phar_open_entry_fp(link, &error, 0 TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Phar error: Cannot retrieve contents, \"%s\" in phar \"%s\": %s", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname, error);
efree(error);
return;
}
- if (!(fp = phar_get_efp(entry_obj->ent.entry TSRMLS_CC))) {
+ if (!(fp = phar_get_efp(link, 0 TSRMLS_CC))) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Phar error: Cannot retrieve contents of \"%s\" in phar \"%s\"", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
return;
}
- phar_seek_efp(entry_obj->ent.entry, 0, SEEK_SET, 0 TSRMLS_CC);
+ phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC);
Z_TYPE_P(return_value) = IS_STRING;
- Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), entry_obj->ent.entry->uncompressed_filesize, 0);
+ Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
+ if (!Z_STRVAL_P(return_value)) {
+ Z_STRVAL_P(return_value) = estrndup("", 0);
+ }
}
/* }}} */
return;
}
/* decompress this file indirectly */
- if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error TSRMLS_CC)) {
+ if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error, 1 TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Phar error: Cannot decompress bzip2-compressed file \"%s\" in phar \"%s\" in order to compress with gzip: %s", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname, error);
efree(error);
return;
}
/* decompress this file indirectly */
- if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error TSRMLS_CC)) {
+ if (SUCCESS != phar_open_entry_fp(entry_obj->ent.entry, &error, 1 TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Phar error: Cannot decompress gzip-compressed file \"%s\" in phar \"%s\" in order to compress with bzip2: %s", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname, error);
efree(error);
if (SUCCESS != zend_hash_find(&phar->manifest, key, keylen, (void **) &entry)) {
goto free_resource;
}
- if (!entry->link || !entry->is_mounted) {
+ if (!entry->tmp || !entry->is_mounted) {
goto free_resource;
}
- test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->link, internal_file + keylen);
+ test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, internal_file + keylen);
if (SUCCESS != php_stream_stat_path(test, &ssbi)) {
efree(test);
continue;
entry->is_deleted = 1;
entry->fp = NULL;
entry->metadata = 0;
- entry->link = NULL;
+ entry->link = entry->tmp = NULL;
source = entry;
/* add to the manifest, and then store the pointer to the new guy in entry */
if (entry.tar_type == TAR_LINK) {
if (!zend_hash_exists(&myphar->manifest, hdr->linkname, strlen(hdr->linkname))) {
if (error) {
- spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file", fname);
+ spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%s\"", fname, hdr->linkname);
}
efree(entry.filename);
php_stream_close(fp);
pos = php_stream_tell(fp->new); /* save start of file within tar */
/* write contents */
- if (FAILURE == phar_open_entry_fp(entry, fp->error TSRMLS_CC)) {
- return ZEND_HASH_APPLY_STOP;
- }
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
- if (fp->error) {
- spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", entry->phar->fname, entry->filename);
+ if (entry->uncompressed_filesize) {
+ if (FAILURE == phar_open_entry_fp(entry, fp->error, 0 TSRMLS_CC)) {
+ return ZEND_HASH_APPLY_STOP;
}
- return ZEND_HASH_APPLY_STOP;
- }
- if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry TSRMLS_CC), fp->new, entry->uncompressed_filesize)) {
- if (fp->error) {
- spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", entry->phar->fname, entry->filename);
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
+ if (fp->error) {
+ spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", entry->phar->fname, entry->filename);
+ }
+ return ZEND_HASH_APPLY_STOP;
}
- return ZEND_HASH_APPLY_STOP;
+ if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), fp->new, entry->uncompressed_filesize)) {
+ if (fp->error) {
+ spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", entry->phar->fname, entry->filename);
+ }
+ return ZEND_HASH_APPLY_STOP;
+ }
+
+ memset(padding, 0, 512);
+ php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize);
}
- memset(padding, 0, 512);
- php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize);
-
entry->is_modified = 0;
if (entry->fp_type == PHAR_MOD && entry->fp != entry->phar->fp && entry->fp != entry->phar->ufp) {
if (!entry->fp_refcount) {
}
$link = null;
- if ($stat['mode'] & 0x4000) {
- $type = 5; // Directory
- } else if ($stat['mode'] & 0x8000) {
- $type = 0; // Regular
- } else if ($stat['mode'] & 0xA000 && $corrupt = 'symlink') {
+ if ($stat['mode'] & 0xA000 && $corrupt === 'symlink') {
$type = 2; // Symbolic Link
- $link = 'file1.txt';
+ $link = $fileOrStream;
+ $stat['size'] = 0;
+ $fileOrStream = '';
} else if ($stat['mode'] & 0xA000) {
$type = 1; // Link
- $link = 'file1.txt';
+ $link = $fileOrStream;
+ $stat['size'] = 0;
+ $fileOrStream = '';
+ } else if ($stat['mode'] & 0x4000) {
+ $type = 5; // Directory
+ } else if ($stat['mode'] & 0x8000) {
+ $type = 0; // Regular
} else {
$type = 9; // Unknown
}
$checksum = 256; // 8 * ord(' ');
$checksum += array_reduce($checkheader, '_pear2tarchecksum');
- if ($corrupt == 'checksum') $checksum++;
+ if ($corrupt === 'checksum') $checksum++;
$checksum = pack('a8', sprintf('%6s ', decoct($checksum)));
fwrite($this->tmp, $block . $checksum . $blockend, 512);
}
} else {
fwrite($this->tmp, $fileOrStream);
- if (strlen($fileOrStream) % 512) {
+ if (strlen($fileOrStream) && !isset($link) && strlen($fileOrStream) % 512) {
fwrite($this->tmp, str_repeat("\0", 512 - strlen($fileOrStream) % 512));
}
}
<?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar');
?>
---EXPECTF--
-string(2) "hi"
-string(2) "hi"
-string(2) "hi"
+--EXPECT--
+string(3) "hi
+"
+string(3) "hi
+"
+string(3) "hi
+"
===DONE===
extern php_stream_wrapper php_stream_phar_wrapper;
#endif
+/* for links to relative location, prepend cwd of the entry */
+static char *phar_get_link_location(phar_entry_info *entry TSRMLS_DC)
+{
+ char *tmp, *ret, *p;
+ if (!entry->link) {
+ return NULL;
+ }
+ if (entry->link[0] == '/') {
+ return entry->link;
+ }
+ tmp = estrndup(entry->filename, entry->filename_len);
+ p = strrchr(tmp, '/');
+ if (p) {
+ *p = '\0';
+ spprintf(&ret, 0, "%s/%s", tmp, entry->link);
+ efree(tmp);
+ return ret;
+ }
+ efree(ret);
+ return entry->link;
+}
+
+phar_entry_info *phar_get_link_source(phar_entry_info *entry TSRMLS_DC)
+{
+ phar_entry_info *link_entry;
+ char *link = phar_get_link_location(entry);
+
+ if (!entry->link) {
+ return entry;
+ }
+
+ if (SUCCESS == zend_hash_find(&(entry->phar->manifest), entry->link, strlen(entry->link), (void **)&link_entry) ||
+ SUCCESS == zend_hash_find(&(entry->phar->manifest), link, strlen(link), (void **)&link_entry)) {
+ if (link != entry->link) {
+ efree(link);
+ }
+ return phar_get_link_source(link_entry TSRMLS_CC);
+ } else {
+ if (link != entry->link) {
+ efree(link);
+ }
+ return NULL;
+ }
+}
+
/* retrieve a phar_entry_info's current file pointer for reading contents */
-php_stream *phar_get_efp(phar_entry_info *entry TSRMLS_DC)
+php_stream *phar_get_efp(phar_entry_info *entry, int follow_links TSRMLS_DC)
{
+ if (follow_links && entry->link) {
+ phar_entry_info *link_entry = phar_get_link_source(entry TSRMLS_CC);
+
+ if (link_entry && link_entry != entry) {
+ return phar_get_efp(link_entry, 1 TSRMLS_CC);
+ }
+ }
if (entry->fp_type == PHAR_FP) {
if (!entry->phar->fp) {
/* re-open just in time for cases where our refcount reached 0 on the phar archive */
} else {
/* temporary manifest entry */
if (!entry->fp) {
- entry->fp = php_stream_open_wrapper(entry->link, "rb", STREAM_MUST_SEEK|0, NULL);
+ entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
}
return entry->fp;
}
}
-int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position TSRMLS_DC)
+int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC)
{
- php_stream *fp = phar_get_efp(entry TSRMLS_CC);
+ php_stream *fp = phar_get_efp(entry, follow_links TSRMLS_CC);
off_t temp;
+ if (follow_links) {
+ phar_entry_info *t;
+ t = phar_get_link_source(entry TSRMLS_CC);
+ if (t) {
+ entry = t;
+ }
+ }
if (entry->is_dir) {
return 0;
}
#endif
entry.filename_len = path_len;
if (strstr(filename, "phar://")) {
- entry.link = estrndup(filename, filename_len);
+ entry.tmp = estrndup(filename, filename_len);
} else {
- entry.link = expand_filepath(filename, NULL TSRMLS_CC);
- if (!entry.link) {
- entry.link = estrndup(filename, filename_len);
+ entry.tmp = expand_filepath(filename, NULL TSRMLS_CC);
+ if (!entry.tmp) {
+ entry.tmp = estrndup(filename, filename_len);
}
}
#if PHP_MAJOR_VERSION < 6
- if (PG(safe_mode) && !strstr(filename, "phar://") && (!php_checkuid(entry.link, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
- efree(entry.link);
+ if (PG(safe_mode) && !strstr(filename, "phar://") && (!php_checkuid(entry.tmp, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
+ efree(entry.tmp);
efree(entry.filename);
return FAILURE;
}
#endif
- filename_len = strlen(entry.link);
- filename = entry.link;
+ filename_len = strlen(entry.tmp);
+ filename = entry.tmp;
/* only check openbasedir for files, not for phar streams */
if (!strstr(filename, "phar://") && php_check_open_basedir(filename TSRMLS_CC)) {
- efree(entry.link);
+ efree(entry.tmp);
efree(entry.filename);
return FAILURE;
}
entry.fp_type = PHAR_TMP;
if (SUCCESS != php_stream_stat_path(filename, &ssb)) {
- efree(entry.link);
+ efree(entry.tmp);
efree(entry.filename);
return FAILURE;
}
entry.is_dir = 1;
if (SUCCESS != zend_hash_add(&phar->mounted_dirs, entry.filename, path_len, (void *)&(entry.filename), sizeof(char *), NULL)) {
/* directory already mounted */
- efree(entry.link);
+ efree(entry.tmp);
efree(entry.filename);
return FAILURE;
}
if (SUCCESS == zend_hash_add(&phar->manifest, entry.filename, path_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
return SUCCESS;
}
- efree(entry.link);
+ efree(entry.tmp);
efree(entry.filename);
return FAILURE;
}
return FAILURE;
}
} else if (for_append) {
- phar_seek_efp(entry, 0, SEEK_END, 0 TSRMLS_CC);
+ phar_seek_efp(entry, 0, SEEK_END, 0, 0 TSRMLS_CC);
}
} else {
+ if (entry->link) {
+ efree(entry->link);
+ entry->link = NULL;
+ entry->tar_type = (entry->tar_type ? TAR_FILE : 0);
+ }
if (for_write) {
if (for_trunc) {
if (FAILURE == phar_create_writeable_entry(phar, entry, error TSRMLS_CC)) {
}
}
} else {
- if (FAILURE == phar_open_entry_fp(entry, error TSRMLS_CC)) {
+ if (FAILURE == phar_open_entry_fp(entry, error, 1 TSRMLS_CC)) {
return FAILURE;
}
}
(*ret)->internal_file = entry;
(*ret)->is_zip = entry->is_zip;
(*ret)->is_tar = entry->is_tar;
- (*ret)->fp = phar_get_efp(entry TSRMLS_CC);
+ (*ret)->fp = phar_get_efp(entry, 1 TSRMLS_CC);
(*ret)->zero = entry->offset;
++(entry->fp_refcount);
++(entry->phar->refcount);
/* copy file data from an existing to a new phar_entry_info that is not in the manifest */
int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error TSRMLS_DC)
{
- if (FAILURE == phar_open_entry_fp(source, error TSRMLS_CC)) {
+ phar_entry_info *link;
+
+ if (FAILURE == phar_open_entry_fp(source, error, 1 TSRMLS_CC)) {
return FAILURE;
}
+ if (dest->link) {
+ efree(dest->link);
+ dest->link = NULL;
+ dest->tar_type = (dest->tar_type ? TAR_FILE : 0);
+ }
dest->fp_type = PHAR_MOD;
dest->offset = 0;
dest->is_modified = 1;
dest->fp = php_stream_fopen_tmpfile();
- phar_seek_efp(source, 0, SEEK_SET, 0 TSRMLS_CC);
- if (source->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(source TSRMLS_CC), dest->fp, source->uncompressed_filesize)) {
+ phar_seek_efp(source, 0, SEEK_SET, 0, 1 TSRMLS_CC);
+ link = phar_get_link_source(source TSRMLS_CC);
+ if (!link) {
+ link = source;
+ }
+ if (link->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), dest->fp, link->uncompressed_filesize)) {
php_stream_close(dest->fp);
dest->fp_type = PHAR_FP;
if (error) {
/* open and decompress a compressed phar entry
*/
-int phar_open_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC)
+int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links TSRMLS_DC)
{
php_stream_filter *filter;
phar_archive_data *phar = entry->phar;
char *filtername;
off_t loc;
+ if (follow_links && entry->link) {
+ phar_entry_info *link_entry = phar_get_link_source(entry TSRMLS_CC);
+
+ if (link_entry && link_entry != entry) {
+ return phar_open_entry_fp(link_entry, error, 1 TSRMLS_CC);
+ }
+ }
if (entry->fp_type == PHAR_TMP) {
if (!entry->fp) {
- entry->fp = php_stream_open_wrapper(entry->link, "rb", STREAM_MUST_SEEK|0, NULL);
+ entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
}
return SUCCESS;
}
*error = NULL;
}
/* open a new temp file for writing */
+ if (entry->link) {
+ efree(entry->link);
+ entry->link = NULL;
+ entry->tar_type = (entry->tar_type ? TAR_FILE : 0);
+ }
entry->fp = php_stream_fopen_tmpfile();
if (!entry->fp) {
if (error) {
int phar_separate_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC)
{
php_stream *fp;
+ phar_entry_info *link;
- if (FAILURE == phar_open_entry_fp(entry, error TSRMLS_CC)) {
+ if (FAILURE == phar_open_entry_fp(entry, error, 1 TSRMLS_CC)) {
return FAILURE;
}
}
fp = php_stream_fopen_tmpfile();
- phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC);
- if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry TSRMLS_CC), fp, entry->uncompressed_filesize)) {
+ phar_seek_efp(entry, 0, SEEK_SET, 0, 1 TSRMLS_CC);
+ link = phar_get_link_source(entry TSRMLS_CC);
+ if (!link) {
+ link = entry;
+ }
+ if (link->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize)) {
if (error) {
spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname);
}
return FAILURE;
}
+ if (entry->link) {
+ efree(entry->link);
+ entry->link = NULL;
+ entry->tar_type = (entry->tar_type ? TAR_FILE : 0);
+ }
+
entry->offset = 0;
entry->fp = fp;
entry->fp_type = PHAR_MOD;
*error = NULL;
}
/* seek to start of internal file and read it */
- if (FAILURE == phar_open_entry_fp(entry, error TSRMLS_CC)) {
+ if (FAILURE == phar_open_entry_fp(entry, error, 1 TSRMLS_CC)) {
return NULL;
}
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1 TSRMLS_CC)) {
spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", entry->filename, phar->fname);
return NULL;
}
}
return NULL;
}
- if (!entry->link || !entry->is_mounted) {
+ if (!entry->tmp || !entry->is_mounted) {
if (error) {
spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", key);
}
return NULL;
}
- test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->link, path + keylen);
+ test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + keylen);
if (SUCCESS != php_stream_stat_path(test, &ssb)) {
efree(test);
return NULL;
}
goto continue_dir;
}
- if (FAILURE == phar_open_entry_fp(entry, p->error TSRMLS_CC)) {
+ if (FAILURE == phar_open_entry_fp(entry, p->error, 0 TSRMLS_CC)) {
spprintf(p->error, 0, "unable to open file contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname);
return ZEND_HASH_APPLY_STOP;
}
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
return ZEND_HASH_APPLY_STOP;
}
- efp = phar_get_efp(entry TSRMLS_CC);
+ efp = phar_get_efp(entry, 0 TSRMLS_CC);
newcrc32 = ~0;
for (loc = 0;loc < entry->uncompressed_filesize; ++loc) {
return ZEND_HASH_APPLY_STOP;
}
php_stream_flush(efp);
- if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC)) {
+ if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC)) {
spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
return ZEND_HASH_APPLY_STOP;
}
php_stream_close(entry->cfp);
entry->cfp = NULL;
} else {
- if (FAILURE == phar_open_entry_fp(entry, p->error TSRMLS_CC)) {
+ if (FAILURE == phar_open_entry_fp(entry, p->error, 0 TSRMLS_CC)) {
return ZEND_HASH_APPLY_STOP;
}
- phar_seek_efp(entry, 0, SEEK_SET, 0 TSRMLS_CC);
- if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry TSRMLS_CC), p->filefp, entry->uncompressed_filesize)) {
+ phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC);
+ if (entry->uncompressed_filesize != php_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), p->filefp, entry->uncompressed_filesize)) {
spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname);
return ZEND_HASH_APPLY_STOP;
}