Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0704c26

Browse files
committed
bug #54724 [AssetMapper] Check asset/vendor directory is writable (smnandre)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [AssetMapper] Check asset/vendor directory is writable | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #54719 | License | MIT 💐 Commits ------- 7c2da27 [AssetMapper] Check asset/vendor directory is writable
2 parents 50faef9 + 7c2da27 commit 0704c26

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

src/Symfony/Component/AssetMapper/ImportMap/RemotePackageStorage.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\AssetMapper\ImportMap;
1313

14+
use Symfony\Component\AssetMapper\Exception\RuntimeException;
15+
1416
/**
1517
* Manages the local storage of remote/vendor importmap packages.
1618
*/
@@ -52,7 +54,9 @@ public function save(ImportMapEntry $entry, string $contents): void
5254
$vendorPath = $this->getDownloadPath($entry->packageModuleSpecifier, $entry->type);
5355

5456
@mkdir(\dirname($vendorPath), 0777, true);
55-
file_put_contents($vendorPath, $contents);
57+
if (false === @file_put_contents($vendorPath, $contents)) {
58+
throw new RuntimeException(error_get_last()['message'] ?? sprintf('Failed to write file "%s".', $vendorPath));
59+
}
5660
}
5761

5862
public function saveExtraFile(ImportMapEntry $entry, string $extraFilename, string $contents): void
@@ -64,7 +68,9 @@ public function saveExtraFile(ImportMapEntry $entry, string $extraFilename, stri
6468
$vendorPath = $this->getExtraFileDownloadPath($entry, $extraFilename);
6569

6670
@mkdir(\dirname($vendorPath), 0777, true);
67-
file_put_contents($vendorPath, $contents);
71+
if (false === @file_put_contents($vendorPath, $contents)) {
72+
throw new RuntimeException(error_get_last()['message'] ?? sprintf('Failed to write file "%s".', $vendorPath));
73+
}
6874
}
6975

7076
/**

src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapManagerTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ public static function getRequirePackageTests(): iterable
201201
];
202202

203203
yield 'single_package_with_a_path' => [
204-
'packages' => [new PackageRequireOptions('some/module', path: self::$writableRoot.'/assets/some_file.js')],
205-
'expectedProviderPackageArgumentCount' => 0,
206-
'resolvedPackages' => [],
207-
'expectedImportMap' => [
208-
'some/module' => [
209-
// converted to relative path
210-
'path' => './assets/some_file.js',
204+
'packages' => [new PackageRequireOptions('some/module', path: self::$writableRoot.'/assets/some_file.js')],
205+
'expectedProviderPackageArgumentCount' => 0,
206+
'resolvedPackages' => [],
207+
'expectedImportMap' => [
208+
'some/module' => [
209+
// converted to relative path
210+
'path' => './assets/some_file.js',
211+
],
211212
],
212-
],
213213
];
214214
}
215215

src/Symfony/Component/AssetMapper/Tests/ImportMap/RemotePackageStorageTest.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class RemotePackageStorageTest extends TestCase
2525
protected function setUp(): void
2626
{
2727
$this->filesystem = new Filesystem();
28-
if (!file_exists(self::$writableRoot)) {
28+
if (!$this->filesystem->exists(self::$writableRoot)) {
2929
$this->filesystem->mkdir(self::$writableRoot);
3030
}
3131
}
@@ -41,14 +41,30 @@ public function testGetStorageDir()
4141
$this->assertSame(realpath(self::$writableRoot.'/assets/vendor'), realpath($storage->getStorageDir()));
4242
}
4343

44+
public function testSaveThrowsWhenVendorDirectoryIsNotWritable()
45+
{
46+
$this->filesystem->mkdir($vendorDir = self::$writableRoot.'/assets/acme/vendor');
47+
$this->filesystem->chmod($vendorDir, 0555);
48+
49+
$storage = new RemotePackageStorage($vendorDir);
50+
$entry = ImportMapEntry::createRemote('foo', ImportMapType::JS, '/does/not/matter', '1.0.0', 'module_specifier', false);
51+
52+
$this->expectException(\RuntimeException::class);
53+
$this->expectExceptionMessage('file_put_contents('.$vendorDir.'/module_specifier/module_specifier.index.js): Failed to open stream: No such file or directory');
54+
$storage->save($entry, 'any content');
55+
56+
$this->filesystem->remove($vendorDir);
57+
}
58+
4459
public function testIsDownloaded()
4560
{
4661
$storage = new RemotePackageStorage(self::$writableRoot.'/assets/vendor');
4762
$entry = ImportMapEntry::createRemote('foo', ImportMapType::JS, '/does/not/matter', '1.0.0', 'module_specifier', false);
4863
$this->assertFalse($storage->isDownloaded($entry));
64+
4965
$targetPath = self::$writableRoot.'/assets/vendor/module_specifier/module_specifier.index.js';
50-
@mkdir(\dirname($targetPath), 0777, true);
51-
file_put_contents($targetPath, 'any content');
66+
$this->filesystem->mkdir(\dirname($targetPath));
67+
$this->filesystem->dumpFile($targetPath, 'any content');
5268
$this->assertTrue($storage->isDownloaded($entry));
5369
}
5470

@@ -57,9 +73,10 @@ public function testIsExtraFileDownloaded()
5773
$storage = new RemotePackageStorage(self::$writableRoot.'/assets/vendor');
5874
$entry = ImportMapEntry::createRemote('foo', ImportMapType::JS, '/does/not/matter', '1.0.0', 'module_specifier', false);
5975
$this->assertFalse($storage->isExtraFileDownloaded($entry, '/path/to/extra.woff'));
76+
6077
$targetPath = self::$writableRoot.'/assets/vendor/module_specifier/path/to/extra.woff';
61-
@mkdir(\dirname($targetPath), 0777, true);
62-
file_put_contents($targetPath, 'any content');
78+
$this->filesystem->mkdir(\dirname($targetPath));
79+
$this->filesystem->dumpFile($targetPath, 'any content');
6380
$this->assertTrue($storage->isExtraFileDownloaded($entry, '/path/to/extra.woff'));
6481
}
6582

@@ -92,7 +109,7 @@ public function testGetDownloadedPath(string $packageModuleSpecifier, ImportMapT
92109
$this->assertSame($expectedPath, $storage->getDownloadPath($packageModuleSpecifier, $importMapType));
93110
}
94111

95-
public static function getDownloadPathTests()
112+
public static function getDownloadPathTests(): iterable
96113
{
97114
yield 'javascript bare package' => [
98115
'packageModuleSpecifier' => 'foo',

0 commit comments

Comments
 (0)