This commit is contained in:
hashbro
2026-08-05 06:01:42 +08:00
parent 22942f1a78
commit 3b9e653cea
80 changed files with 561 additions and 6 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ class AppServiceProvider extends ServiceProvider
$this->app->singleton(CorunaArchive::class, function ($app) {
return new CorunaArchive(
$app->make(CorunaCrypto::class),
(string) config('coruna.seven_zip', '/opt/homebrew/opt/p7zip/bin/7z'),
(string) config('coruna.seven_zip', ''),
);
});
}
+58 -2
View File
@@ -20,7 +20,7 @@ class CorunaArchive
public function __construct(
private readonly CorunaCrypto $crypto,
private readonly string $sevenZip = '/opt/homebrew/opt/p7zip/bin/7z',
private readonly string $sevenZip = '',
) {}
public function isCorunaHeader(string $data): bool
@@ -85,7 +85,7 @@ class CorunaArchive
$membersDir = $destDir.'/members';
@mkdir($membersDir, 0755, true);
$bin = is_executable($this->sevenZip) ? $this->sevenZip : '7z';
$bin = $this->resolveSevenZipBinary();
$result = Process::timeout(120)->run([
$bin, 'x', '-y',
'-p'.$password,
@@ -113,4 +113,60 @@ class CorunaArchive
'password_recipe' => 'session_key||'.$batchBase,
];
}
/**
* Resolve 7z path without probing outside open_basedir.
* is_executable('/usr/bin/7z') fatals under typical panel open_basedir.
*/
private function resolveSevenZipBinary(): string
{
$configured = trim($this->sevenZip);
$candidates = array_values(array_unique(array_filter([
$configured,
// Prefer a binary vendored inside the Laravel root (within open_basedir).
base_path('bin/7z'),
'7z',
])));
foreach ($candidates as $candidate) {
if ($candidate === '7z') {
return '7z';
}
if (! $this->isPathInsideOpenBasedir($candidate)) {
// Still try absolute configured path: exec() is often allowed even when
// is_executable() is blocked. Skip the filesystem probe.
if ($candidate === $configured && str_starts_with($candidate, '/')) {
return $candidate;
}
continue;
}
if (@is_file($candidate) && @is_executable($candidate)) {
return $candidate;
}
}
return $configured !== '' ? $configured : '7z';
}
private function isPathInsideOpenBasedir(string $path): bool
{
$basedir = (string) ini_get('open_basedir');
if ($basedir === '') {
return true;
}
$real = realpath($path);
$check = $real !== false ? $real : $path;
foreach (explode(PATH_SEPARATOR, $basedir) as $root) {
$root = rtrim($root, DIRECTORY_SEPARATOR);
if ($root === '') {
continue;
}
if ($check === $root || str_starts_with($check, $root.DIRECTORY_SEPARATOR)) {
return true;
}
}
return false;
}
}