init
This commit is contained in:
@@ -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', ''),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user