Skip to content

Commit 1787cea

Browse files
committed
Require PATH-discovered FFmpeg binary to be executable
which/where can return a stale non-executable path; treat that the same as a missing binary so video thumbnail URLs are not emitted.
1 parent 23db8db commit 1787cea

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

src/Console/Processes/Ffmpeg.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,11 @@ private function resolveFfmpegBinary(): ?string
9090
->explode("\n")
9191
->first();
9292

93-
return filled($resolved) ? $resolved : null;
93+
if (! filled($resolved) || ! is_executable($resolved)) {
94+
return null;
95+
}
96+
97+
return $resolved;
9498
}
9599

96100
public static function clearBinaryCache(): void

tests/Console/FfmpegTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,35 @@ public function it_memoizes_binary_resolution_across_instances()
5454
$this->assertNull((new Ffmpeg)->ffmpegBinary());
5555
}
5656

57+
#[Test]
58+
public function it_ignores_a_path_discovered_binary_that_is_not_executable()
59+
{
60+
Ffmpeg::clearBinaryCache();
61+
config(['statamic.assets.ffmpeg.binary' => null]);
62+
63+
$path = storage_path('non-executable-ffmpeg');
64+
file_put_contents($path, '');
65+
chmod($path, 0644);
66+
67+
$ffmpeg = new class($path) extends Ffmpeg
68+
{
69+
public function __construct(private string $discoveredPath)
70+
{
71+
parent::__construct();
72+
}
73+
74+
public function run($command, $cacheKey = null)
75+
{
76+
return $this->discoveredPath;
77+
}
78+
};
79+
80+
$this->assertNull($ffmpeg->ffmpegBinary());
81+
$this->assertFalse($ffmpeg->available());
82+
83+
@unlink($path);
84+
}
85+
5786
private function buildCommand(...$arguments)
5887
{
5988
$method = (new \ReflectionClass(Ffmpeg::class))->getMethod('buildCommand');

0 commit comments

Comments
 (0)