Fix Bug #49020: phar misinterprets ustar long filename standard

This commit is contained in:
Greg Beaver 2009-07-22 19:51:37 +00:00
parent 6bfa373248
commit aef00895ad
3 changed files with 43 additions and 11 deletions

View file

@ -341,6 +341,7 @@ bail:
break; break;
} }
} }
name[i++] = '/';
for (j = 0; j < 100; j++) { for (j = 0; j < 100; j++) {
name[i+j] = hdr->name[j]; name[i+j] = hdr->name[j];
if (name[i+j] == '\0') { if (name[i+j] == '\0') {
@ -641,14 +642,25 @@ static int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ *
memset((char *) &header, 0, sizeof(header)); memset((char *) &header, 0, sizeof(header));
if (entry->filename_len > 100) { if (entry->filename_len > 100) {
if (entry->filename_len > 255) { char *boundary;
if (entry->filename_len > 256) {
if (fp->error) { if (fp->error) {
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, entry->filename); spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, entry->filename);
} }
return ZEND_HASH_APPLY_STOP; return ZEND_HASH_APPLY_STOP;
} }
memcpy(header.prefix, entry->filename, entry->filename_len - 100); boundary = entry->filename + entry->filename_len - 101;
memcpy(header.name, entry->filename + (entry->filename_len - 100), 100); while (*boundary && *boundary != '/') {
++boundary;
}
if (!*boundary || ((boundary - entry->filename) > 155)) {
if (fp->error) {
spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, entry->filename);
}
return ZEND_HASH_APPLY_STOP;
}
memcpy(header.prefix, entry->filename, boundary - entry->filename);
memcpy(header.name, boundary + 1, entry->filename_len - (boundary + 1 - entry->filename));
} else { } else {
memcpy(header.name, entry->filename, entry->filename_len); memcpy(header.name, entry->filename, entry->filename_len);
} }

View file

@ -8,30 +8,50 @@ phar.require_hash=0
<?php <?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar'; $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar';
$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.tar'; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.tar';
$fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.3.tar';
$fname4 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.4.tar';
$pname = 'phar://' . $fname; $pname = 'phar://' . $fname;
$p1 = new PharData($fname); $p1 = new PharData($fname);
$p1[str_repeat('a', 100) . 'b'] = 'hi'; $p1[str_repeat('a', 100) . '/b'] = 'hi';
$p1[str_repeat('a', 255)] = 'hi2'; $p1[str_repeat('a', 155) . '/' . str_repeat('b', 100)] = 'hi2';
copy($fname, $fname2); copy($fname, $fname2);
$p2 = new PharData($fname2); $p2 = new PharData($fname2);
echo $p2[str_repeat('a', 100) . 'b']->getContent() . "\n"; echo $p2[str_repeat('a', 100) . '/b']->getContent() . "\n";
echo $p2[str_repeat('a', 255)]->getContent() . "\n"; echo $p2[str_repeat('a', 155) . '/' . str_repeat('b', 100)]->getContent() . "\n";
try { try {
$p2[str_repeat('a', 400)] = 'yuck'; $p2[str_repeat('a', 400)] = 'yuck';
} catch (Exception $e) { } catch (Exception $e) {
echo $e->getMessage() . "\n"; echo $e->getMessage() . "\n";
} }
try {
$p2 = new PharData($fname3);
$p2[str_repeat('a', 101)] = 'yuck';
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
try {
$p2 = new PharData($fname4);
$p2[str_repeat('b', 160) . '/' . str_repeat('a', 90)] = 'yuck';
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
?> ?>
===DONE=== ===DONE===
--CLEAN-- --CLEAN--
<?php <?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.tar');
@unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.3.tar');
@unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.4.tar');
?> ?>
--EXPECTF-- --EXPECTF--
hi hi
hi2 hi2
tar-based phar "%sbignames.2.tar" cannot be created, filename "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format tar-based phar "%sbignames.2.tar" cannot be created, filename "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format
tar-based phar "%sbignames.3.tar" cannot be created, filename "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format
tar-based phar "%sbignames.4.tar" cannot be created, filename "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format
===DONE=== ===DONE===

View file

@ -22,8 +22,8 @@ $p1 = new PharData($fname);
foreach ($p1 as $file) { foreach ($p1 as $file) {
echo $file->getFileName(), "\n"; echo $file->getFileName(), "\n";
} }
echo $p1[str_repeat('a', 101)]->getContent() . "\n"; echo $p1['a/' . str_repeat('a', 100)]->getContent() . "\n";
echo $p1[str_repeat('a', 255)]->getContent() . "\n"; echo $p1[str_repeat('a', 155) . '/' . str_repeat('a', 100)]->getContent() . "\n";
?> ?>
===DONE=== ===DONE===
@ -33,8 +33,8 @@ unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.tar');
?> ?>
--EXPECT-- --EXPECT--
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
hi hi
hi2 hi2
===DONE=== ===DONE===