removeffmpeg (#6053)

This commit is contained in:
Anthony Stirling
2026-04-02 17:40:02 +01:00
committed by GitHub
parent 0adcbeedf1
commit c9a70f3754
9 changed files with 17 additions and 190 deletions
@@ -129,7 +129,9 @@ public class FileMonitor {
// Skip expensive collection work when there is nothing to track
WatchKey firstKey = watchService.poll();
if (firstKey == null && newlyDiscoveredFiles.isEmpty() && readyForProcessingFiles.isEmpty()) {
if (firstKey == null
&& newlyDiscoveredFiles.isEmpty()
&& readyForProcessingFiles.isEmpty()) {
return;
}
@@ -73,7 +73,8 @@ public class ExternalAppDepConfig {
tmp.put("tesseract", List.of("tesseract"));
tmp.put("rar", List.of("rar")); // Required for real CBR output
tmp.put(calibrePath, List.of("Calibre"));
tmp.put("ffmpeg", List.of("FFmpeg"));
// ffmpeg disabled due to raised CVEs
// tmp.put("ffmpeg", List.of("FFmpeg"));
tmp.put("magick", List.of("ImageMagick"));
this.commandToGroupMapping = Collections.unmodifiableMap(tmp);
}
@@ -8,10 +8,7 @@ import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -23,31 +20,17 @@ import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import stirling.software.SPDF.model.api.converters.PdfToVideoRequest;
import stirling.software.common.annotations.AutoJobPostMapping;
import stirling.software.common.annotations.api.ConvertApi;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ApplicationContextProvider;
import stirling.software.common.util.CheckProgramInstall;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.TempDirectory;
import stirling.software.common.util.TempFile;
import stirling.software.common.util.TempFileManager;
import stirling.software.common.util.WebResponseUtils;
@ConvertApi
@RequiredArgsConstructor
@@ -64,6 +47,8 @@ public class ConvertPdfToVideoController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final TempFileManager tempFileManager;
// ffmpeg disabled due to raised CVEs
/*
@AutoJobPostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/pdf/video")
@Operation(
summary = "Convert PDF to Video Slideshow",
@@ -163,6 +148,7 @@ public class ConvertPdfToVideoController {
return WebResponseUtils.bytesToWebResponse(videoBytes, outputName, mediaType);
}
}
*/
private void generateFrames(
Path inputPdf,
@@ -1,164 +0,0 @@
package stirling.software.SPDF.controller.api.converters;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import stirling.software.SPDF.model.api.converters.PdfToVideoRequest;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.CheckProgramInstall;
import stirling.software.common.util.TempFileManager;
@ExtendWith(MockitoExtension.class)
class ConvertPdfToVideoControllerTest {
@Mock private CustomPDFDocumentFactory pdfDocumentFactory;
@Mock private TempFileManager tempFileManager;
@InjectMocks private ConvertPdfToVideoController controller;
@Test
void convertPdfToVideo_ffmpegNotAvailableThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile pdfFile =
new MockMultipartFile(
"fileInput", "doc.pdf", "application/pdf", "content".getBytes());
request.setFileInput(pdfFile);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(false);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void convertPdfToVideo_nullFileThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
request.setFileInput(null);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void convertPdfToVideo_emptyFileThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile emptyFile =
new MockMultipartFile("fileInput", "doc.pdf", "application/pdf", new byte[0]);
request.setFileInput(emptyFile);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void convertPdfToVideo_nonPdfContentTypeReturnsBadRequest() throws Exception {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile txtFile =
new MockMultipartFile("fileInput", "doc.txt", "text/plain", "content".getBytes());
request.setFileInput(txtFile);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
ResponseEntity<byte[]> response = controller.convertPdfToVideo(request);
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
}
}
@Test
void convertPdfToVideo_invalidOpacityThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile pdfFile =
new MockMultipartFile(
"fileInput", "doc.pdf", "application/pdf", "content".getBytes());
request.setFileInput(pdfFile);
request.setOpacity(1.5f);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void convertPdfToVideo_negativeOpacityThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile pdfFile =
new MockMultipartFile(
"fileInput", "doc.pdf", "application/pdf", "content".getBytes());
request.setFileInput(pdfFile);
request.setOpacity(-0.1f);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void convertPdfToVideo_negativeSecondsPerPageThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile pdfFile =
new MockMultipartFile(
"fileInput", "doc.pdf", "application/pdf", "content".getBytes());
request.setFileInput(pdfFile);
request.setSecondsPerPage(-1);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void convertPdfToVideo_zeroSecondsPerPageThrows() {
PdfToVideoRequest request = new PdfToVideoRequest();
MockMultipartFile pdfFile =
new MockMultipartFile(
"fileInput", "doc.pdf", "application/pdf", "content".getBytes());
request.setFileInput(pdfFile);
request.setSecondsPerPage(0);
try (MockedStatic<CheckProgramInstall> mock =
Mockito.mockStatic(CheckProgramInstall.class)) {
mock.when(CheckProgramInstall::isFfmpegAvailable).thenReturn(true);
assertThrows(Exception.class, () -> controller.convertPdfToVideo(request));
}
}
@Test
void controllerIsConstructed() {
assertNotNull(controller);
}
}
@@ -159,9 +159,8 @@ public class SecurityConfiguration {
firewall.setAllowedHeaderValues(
headerValue -> headerValue != null && allowedChars.matcher(headerValue).matches());
// Allow non-ASCII characters and newlines in parameter values.
Pattern allowedParamChars =
Pattern.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]\\r\\n]*");
// Allow non-ASCII characters and newlines in parameter values.
Pattern allowedParamChars = Pattern.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]\\r\\n]*");
firewall.setAllowedParameterValues(
parameterValue ->
parameterValue != null
+3 -1
View File
@@ -385,7 +385,9 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
apt-get install -y --no-install-recommends \
# Core tools
ca-certificates tzdata tini bash fontconfig curl \
ffmpeg poppler-utils fontforge \
# ffmpeg disabled due to raised CVEs
# ffmpeg \
poppler-utils fontforge \
unpaper pngquant \
# Fonts: full coverage for standard + fat variants
fonts-dejavu \
+1 -1
View File
@@ -1,7 +1,7 @@
# Stirling-PDF - Full version (embedded frontend)
# Uses pre-built base image for fast builds
ARG BASE_VERSION=1.0.1
ARG BASE_VERSION=1.0.2
ARG BASE_IMAGE=stirlingtools/stirling-pdf-base:${BASE_VERSION}
# Stage 1: Build the Java application and frontend
+1 -1
View File
@@ -2,7 +2,7 @@
# Extra fonts for air-gapped environments
# Uses pre-built base image for fast builds
ARG BASE_VERSION=1.0.1
ARG BASE_VERSION=1.0.2
ARG BASE_IMAGE=stirlingtools/stirling-pdf-base:${BASE_VERSION}
# Stage 1: Build the Java application and frontend
+2 -1
View File
@@ -41,7 +41,8 @@ print_versions() {
command_exists unoserver && unoserver --version 2>&1 | head -n 1 | log
command_exists tesseract && tesseract --version | head -n 1 | log
command_exists gs && gs --version | printf "Ghostscript %s\n" "$(cat)" | log
command_exists ffmpeg && ffmpeg -version | head -n 1 | log
# ffmpeg disabled due to raised CVEs
# command_exists ffmpeg && ffmpeg -version | head -n 1 | log
command_exists pdfinfo && pdfinfo -v 2>&1 | head -n 1 | log
command_exists fontforge && fontforge --version 2>&1 | head -n 1 | log
command_exists unpaper && unpaper --version 2>&1 | head -n 1 | log