fix all but one of the double-destroyed hashes, and all but one of the unclosed streams

This commit is contained in:
Greg Beaver 2007-01-03 15:43:07 +00:00
parent 44327b0af2
commit d1cc13c9b2

View file

@ -191,7 +191,9 @@ static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
data->alias = NULL; data->alias = NULL;
} }
efree(data->fname); efree(data->fname);
if (data->manifest.arBuckets) {
zend_hash_destroy(&data->manifest); zend_hash_destroy(&data->manifest);
}
if (data->fp) { if (data->fp) {
php_stream_close(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++;
path_len--; path_len--;
} }
if (!&phar->manifest.arBuckets) {
return NULL;
}
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) { if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
return 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 ((mydata = phar_get_archive(fname, fname_len, alias, alias_len TSRMLS_CC)) != NULL) {
if (reload) { if (reload) {
/* start over */ /* start over */
if (mydata->manifest.arBuckets) {
zend_hash_destroy(&mydata->manifest); zend_hash_destroy(&mydata->manifest);
mydata->manifest.arBuckets = 0;
}
} else { } else {
/* Overloading or reloading an archive would only be possible if we */ /* Overloading or reloading an archive would only be possible if we */
/* refcount everything to be sure no stream for any file in the */ /* refcount everything to be sure no stream for any file in the */
@ -672,10 +680,12 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia
mydata->has_compressed_files = compressed; mydata->has_compressed_files = compressed;
mydata->fp = fp; mydata->fp = fp;
mydata->refcount = 0; mydata->refcount = 0;
if (!reload) {
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&mydata, sizeof(phar_archive_data), NULL); zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&mydata, sizeof(phar_archive_data), NULL);
if (register_alias) { if (register_alias) {
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL); zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
} }
}
efree(savebuf); efree(savebuf);
if (!reload && pphar) { if (!reload && pphar) {
@ -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)") 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; HashTable *data = (HashTable *)stream->abstract;
if (data) if (data && data->arBuckets)
{ {
zend_hash_destroy(data); zend_hash_destroy(data);
data->arBuckets = 0;
FREE_HASHTABLE(data); FREE_HASHTABLE(data);
stream->abstract = NULL; 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) {
if (data->phar->halt_offset != php_stream_copy_to_stream(data->fp, newfile, 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); 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 */ /* write the manifest header */
if (14 + data->phar->alias_len != php_stream_write(newfile, manifest, 14 + data->phar->alias_len)) { 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); 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); phar_set_32(buffer, entry->filename_len);
memcpy(buffer + 4, entry->filename, 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)) { 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); 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) { 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); phar_set_32(buffer+12, entry->crc32);
buffer[16] = (char) entry->flags; buffer[16] = (char) entry->flags;
if (17 != php_stream_write(newfile, buffer, 17)) { 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); 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 */ /* write the actual manifest size */
file_ftell = php_stream_tell(newfile); 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); phar_set_32(manifest, copy);
if (-1 == php_stream_seek(newfile, manifest_ftell, SEEK_SET)) { 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); 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 */ /* write the manifest header */
if (2 != php_stream_write(newfile, manifest, 2)) { 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); 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)) { 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); 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; copy = entry->uncompressed_filesize;
} else { } else {
if (-1 == php_stream_seek(data->fp, entry->offset_within_phar + data->phar->internal_file_start, SEEK_SET)) { 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); 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; file = data->fp;
@ -1594,6 +1634,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
filter = php_stream_filter_create("zlib.deflate", NULL, 0 TSRMLS_CC); filter = php_stream_filter_create("zlib.deflate", NULL, 0 TSRMLS_CC);
if (!filter) { 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_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); 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) { } else if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
filter = php_stream_filter_create("bzip2.compress", NULL, 0 TSRMLS_CC); filter = php_stream_filter_create("bzip2.compress", NULL, 0 TSRMLS_CC);
if (!filter) { 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_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); php_stream_filter_append(&file->readfilters, filter);
@ -1633,6 +1683,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
entry->crc32 = newcrc32; entry->crc32 = newcrc32;
} }
if (copy != php_stream_copy_to_stream(file, newfile, copy)) { 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); 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 */ /* close the temporary file, no longer needed */
@ -1647,6 +1702,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */
php_stream_close(compressedfile); php_stream_close(compressedfile);
/* now that we know the actual file sizes and CRC32s, re-write the manifest */ /* 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)) { 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); 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); 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 */ /* skip already written filename */
if (-1 == php_stream_seek(newfile, 4 + entry->filename_len, SEEK_CUR)) { 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); 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: /* 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); phar_set_32(buffer+12, entry->crc32);
buffer[16] = (char) entry->flags; buffer[16] = (char) entry->flags;
if (17 != php_stream_write(newfile, buffer, 17)) { 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); 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); php_stream_rewind(newfile);
file = php_stream_open_wrapper(data->phar->fname, "wb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); file = php_stream_open_wrapper(data->phar->fname, "wb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
if (!file) { 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_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); 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 PHP_MAJOR_VERSION < 6
if (PG(safe_mode) && (!php_checkuid(data->phar->fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) { if (PG(safe_mode) && (!php_checkuid(data->phar->fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
php_stream_close(data->fp);
return EOF; return EOF;
} }
#endif #endif
if (php_check_open_basedir(data->phar->fname TSRMLS_CC)) { if (php_check_open_basedir(data->phar->fname TSRMLS_CC)) {
php_stream_close(data->fp);
return EOF; return EOF;
} }
file = php_stream_open_wrapper(data->phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); file = php_stream_open_wrapper(data->phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
if (!file) { 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); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open phar for reading \"%s\"", data->phar->fname);
return EOF; return EOF;
} }
if (-1 == php_stream_seek(file, data->phar->halt_offset, SEEK_SET)) { 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_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); 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; return EOF;
} }
@ -1852,6 +1928,10 @@ static int phar_stream_stat(php_stream_wrapper *wrapper, char *url, int flags,
php_url_free(resource); php_url_free(resource);
return 0; 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 */ /* 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)) { 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); 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); php_url_free(resource);
return ret; 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)) { if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) {
php_url_free(resource); php_url_free(resource);
return NULL; return NULL;