]> granicus.if.org Git - php/commitdiff
MFB: fix reading links from streams (works with PharFileInfo->getContent())
authorGreg Beaver <cellog@php.net>
Sat, 11 Oct 2008 22:12:18 +0000 (22:12 +0000)
committerGreg Beaver <cellog@php.net>
Sat, 11 Oct 2008 22:12:18 +0000 (22:12 +0000)
ext/phar/stream.c
ext/phar/tests/tar/files/links.phar.tar [new file with mode: 0644]
ext/phar/tests/tar/links6.phpt [new file with mode: 0644]
ext/phar/util.c

index 665fae97d8cdc85b15275bae039d92805d81ab83..95950bf60f154c6c25738ec82e0e7723fba7a72c 100644 (file)
@@ -359,8 +359,15 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML
 {
        phar_entry_data *data = (phar_entry_data *)stream->abstract;
        size_t got;
+       phar_entry_info *entry;
+
+       if (data->internal_file->link) {
+               entry = phar_get_link_source(data->internal_file TSRMLS_CC);
+       } else {
+               entry = data->internal_file;
+       }
 
-       if (data->internal_file->is_deleted) {
+       if (entry->is_deleted) {
                stream->eof = 1;
                return 0;
        }
@@ -368,9 +375,9 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML
        /* use our proxy position */
        php_stream_seek(data->fp, data->position + data->zero, SEEK_SET);
 
-       got = php_stream_read(data->fp, buf, MIN(count, data->internal_file->uncompressed_filesize - data->position));
+       got = php_stream_read(data->fp, buf, MIN(count, entry->uncompressed_filesize - data->position));
        data->position = php_stream_tell(data->fp) - data->zero;
-       stream->eof = (data->position == (off_t) data->internal_file->uncompressed_filesize);
+       stream->eof = (data->position == (off_t) entry->uncompressed_filesize);
 
        return got;
 }
diff --git a/ext/phar/tests/tar/files/links.phar.tar b/ext/phar/tests/tar/files/links.phar.tar
new file mode 100644 (file)
index 0000000..4646100
Binary files /dev/null and b/ext/phar/tests/tar/files/links.phar.tar differ
diff --git a/ext/phar/tests/tar/links6.phpt b/ext/phar/tests/tar/links6.phpt
new file mode 100644 (file)
index 0000000..622a8b6
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Phar: test nested linked files
+--SKIPIF--
+<?php
+if (!extension_loaded("phar")) die("skip");
+?>
+--FILE--
+<?php
+echo file_get_contents('phar://' . dirname(__FILE__) . '/files/links.phar.tar/link2');
+echo file_get_contents('phar://' . dirname(__FILE__) . '/files/links.phar.tar/link1');
+echo file_get_contents('phar://' . dirname(__FILE__) . '/files/links.phar.tar/testit.txt');
+?>
+===DONE===
+--EXPECT--
+hi there
+
+hi there
+
+hi there
+
+===DONE===
\ No newline at end of file
index 7e9c50ac643a4305e087622faf4c7da09b212d4b..224b7e778b230b9be593b856d888ab9ffc1c23a7 100644 (file)
@@ -65,12 +65,13 @@ static char *phar_get_link_location(phar_entry_info *entry TSRMLS_DC) /* {{{ */
 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 TSRMLS_CC);
+       char *link;
 
        if (!entry->link) {
                return entry;
        }
 
+       link = phar_get_link_location(entry TSRMLS_CC);
        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) {
@@ -680,13 +681,13 @@ really_get_entry:
                        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->is_tar ? TAR_FILE : '\0');
-               }
-
                if (for_write) {
+                       if (entry->link) {
+                               efree(entry->link);
+                               entry->link = NULL;
+                               entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
+                       }
+
                        if (for_trunc) {
                                if (FAILURE == phar_create_writeable_entry(phar, entry, error TSRMLS_CC)) {
                                        return FAILURE;
@@ -711,7 +712,11 @@ really_get_entry:
        (*ret)->is_zip = entry->is_zip;
        (*ret)->is_tar = entry->is_tar;
        (*ret)->fp = phar_get_efp(entry, 1 TSRMLS_CC);
-       (*ret)->zero = phar_get_fp_offset(entry TSRMLS_CC);
+       if (entry->link) {
+               (*ret)->zero = phar_get_fp_offset(phar_get_link_source(entry TSRMLS_CC) TSRMLS_CC);
+       } else {
+               (*ret)->zero = phar_get_fp_offset(entry TSRMLS_CC);
+       }
 
        if (!phar->is_persistent) {
                ++(entry->fp_refcount);