|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-04-05 13:09 UTC] pandrade at redhat dot com
Description:
------------
To test the below script, run first:
$ touch file1 file2 file3
$ tar zcf dotslash.tar.gz ./file1 ./file2 ./file3
$ tar zcf nodotslash.tar.gz file1 file2 file3
I made an initial experiment, that "almost" works,
will work for "./file" but fail for "./dir/file".
---8<---
diff -up php-5.4.16/ext/phar/tar.c.orig php-5.4.16/ext/phar/tar.c
--- php-5.4.16/ext/phar/tar.c.orig 2016-03-29 11:39:57.020599910 -0300
+++ php-5.4.16/ext/phar/tar.c 2016-03-29 11:42:25.582624697 -0300
@@ -481,6 +481,9 @@ bail:
entry.link = estrdup(hdr->linkname);
}
phar_set_inode(&entry TSRMLS_CC);
+ if (entry.filename_len > 2 && entry.filename[0] == '.' && entry.filename[1] == '/')
+ /* Also copy trailing nul */
+ memmove(entry.filename, entry.filename + 2, (entry.filename_len -= 2) + 1);
zend_hash_add(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry);
if (entry.is_persistent) {
---8<---
If erroring out on "." or ".." on tar pathnames is the
expected result, please let me know.
Test script:
---------------
#!/usr/bin/php
<?php
echo "\nRunning for the broken file\n";
$path = realpath('./dotslash.tar.gz');
$pharpath = "phar://" . $path;
$phardata = new PharData($path);
$phariter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharpath));
echo "The phar has " . $phardata->count() . " entries\n";
$i = 0;
foreach($phariter as $file){
echo $file . "\n";
$i++;
}
echo "There were $i entries listed.\n";
echo "\nNow running for the working file\n";
$path = realpath('./nodotslash.tar.gz');
$pharpath = "phar://" . $path;
$phardata = new PharData($path);
$phariter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharpath));
echo "The phar has " . $phardata->count() . " entries\n";
$i = 0;
foreach($phariter as $file){
echo $file . "\n";
$i++;
}
echo "There were $i entries listed.\n";
?>
Expected result:
----------------
$ ./pharbug.php
Running for the broken file
The phar has 3 entries
phar:///home/testuser/dotslash.tar.gz/file1
phar:///home/testuser/dotslash.tar.gz/file2
phar:///home/testuser/dotslash.tar.gz/file3
There were 3 entries listed.
Now running for the working file
The phar has 3 entries
phar:///home/testuser/nodotslash.tar.gz/file1
phar:///home/testuser/nodotslash.tar.gz/file2
phar:///home/testuser/nodotslash.tar.gz/file3
There were 3 entries listed.
Actual result:
--------------
$ ./pharbug.php
Running for the broken file
The phar has 3 entries
phar:///home/testuser/dotslash.tar.gz/.
There were 1 entries listed.
Now running for the working file
The phar has 3 entries
phar:///home/testuser/nodotslash.tar.gz/file1
phar:///home/testuser/nodotslash.tar.gz/file2
phar:///home/testuser/nodotslash.tar.gz/file3
There were 3 entries listed.
Patchesphp-dotslash.patch (last revision 2016-04-05 13:10 UTC by pandrade at redhat dot com)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 18:00:01 2025 UTC |
I'm experiencing this problem too (linux, php 7.2.10, but this is not relevant really). How to reproduce: 1. Create archive with paths starting with "./": > $ tar -cvf myfile.tar . 2. Check that files paths start with "./": > $ tar -tvf myfile.tar 3. Try to iterate over archive: > $this->tar = new PharData('myfile.tar', FilesystemIterator::UNIX_PATHS); > foreach (new RecursiveIteratorIterator($this->tar) as $i => $file) { > // ... > } Got an exception: PHP Fatal error: Uncaught RuntimeException: Cannot access phar file entry '/' in archive '...' in ... Stack trace: #0 [internal function]: PharFileInfo->__construct('phar:///home/wa...') #1 ...(...): FilesystemIterator->current() --- This problem is really annoying, making impossible work with these types of achives.