diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..5d5d197ca --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# Exclude development and CI/CD files from release archives +/.github export-ignore +/.phan export-ignore +/tests export-ignore +/codeception.yml export-ignore +/.travis.yml export-ignore +/.dependencies export-ignore +/.editorconfig export-ignore diff --git a/system/src/Grav/Common/Upgrade/SafeUpgradeService.php b/system/src/Grav/Common/Upgrade/SafeUpgradeService.php index 687ada268..e1ef1e2d9 100644 --- a/system/src/Grav/Common/Upgrade/SafeUpgradeService.php +++ b/system/src/Grav/Common/Upgrade/SafeUpgradeService.php @@ -84,6 +84,8 @@ class SafeUpgradeService 'tmp', 'cache', 'user', + '.github', + '.phan', ]; /** @var callable|null */ private $progressCallback = null; @@ -913,10 +915,14 @@ class SafeUpgradeService $stage = $packagePath . '/' . $relative; // Only delete from staging area, NEVER from live installation - if (strpos($stage, $this->rootPath . DIRECTORY_SEPARATOR) === 0) { + // Check if stage path is directly under root (e.g., /home/grav/user) + // but allow subdirectories (e.g., /home/grav/tmp/.../package/user) + $realStage = realpath(dirname($stage)); + $realRoot = realpath($this->rootPath); + if ($realStage === $realRoot) { throw new RuntimeException( 'SAFETY VIOLATION: Attempted to delete directory from live installation during hydration. ' . - 'Stage path appears to be within live root. This should never happen.' + 'Stage path appears to be directly in live root. This should never happen.' ); }