From: Greg Beaver Date: Mon, 22 Jan 2007 03:41:41 +0000 (+0000) Subject: fix tests, fix corruption issues with compression, simplify code. 3 tests still... X-Git-Tag: RELEASE_1_0_0RC1~156 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d8c26fd4611f22364e7316bafd43af98f5130501;p=php fix tests, fix corruption issues with compression, simplify code. 3 tests still fail, memory leaks and mysterious crc error - the 16 tests are faulty --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index f1a795458c..3bf2ee3a61 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1171,7 +1171,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat php_url *resource = NULL; php_stream *fp, *fpf; php_stream_filter *filter, *consumed; - php_uint32 offset; + php_uint32 offset, read, total, toread; zval **pzoption; resource = php_url_parse(path); @@ -1291,26 +1291,37 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat efree(internal_file); return NULL; } - /* Unfortunately we cannot check the read position of fp after getting */ - /* uncompressed data because the new stream posiition is being changed */ - /* by the number of bytes read throughthe filter not by the raw number */ - /* bytes being consumed on the stream. Therefore use a consumed filter. */ - consumed = php_stream_filter_create("consumed", NULL, php_stream_is_persistent(fp) TSRMLS_CC); - php_stream_filter_append(&fp->readfilters, consumed); - php_stream_filter_append(&fp->readfilters, filter); + buffer = (char *) emalloc(8192); + read = 0; + total = 0; idata->fp = php_stream_temp_new(); - if (php_stream_copy_to_stream(fp, idata->fp, idata->internal_file->uncompressed_filesize) != idata->internal_file->uncompressed_filesize) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", idata->phar->fname, internal_file); - php_stream_close(idata->fp); - efree(idata); - efree(internal_file); - return NULL; - } + php_stream_filter_append(&idata->fp->writefilters, filter); + do { + if ((total + 8192) > idata->internal_file->compressed_filesize) { + toread = idata->internal_file->compressed_filesize - total; + } else { + toread = 8192; + } + read = php_stream_read(fp, buffer, toread); + if (read) { + total += read; + if (read != php_stream_write(idata->fp, buffer, read)) { + efree(buffer); + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", idata->phar->fname, internal_file); + php_stream_close(idata->fp); + efree(idata); + efree(internal_file); + return NULL; + } + if (total == idata->internal_file->compressed_filesize) { + read = 0; + } + } + } while (read); + efree(buffer); php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); - php_stream_filter_flush(consumed, 1); - php_stream_filter_remove(consumed, 1 TSRMLS_CC); if (offset + idata->internal_file->compressed_filesize != php_stream_tell(fp)) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", idata->phar->fname, internal_file); php_stream_close(idata->fp); @@ -1561,12 +1572,12 @@ int phar_flush(phar_entry_data *data, char *user_stub, long len TSRMLS_DC) /* {{ { static const char newstub[] = "phar->manifest); zend_hash_has_more_elements(&data->phar->manifest) == SUCCESS; zend_hash_move_forward(&data->phar->manifest)) { @@ -1660,75 +1672,74 @@ int phar_flush(phar_entry_data *data, char *user_stub, long len TSRMLS_DC) /* {{ offset += 4 + entry->filename_len + sizeof(entry_buffer); /* compress as necessary */ - if (entry->is_modified) { - if (!entry->temp_file) { - /* nothing to do here */ - continue; - } - php_stream_rewind(entry->temp_file); - file = entry->temp_file; - php_stream_rewind(file); - newcrc32 = ~0; - for (loc = entry->uncompressed_filesize; loc > 0; --loc) { - CRC32(newcrc32, php_stream_getc(file)); - } - entry->crc32 = ~newcrc32; - entry->is_crc_checked = 1; - entry->compressed_filesize = entry->uncompressed_filesize; - } else { - if (!entry->is_crc_checked) { - if (-1 == php_stream_seek(oldfile, entry->offset_within_phar + data->phar->internal_file_start, SEEK_SET)) { - 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, data->phar->fname); - return EOF; - } - newcrc32 = ~0; - for (loc = entry->uncompressed_filesize; loc > 0; --loc) { - CRC32(newcrc32, php_stream_getc(oldfile)); - } - entry->crc32 = ~newcrc32; - entry->is_crc_checked = 1; - } - if (-1 == php_stream_seek(oldfile, entry->offset_within_phar + data->phar->internal_file_start, SEEK_SET)) { + if (!entry->is_modified) { + continue; + } + if (!entry->temp_file) { + /* nothing to do here */ + continue; + } + php_stream_rewind(entry->temp_file); + file = entry->temp_file; + php_stream_rewind(file); + newcrc32 = ~0; + mytime = entry->uncompressed_filesize; + for (loc = 0;loc < mytime; loc++) { + CRC32(newcrc32, php_stream_getc(file)); + } + entry->crc32 = ~newcrc32; + entry->is_crc_checked = 1; + if (!(entry->flags & PHAR_ENT_COMPRESSION_MASK)) { + continue; + } + php_stream_rewind(file); + filter = php_stream_filter_create(phar_compress_filter(entry, 0), NULL, 0 TSRMLS_CC); + if (!filter) { + if (oldfile) { 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, data->phar->fname); - return EOF; } - file = oldfile; + 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, data->phar->fname); + } else { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname); + } + efree(buf); + return EOF; } - if (entry->flags & PHAR_ENT_COMPRESSION_MASK) { - filter = php_stream_filter_create(phar_compress_filter(entry, 0), NULL, 0 TSRMLS_CC); - if (!filter) { - if (oldfile) { - php_stream_close(oldfile); - } - 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, data->phar->fname); - } else { - 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); + + /* create new file that holds the compressed version */ + /* work around inability to specify freedom in write and strictness + in read count */ + entry->compressed_filesize = 0; + compfile = php_stream_fopen_tmpfile(); + do { + read = php_stream_read(file, buf, 8192); + if (read) { + if (read != php_stream_write(compfile, buf, read)) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write to file \"%s\" while creating new phar \"%s\"", entry->filename, data->phar->fname); + efree(buf); + php_stream_filter_remove(filter, 1 TSRMLS_CC); + php_stream_close(compfile); + return EOF; } - return EOF; + entry->compressed_filesize += read; } - php_stream_filter_append(&file->readfilters, filter); - - /* create new file that holds the compressed version */ - compfile = php_stream_fopen_tmpfile(); - entry->compressed_filesize = php_stream_copy_to_stream(file, compfile, entry->uncompressed_filesize); - php_stream_filter_remove(filter, 1 TSRMLS_CC); - if (entry->temp_file) { - /* no longer need the uncompressed contents */ - php_stream_close(entry->temp_file); - } - /* use temp_file to store the newly compressed data */ - entry->temp_file = compfile; - entry->is_modified = 1; - global_flags |= (entry->flags & PHAR_ENT_COMPRESSION_MASK); - } - } - + } while (read); + php_stream_filter_remove(filter, 1 TSRMLS_CC); + /* generate crc on compressed file */ + php_stream_rewind(compfile); + if (entry->temp_file) { + /* no longer need the uncompressed contents */ + php_stream_close(entry->temp_file); + } + /* use temp_file to store the newly compressed data */ + entry->temp_file = compfile; + entry->is_modified = 1; + global_flags |= (entry->flags & PHAR_ENT_COMPRESSION_MASK); + } + efree(buf); global_flags |= PHAR_HDR_SIGNATURE; /* write out manifest pre-header */ @@ -1802,9 +1813,9 @@ int phar_flush(phar_entry_data *data, char *user_stub, long len TSRMLS_DC) /* {{ php_var_serialize(&metadata_str, &entry->metadata, &metadata_hash TSRMLS_CC); PHP_VAR_SERIALIZE_DESTROY(metadata_hash); } - copy = time(NULL); + mytime = time(NULL); phar_set_32(entry_buffer, entry->uncompressed_filesize); - phar_set_32(entry_buffer+4, copy); + phar_set_32(entry_buffer+4, mytime); phar_set_32(entry_buffer+8, entry->compressed_filesize); phar_set_32(entry_buffer+12, entry->crc32); phar_set_32(entry_buffer+16, entry->flags); diff --git a/ext/phar/tests/016.phpt b/ext/phar/tests/016.phpt index 1bb9e1e8c0..8b5ae3e36e 100644 --- a/ext/phar/tests/016.phpt +++ b/ext/phar/tests/016.phpt @@ -13,7 +13,7 @@ $file = ""; // file length is too short $files = array(); -$files['a'] = array('cont'=>'a','comp'=>chr(75)/*. chr(4) . chr(0): 'a' gzdeflated */,'flags'=>0x00001000); +$files['a'] = array('cont'=>'a','comp'=>chr(75)/*. chr(4) . chr(0): 'a' gzdeflated */,'flags'=>0x00001000, 'clen' => 3); $files['b'] = $files['a']; $files['c'] = array('cont'=>'*'); $files['d'] = $files['a']; diff --git a/ext/phar/tests/016b.phpt b/ext/phar/tests/016b.phpt index 027657f281..124a248fa1 100755 --- a/ext/phar/tests/016b.phpt +++ b/ext/phar/tests/016b.phpt @@ -13,7 +13,7 @@ $file = ""; // file length is too short $files = array(); -$files['a'] = array('cont'=>'a','flags'=>0x00001000); +$files['a'] = array('cont'=>'a','flags'=>0x00001000, 'clen' => 1); include 'phar_test.inc'; echo file_get_contents($pname . '/a'); diff --git a/ext/phar/tests/phar_ctx_001.phpt b/ext/phar/tests/phar_ctx_001.phpt index 07137aa6b8..6ec812df86 100644 --- a/ext/phar/tests/phar_ctx_001.phpt +++ b/ext/phar/tests/phar_ctx_001.phpt @@ -57,12 +57,12 @@ string(1) "b" bool(false) string(1) "c" bool(false) -string(4) "new a" +string(5) "new a" bool(false) -string(4) "new b" +string(5) "new b" bool(true) string(1) "c" bool(false) -string(4) "new d" -bool(true) +string(5) "new d" +bool(false) ===DONE=== diff --git a/ext/phar/tests/phar_oo_compressed_001.phpt b/ext/phar/tests/phar_oo_compressed_001.phpt index 6809eb98c3..d58df16890 100644 --- a/ext/phar/tests/phar_oo_compressed_001.phpt +++ b/ext/phar/tests/phar_oo_compressed_001.phpt @@ -5,6 +5,7 @@ Phar context --INI-- phar.require_hash=0 +phar.readonly=0 --FILE-- --INI-- phar.require_hash=0 +phar.readonly=0 --FILE-- --INI-- phar.require_hash=0 +phar.readonly=0 --FILE--