]> granicus.if.org Git - php/commitdiff
fix tests, fix corruption issues with compression, simplify code. 3 tests still...
authorGreg Beaver <cellog@php.net>
Mon, 22 Jan 2007 03:41:41 +0000 (03:41 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 22 Jan 2007 03:41:41 +0000 (03:41 +0000)
ext/phar/phar.c
ext/phar/tests/016.phpt
ext/phar/tests/016b.phpt
ext/phar/tests/phar_ctx_001.phpt
ext/phar/tests/phar_oo_compressed_001.phpt
ext/phar/tests/phar_stub.phpt
ext/phar/tests/phar_stub_write.phpt

index f1a795458cf89681ab453ceed4d603a95eeb8516..3bf2ee3a61c1994bc3afd289bc0d6b84dda7a14f 100644 (file)
@@ -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[] = "<?php __HALT_COMPILER();";
        phar_entry_info *entry;
-       int alias_len, fname_len, halt_offset, restore_alias_len, global_flags = 0;
-       char *fname, *alias;
+       int alias_len, fname_len, halt_offset, restore_alias_len, global_flags = 0, read;
+       char *fname, *alias, *buf;
        char manifest[18], entry_buffer[24];
        off_t manifest_ftell;
        long offset;
-       php_uint32 copy, loc, new_manifest_count;
+       php_uint32 mytime, loc, new_manifest_count;
        php_uint32 newcrc32;
        php_stream *file, *oldfile, *newfile, *compfile, *stubfile;
        php_stream_filter *filter;
@@ -1645,6 +1656,7 @@ int phar_flush(phar_entry_data *data, char *user_stub, long len TSRMLS_DC) /* {{
        /* compress as necessary, calculate crcs, manifest size, and file sizes */
        new_manifest_count = 0;
        offset = 0;
+       buf = (char *) emalloc(8192);
        for (zend_hash_internal_pointer_reset(&data->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);
index 1bb9e1e8c02b0354df1067869f71e004a836860b..8b5ae3e36e5a66aaa99f9b7bddd316533fca26ff 100644 (file)
@@ -13,7 +13,7 @@ $file = "<?php __HALT_COMPILER(); ?>";
 // 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'];
index 027657f281868700fb94189e6ea23016a57145cd..124a248fa1013ebe3ee0a7571614c5f853decf21 100755 (executable)
@@ -13,7 +13,7 @@ $file = "<?php __HALT_COMPILER(); ?>";
 // 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');
index 07137aa6b8a11b9aa2351eb4dcf4debf31ce9474..6ec812df86733eaf319cbef9b8cc803a13b953fd 100644 (file)
@@ -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===
index 6809eb98c3fd95e7416247ee64cd1d9fcb260a37..d58df16890a601a849d638c0b925b22ae8ca4f7f 100644 (file)
@@ -5,6 +5,7 @@ Phar context
 <?php if (!extension_loaded("zlib")) print "skip zlib not present"; ?>
 --INI--
 phar.require_hash=0
+phar.readonly=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
@@ -58,12 +59,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===
index f24b3f4c8d0f40219c2d145af22e02bd32b2bcc5..3cf514b8362295072f6d4a4d28c697452583350d 100644 (file)
@@ -4,6 +4,7 @@ Phar::setStub()
 <?php if (!extension_loaded("phar")) print "skip"; ?>
 --INI--
 phar.require_hash=0
+phar.readonly=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
index 9112c97f91a95d12bc6aa0f96d634821a1912682..3c88ec1010ea0c10220a5982b7888ef6a4161b32 100755 (executable)
@@ -4,6 +4,7 @@ Phar::setStub()/getStub()
 <?php if (!extension_loaded("phar")) print "skip"; ?>
 --INI--
 phar.require_hash=0
+phar.readonly=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';