Skip to content

Commit

Permalink
Merge pull request #4838 from mhsdesign/bugfix/4415-fusion-error-on-d…
Browse files Browse the repository at this point in the history
…ev-cache-invalidation-attempt-2

BUGFIX: Fusion avoid error on cache invalidation while developing
  • Loading branch information
kitsunet authored Jan 16, 2024
2 parents 28ddd36 + 5377b86 commit ec26823
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
7 changes: 6 additions & 1 deletion Neos.Fusion/Classes/Core/Cache/ParserCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ public function cacheForFusionFile(?string $contextPathAndFilename, \Closure $ge
if (str_contains($contextPathAndFilename, '://')) {
$contextPathAndFilename = $this->getAbsolutePathForPackageRessourceUri($contextPathAndFilename);
}
$identifier = $this->getCacheIdentifierForFile($contextPathAndFilename);
$fusionFileRealPath = realpath($contextPathAndFilename);
if ($fusionFileRealPath === false) {
// should not happen as the file would not been able to be read in the first place.
throw new \RuntimeException("Couldn't resolve realpath for: '$contextPathAndFilename'", 1705409467);
}
$identifier = $this->getCacheIdentifierForAbsoluteUnixStyleFilePathWithoutDirectoryTraversal($fusionFileRealPath);
return $this->cacheForIdentifier($identifier, $generateValueToCache);
}

Expand Down
5 changes: 4 additions & 1 deletion Neos.Fusion/Classes/Core/Cache/ParserCacheFlusher.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ public function flushPartialCacheOnFileChanges($fileMonitorIdentifier, array $ch

$identifiersToFlush = [];
foreach ($changedFiles as $changedFile => $status) {
$identifiersToFlush[] = $this->getCacheIdentifierForFile($changedFile);
// flow already returns absolute file paths from the file monitor, so we don't have to call realpath.
// attempting to use realpath can even result in an error as the file might be removed and thus no realpath can be resolved via file system.
// https://github.com/neos/neos-development-collection/pull/4509
$identifiersToFlush[] = $this->getCacheIdentifierForAbsoluteUnixStyleFilePathWithoutDirectoryTraversal($changedFile);
}

if ($identifiersToFlush !== []) {
Expand Down
30 changes: 18 additions & 12 deletions Neos.Fusion/Classes/Core/Cache/ParserCacheIdentifierTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,32 @@
trait ParserCacheIdentifierTrait
{
/**
* creates a comparable hash of the dsl type and content to be used as cache identifier
* Creates a comparable hash of the dsl type and content to be used as cache identifier
*/
private function getCacheIdentifierForDslCode(string $identifier, string $code): string
{
return 'dsl_' . $identifier . '_' . md5($code);
}

/**
* creates a comparable hash of the absolute, resolved $fusionFileName
* Creates a comparable hash of the absolute-unix-style-file-path-without-directory-traversal
*
* @throws \InvalidArgumentException
* something like
* - /Users/marc/Code/neos-project/Packages/Neos
*
* its crucial that the path
* - is absolute
* - the path separator is in unix style: forward-slash /
* - doesn't contain directory traversal /../ or /./
*
* to be absolutely sure the path matches the criteria, {@see realpath} can be used.
*
* if the path does not match the criteria, a different hash as expected will be generated and caching will break.
*/
private function getCacheIdentifierForFile(string $fusionFileName): string
{
$realPath = realpath($fusionFileName);
if ($realPath === false) {
throw new \InvalidArgumentException("Couldn't resolve realpath for: '$fusionFileName'");
}

$realFusionFilePathWithoutRoot = str_replace(FLOW_PATH_ROOT, '', $realPath);
return 'file_' . md5($realFusionFilePathWithoutRoot);
private function getCacheIdentifierForAbsoluteUnixStyleFilePathWithoutDirectoryTraversal(
string $absoluteUnixStyleFilePathWithoutDirectoryTraversal
): string {
$filePathWithoutRoot = str_replace(FLOW_PATH_ROOT, '', $absoluteUnixStyleFilePathWithoutDirectoryTraversal);
return 'file_' . md5($filePathWithoutRoot);
}
}

0 comments on commit ec26823

Please sign in to comment.