Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions FFmpeg.AutoGen.Redist/FFmpeg.AutoGen.Redist.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<PackageId>FFmpeg.AutoGen.Redist</PackageId>
<Version>7.1.2</Version>
<Version>7.1.3</Version>
<Description>FFmpeg native binaries redistribution package</Description>
<Copyright>Copyright © FFmpeg.AutoGen Contributors</Copyright>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
Expand All @@ -17,17 +17,20 @@
<None Include="README.md" Pack="true" PackagePath="\"/>
</ItemGroup>

<!-- Ship the shared-linked FFmpeg DLLs. SDL2/openal are excluded: their only
consumer was ffplay.exe, which we no longer ship. -->
<!-- Ship the shared-linked FFmpeg DLLs. SDL2.dll and libopenal-1.dll are required:
avdevice-if-61.dll links against both, and avdevice-if-61.dll is a static import
of ffmpeg.exe and ffprobe.exe, so the Windows loader needs them next to the exe or
the process fails at startup with STATUS_DLL_NOT_FOUND (0xC0000135). ffplay.exe is
still dropped: it is the only binary we do not ship, and nothing else imports it. -->
<ItemGroup>
<Content Include="../FFmpeg/bin/*.dll" Exclude="../FFmpeg/bin/SDL2.dll;../FFmpeg/bin/libopenal-1.dll" Pack="true" PackagePath="runtimes/win-x64/native/" CopyToOutputDirectory="PreserveNewest" />
<Content Include="../FFmpeg/bin/*.dll" Pack="true" PackagePath="runtimes/win-x64/native/" CopyToOutputDirectory="PreserveNewest" />
<Content Include="../FFmpeg/bin/ffmpeg.exe" Pack="true" PackagePath="runtimes/win-x64/native/" CopyToOutputDirectory="PreserveNewest" />
<Content Include="../FFmpeg/bin/ffprobe.exe" Pack="true" PackagePath="runtimes/win-x64/native/" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

<!-- Copy binaries to output directory when building projects that reference this -->
<ItemGroup>
<None Include="../FFmpeg/bin/*.dll" Exclude="../FFmpeg/bin/SDL2.dll;../FFmpeg/bin/libopenal-1.dll" CopyToOutputDirectory="PreserveNewest" />
<None Include="../FFmpeg/bin/*.dll" CopyToOutputDirectory="PreserveNewest" />
<None Include="../FFmpeg/bin/ffmpeg.exe" CopyToOutputDirectory="PreserveNewest" />
<None Include="../FFmpeg/bin/ffprobe.exe" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Expand Down
Binary file added FFmpeg/bin/SDL2.dll
Binary file not shown.
Binary file added FFmpeg/bin/libopenal-1.dll
Binary file not shown.
2 changes: 2 additions & 0 deletions scripts/redist-manifest.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
SDL2.dll
avcodec-if-61.dll
avdevice-if-61.dll
avfilter-if-10.dll
Expand Down Expand Up @@ -41,6 +42,7 @@ libmodplug-1.dll
libmp3lame-0.dll
libnettle-8.dll
libogg-0.dll
libopenal-1.dll
libopenjp2-7.dll
libopus-0.dll
libp11-kit-0.dll
Expand Down
22 changes: 18 additions & 4 deletions scripts/test_verify_redist.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ def build_minimal_pe(imported_dlls: list[str], extra_padding: int = 0) -> bytes:
return bytes(header_blob) + section_payload + b"\x00" * extra_padding


GOOD_FFMPEG_IMPORTS = ["avcodec-if-61.dll", "avutil-if-59.dll", "KERNEL32.dll"]
GOOD_FFMPEG_IMPORTS = [
"avcodec-if-61.dll",
"avutil-if-59.dll",
"avdevice-if-61.dll",
"KERNEL32.dll",
]

BASELINE_FILES = {
"ffmpeg.exe": build_minimal_pe(GOOD_FFMPEG_IMPORTS),
Expand Down Expand Up @@ -222,12 +227,21 @@ def test_manifest_gate_fails_on_missing_file(self):

# --- gate 2: forbidden files ---

def test_forbidden_gate_fails_on_reintroduced_sdl2(self):
def test_forbidden_gate_fails_on_ffplay(self):
doctored = dict(BASELINE_FILES)
doctored["SDL2.dll"] = b"\x00" * 10
doctored["ffplay.exe"] = b"\x00" * 10
results = self._run(doctored, manifest_names=doctored.keys())
self._assert_only_failed(results, "forbidden-files")

def test_forbidden_gate_allows_sdl2_and_openal(self):
# avdevice-if-61.dll links SDL2.dll + libopenal-1.dll, and avdevice is a
# static import of the exes, so both DLLs are required payload now.
allowed = dict(BASELINE_FILES)
allowed["SDL2.dll"] = b"\x00" * 10
allowed["libopenal-1.dll"] = b"\x00" * 10
results = self._run(allowed, manifest_names=allowed.keys())
self.assertTrue(results["forbidden-files"].passed)

def test_forbidden_gate_fails_on_pdb(self):
doctored = dict(BASELINE_FILES)
doctored["avcodec-if-61.pdb"] = b"\x00" * 10
Expand Down Expand Up @@ -333,7 +347,7 @@ def test_main_exit_code_zero_on_good_package(self):

def test_main_exit_code_nonzero_on_doctored_package(self):
doctored = dict(BASELINE_FILES)
doctored["SDL2.dll"] = b"\x00" * 10
doctored["ffplay.exe"] = b"\x00" * 10
nupkg = build_nupkg(self.tmp_path / "cli-bad.nupkg", doctored)
manifest = self._manifest(doctored.keys())
with mock.patch.object(vr, "DEFAULT_MANIFEST_PATH", manifest):
Expand Down
18 changes: 13 additions & 5 deletions scripts/verify_redist.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
1. manifest - exact file-set compare of runtimes/win-x64/native/ against
scripts/redist-manifest.txt (catches unexpected extra files,
not just missing required ones).
2. forbidden - ffplay.exe, SDL2.dll, libopenal-1.dll, *.pdb must not be present.
2. forbidden - ffplay.exe and *.pdb must not be present. (SDL2.dll and
libopenal-1.dll are required payload: avdevice-if-61.dll links
against them and is a static import of ffmpeg.exe/ffprobe.exe.)
3. sizes - nupkg < 100MB; ffmpeg.exe / ffprobe.exe < 5MB each;
avcodec-if-*.dll < 1.5x its known baseline size.
4. pe-imports - ffmpeg.exe / ffprobe.exe must import avcodec-if-61.dll and
avutil-if-59.dll, and must not import SDL2.dll.
4. pe-imports - ffmpeg.exe / ffprobe.exe must import avcodec-if-61.dll,
avutil-if-59.dll and avdevice-if-61.dll, and must not import
SDL2.dll directly (SDL2 is pulled in transitively via avdevice).
5. gpl-scan - no binary may contain evidence of a linked x264/x265 GPL
encoder (project banner strings, or an embedded
--enable-gpl / --enable-libx264 / --enable-libx265
Expand Down Expand Up @@ -43,9 +46,14 @@

NATIVE_PREFIX = "runtimes/win-x64/native/"

FORBIDDEN_EXACT_NAMES = {"ffplay.exe", "SDL2.dll", "libopenal-1.dll"}
# SDL2.dll and libopenal-1.dll are legitimate payload: avdevice-if-61.dll links
# against both, and avdevice is a static import of ffmpeg.exe/ffprobe.exe. Only
# ffplay.exe (unused, its own separate consumer) and debug symbols stay banned.
FORBIDDEN_EXACT_NAMES = {"ffplay.exe"}

REQUIRED_PE_IMPORTS = {"avcodec-if-61.dll", "avutil-if-59.dll"}
# ffmpeg.exe/ffprobe.exe import avdevice-if-61.dll directly; avdevice in turn pulls
# in SDL2.dll + libopenal-1.dll. The exes themselves must NOT import SDL2 directly.
REQUIRED_PE_IMPORTS = {"avcodec-if-61.dll", "avutil-if-59.dll", "avdevice-if-61.dll"}
FORBIDDEN_PE_IMPORTS = {"SDL2.dll"}
PE_CHECKED_FILES = {"ffmpeg.exe", "ffprobe.exe"}

Expand Down
Loading