mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
fix all but one of the double-destroyed hashes, and all but one of the unclosed streams
This commit is contained in:
parent
44327b0af2
commit
d1cc13c9b2
1 changed files with 93 additions and 9 deletions
102
ext/phar/phar.c
102
ext/phar/phar.c
|
@ -191,7 +191,9 @@ static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
|
|||
data->alias = NULL;
|
||||
}
|
||||
efree(data->fname);
|
||||
zend_hash_destroy(&data->manifest);
|
||||
if (data->manifest.arBuckets) {
|
||||
zend_hash_destroy(&data->manifest);
|
||||
}
|
||||
if (data->fp) {
|
||||
php_stream_close(data->fp);
|
||||
}
|
||||
|
@ -313,6 +315,9 @@ static phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path,
|
|||
path++;
|
||||
path_len--;
|
||||
}
|
||||
if (!&phar->manifest.arBuckets) {
|
||||
return NULL;
|
||||
}
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
|
||||
return entry;
|
||||
}
|
||||
|
@ -474,7 +479,10 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia
|
|||
if ((mydata = phar_get_archive(fname, fname_len, alias, alias_len TSRMLS_CC)) != NULL) {
|
||||
if (reload) {
|
||||
/* start over */
|
||||
zend_hash_destroy(&mydata->manifest);
|
||||
if (mydata->manifest.arBuckets) {
|
||||
zend_hash_destroy(&mydata->manifest);
|
||||
mydata->manifest.arBuckets = 0;
|
||||
}
|
||||
} else {
|
||||
/* Overloading or reloading an archive would only be possible if we */
|
||||
/* refcount everything to be sure no stream for any file in the */
|
||||
|
@ -672,9 +680,11 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia
|
|||
mydata->has_compressed_files = compressed;
|
||||
mydata->fp = fp;
|
||||
mydata->refcount = 0;
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&mydata, sizeof(phar_archive_data), NULL);
|
||||
if (register_alias) {
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
if (!reload) {
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&mydata, sizeof(phar_archive_data), NULL);
|
||||
if (register_alias) {
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
}
|
||||
}
|
||||
efree(savebuf);
|
||||
|
||||
|
@ -828,8 +838,6 @@ static int phar_open_filename(char *fname, int fname_len, char *alias, int alias
|
|||
}
|
||||
|
||||
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (__HALT_COMPILER(); not found)")
|
||||
php_stream_close(fp);
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -1299,9 +1307,10 @@ static int phar_closedir(php_stream *stream, int close_handle TSRMLS_DC) /* {{{
|
|||
{
|
||||
HashTable *data = (HashTable *)stream->abstract;
|
||||
|
||||
if (data)
|
||||
if (data && data->arBuckets)
|
||||
{
|
||||
zend_hash_destroy(data);
|
||||
data->arBuckets = 0;
|
||||
FREE_HASHTABLE(data);
|
||||
stream->abstract = NULL;
|
||||
}
|
||||
|
@ -1487,6 +1496,8 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
if (data->phar->halt_offset) {
|
||||
if (data->phar->halt_offset != php_stream_copy_to_stream(data->fp, newfile, data->phar->halt_offset))
|
||||
{
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to copy prologue of old phar to new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
}
|
||||
|
@ -1507,6 +1518,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
|
||||
/* write the manifest header */
|
||||
if (14 + data->phar->alias_len != php_stream_write(newfile, manifest, 14 + data->phar->alias_len)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write manifest meta-data of new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
|
||||
|
@ -1523,6 +1538,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
phar_set_32(buffer, entry->filename_len);
|
||||
memcpy(buffer + 4, entry->filename, entry->filename_len);
|
||||
if (4 + entry->filename_len != php_stream_write(newfile, buffer, 4 + entry->filename_len)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
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, data->phar->fname);
|
||||
}
|
||||
if (entry->flags & PHAR_ENT_MODIFIED) {
|
||||
|
@ -1545,22 +1564,38 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
phar_set_32(buffer+12, entry->crc32);
|
||||
buffer[16] = (char) entry->flags;
|
||||
if (17 != php_stream_write(newfile, buffer, 17)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
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, data->phar->fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* write the actual manifest size */
|
||||
file_ftell = php_stream_tell(newfile);
|
||||
copy = file_ftell - manifest_ftell;
|
||||
copy = file_ftell - manifest_ftell + 13; /* compensate for manifest header size */
|
||||
phar_set_32(manifest, copy);
|
||||
if (-1 == php_stream_seek(newfile, manifest_ftell, SEEK_SET)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to manifest of new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
/* write the manifest header */
|
||||
if (2 != php_stream_write(newfile, manifest, 2)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write out manifest size of new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
if (-1 == php_stream_seek(newfile, file_ftell, SEEK_SET)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to file location of new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
|
||||
|
@ -1586,6 +1621,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
copy = entry->uncompressed_filesize;
|
||||
} else {
|
||||
if (-1 == php_stream_seek(data->fp, entry->offset_within_phar + data->phar->internal_file_start, SEEK_SET)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_stream_close(compressedfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, data->phar->fname);
|
||||
}
|
||||
file = data->fp;
|
||||
|
@ -1594,6 +1634,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
|
||||
filter = php_stream_filter_create("zlib.deflate", NULL, 0 TSRMLS_CC);
|
||||
if (!filter) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_stream_close(compressedfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to zlib compress file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname);
|
||||
}
|
||||
php_stream_filter_append(&file->readfilters, filter);
|
||||
|
@ -1614,6 +1659,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
} else if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
|
||||
filter = php_stream_filter_create("bzip2.compress", NULL, 0 TSRMLS_CC);
|
||||
if (!filter) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_stream_close(compressedfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname);
|
||||
}
|
||||
php_stream_filter_append(&file->readfilters, filter);
|
||||
|
@ -1633,6 +1683,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
entry->crc32 = newcrc32;
|
||||
}
|
||||
if (copy != php_stream_copy_to_stream(file, newfile, copy)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_stream_close(compressedfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write contents of file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname);
|
||||
}
|
||||
/* close the temporary file, no longer needed */
|
||||
|
@ -1647,6 +1702,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
php_stream_close(compressedfile);
|
||||
/* now that we know the actual file sizes and CRC32s, re-write the manifest */
|
||||
if (-1 == php_stream_seek(newfile, data->phar->halt_offset + 14 + data->phar->alias_len, SEEK_SET)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to set manifest length of new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
for (zend_hash_internal_pointer_reset(&data->phar->manifest);
|
||||
|
@ -1661,6 +1720,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
}
|
||||
/* skip already written filename */
|
||||
if (-1 == php_stream_seek(newfile, 4 + entry->filename_len, SEEK_CUR)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to manifest of file \"%s\" in new phar \"%s\"", entry->filename, data->phar->fname);
|
||||
}
|
||||
/* set the actual manifest meta-data:
|
||||
|
@ -1677,6 +1740,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
phar_set_32(buffer+12, entry->crc32);
|
||||
buffer[16] = (char) entry->flags;
|
||||
if (17 != php_stream_write(newfile, buffer, 17)) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write manifest of file \"%s\" in new phar \"%s\"", entry->filename, data->phar->fname);
|
||||
}
|
||||
}
|
||||
|
@ -1686,6 +1753,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
php_stream_rewind(newfile);
|
||||
file = php_stream_open_wrapper(data->phar->fname, "wb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
|
||||
if (!file) {
|
||||
efree(buffer);
|
||||
efree(manifest);
|
||||
php_stream_close(data->fp);
|
||||
php_stream_close(newfile);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open new phar \"%s\" for writing", data->phar->fname);
|
||||
}
|
||||
php_stream_copy_to_stream(newfile, file, PHP_STREAM_COPY_ALL);
|
||||
|
@ -1697,25 +1768,30 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
|
|||
|
||||
#if PHP_MAJOR_VERSION < 6
|
||||
if (PG(safe_mode) && (!php_checkuid(data->phar->fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
|
||||
php_stream_close(data->fp);
|
||||
return EOF;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (php_check_open_basedir(data->phar->fname TSRMLS_CC)) {
|
||||
php_stream_close(data->fp);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
file = php_stream_open_wrapper(data->phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
|
||||
|
||||
if (!file) {
|
||||
php_stream_close(data->fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open phar for reading \"%s\"", data->phar->fname);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (-1 == php_stream_seek(file, data->phar->halt_offset, SEEK_SET)) {
|
||||
php_stream_close(data->fp);
|
||||
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", data->phar->fname);
|
||||
}
|
||||
|
||||
php_stream_close(data->fp);
|
||||
phar_open_file(file, data->phar->fname, data->phar->fname_len, data->phar->alias, data->phar->alias_len, data->phar->halt_offset, &data->phar, TRUE TSRMLS_CC);
|
||||
return EOF;
|
||||
}
|
||||
|
@ -1852,6 +1928,10 @@ static int phar_stream_stat(php_stream_wrapper *wrapper, char *url, int flags,
|
|||
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);
|
||||
|
@ -2061,6 +2141,10 @@ static php_stream *phar_opendir(php_stream_wrapper *wrapper, char *filename, cha
|
|||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue