1
0
Fork 0

Merge pull request #9465 from BR0kEN-/issues/9464

#9464: ZipArchiver incorrectly treats `.gitignore` directory inclusions
pull/9651/head
Jordi Boggiano 2021-01-26 10:42:26 +01:00 committed by GitHub
commit 471a63c206
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 29 deletions

View File

@ -123,26 +123,25 @@ abstract class BaseExcludeFilter
protected function generatePattern($rule)
{
$negate = false;
$pattern = '{';
$pattern = '';
if (strlen($rule) && $rule[0] === '!') {
if ($rule !== '' && $rule[0] === '!') {
$negate = true;
$rule = substr($rule, 1);
$rule = ltrim($rule, '!');
}
if (strlen($rule) && $rule[0] === '/') {
$pattern .= '^/';
$rule = substr($rule, 1);
} elseif (strlen($rule) - 1 === strpos($rule, '/')) {
$pattern .= '/';
$rule = substr($rule, 0, -1);
} elseif (false === strpos($rule, '/')) {
$pattern .= '/';
$firstSlashPosition = strpos($rule, '/');
if (0 === $firstSlashPosition) {
$pattern = '^/';
} elseif (false === $firstSlashPosition || strlen($rule) - 1 === $firstSlashPosition) {
$pattern = '/';
}
$rule = trim($rule, '/');
// remove delimiters as well as caret (^) and dollar sign ($) from the regex
$pattern .= substr(Finder\Glob::toRegex($rule), 2, -2) . '(?=$|/)';
$rule = substr(Finder\Glob::toRegex($rule), 2, -2);
return array($pattern . '}', $negate, false);
return array('{'.$pattern.$rule.'(?=$|/)}', $negate, false);
}
}

View File

@ -18,20 +18,44 @@ use Composer\Package\Archiver\ZipArchiver;
class ZipArchiverTest extends ArchiverTest
{
public function testZipArchive()
/**
* @param string $include
*
* @dataProvider provideGitignoreExcludeNegationTestCases
*/
public function testGitignoreExcludeNegation($include)
{
$this->testZipArchive(array(
'docs/README.md' => '# The doc',
'.gitignore' => "/*\n.*\n!.git*\n$include",
));
}
public function provideGitignoreExcludeNegationTestCases()
{
return array(
array('!/docs'),
array('!/docs/'),
);
}
public function testZipArchive(array $files = array())
{
if (!class_exists('ZipArchive')) {
$this->markTestSkipped('Cannot run ZipArchiverTest, missing class "ZipArchive".');
}
$files = array(
'file.txt',
'foo/bar/baz',
'x/baz',
'x/includeme',
);
if (!Platform::isWindows()) {
$files[] = 'foo' . getcwd() . '/file.txt';
if (empty($files)) {
$files = array(
'file.txt' => NULL,
'foo/bar/baz' => NULL,
'x/baz' => NULL,
'x/includeme' => NULL,
);
if (!Platform::isWindows()) {
$files['foo' . getcwd() . '/file.txt'] = NULL;
}
}
// Set up repository
$this->setupDummyRepo($files);
@ -41,12 +65,12 @@ class ZipArchiverTest extends ArchiverTest
// Test archive
$archiver = new ZipArchiver();
$archiver->archive($package->getSourceUrl(), $target, 'zip');
$this->assertFileExists($target);
static::assertFileExists($target);
$zip = new ZipArchive();
$res = $zip->open($target);
self::assertTrue($res, 'Failed asserting that Zip file can be opened');
foreach ($files as $file) {
$this->assertSame('content', $zip->getFromName($file), 'Failed asserting that Zip contains ' . $file);
static::assertTrue($res, 'Failed asserting that Zip file can be opened');
foreach ($files as $path => $content) {
static::assertSame($content, $zip->getFromName($path), 'Failed asserting that Zip contains ' . $path);
}
$zip->close();
@ -57,12 +81,15 @@ class ZipArchiverTest extends ArchiverTest
* Create a local dummy repository to run tests against!
* @param array $files
*/
protected function setupDummyRepo($files)
protected function setupDummyRepo(array &$files)
{
$currentWorkDir = getcwd();
chdir($this->testDir);
foreach ($files as $file) {
$this->writeFile($file, 'content', $currentWorkDir);
foreach ($files as $path => $content) {
if ($files[$path] === NULL) {
$files[$path] = 'content';
}
$this->writeFile($path, $files[$path], $currentWorkDir);
}
chdir($currentWorkDir);