diff --git a/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java b/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java index 0d1e32609..bb2adca4b 100644 --- a/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java +++ b/app/common/src/main/java/stirling/software/common/util/GeneralUtils.java @@ -651,6 +651,7 @@ public class GeneralUtils { public List parsePageList(String[] pages, int totalPages, boolean oneBased) { List result = new ArrayList<>(); int offset = oneBased ? 1 : 0; + int maxSize = Math.max(1000, totalPages * 3); for (String page : pages) { if ("all".equalsIgnoreCase(page)) { @@ -666,6 +667,10 @@ public class GeneralUtils { } else { result.addAll(handlePart(page, totalPages, offset)); } + if (result.size() > maxSize) { + throw new IllegalArgumentException( + "Page list exceeds maximum allowed size of " + maxSize); + } } return result; } diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java index d0b7e6c3e..df146ea9a 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java @@ -194,7 +194,7 @@ public class PdfOverlayController { // Load the overlay document to check its page count try (PDDocument overlayPdf = Loader.loadPDF(overlayFile)) { int overlayPageCount = overlayPdf.getNumberOfPages(); - for (int j = 0; j < repeatCount; j++) { + for (int j = 0; j < repeatCount && currentPage <= basePageCount; j++) { for (int page = 0; page < overlayPageCount; page++) { if (currentPage > basePageCount) break; overlayGuide.put(currentPage++, overlayFile.getAbsolutePath()); diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java index 3507da95f..dbf64e51c 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java @@ -191,6 +191,14 @@ public class RearrangePagesPDFController { if (duplicateCount < 1) { duplicateCount = 2; // Default to 2 if invalid input } + int maxDuplicateCount = Math.max(100, totalPages * 3); + if (duplicateCount > maxDuplicateCount) { + throw ExceptionUtils.createIllegalArgumentException( + "error.invalidFormat", + "Invalid {0} format: {1}", + "duplicateCount", + "must not exceed " + maxDuplicateCount); + } // For each page in the document for (int pageNum = 0; pageNum < totalPages; pageNum++) { diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java index 2ed917b6c..216c618c4 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java @@ -23,6 +23,8 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.Valid; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -57,7 +59,7 @@ public class SplitPdfBySectionsController { + " which page to split, and how to split" + " ( halves, thirds, quarters, etc.), both vertically and horizontally." + " Input:PDF Output:ZIP-PDF Type:SISO") - public ResponseEntity splitPdf(@ModelAttribute SplitPdfBySectionsRequest request) + public ResponseEntity splitPdf(@Valid @ModelAttribute SplitPdfBySectionsRequest request) throws Exception { MultipartFile file = request.getFileInput(); String pageNumbers = request.getPageNumbers(); diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java index 2e272eeaa..6c71ac4b7 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java @@ -33,6 +33,8 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.Valid; + import lombok.RequiredArgsConstructor; import stirling.software.SPDF.config.swagger.StandardPdfResponse; @@ -71,7 +73,7 @@ public class WatermarkController { "This endpoint adds a watermark to a given PDF file. Users can specify the" + " watermark type (text or image), rotation, opacity, width spacer, and" + " height spacer. Input:PDF Output:PDF Type:SISO") - public ResponseEntity addWatermark(@ModelAttribute AddWatermarkRequest request) + public ResponseEntity addWatermark(@Valid @ModelAttribute AddWatermarkRequest request) throws IOException, Exception { MultipartFile pdfFile = request.getFileInput(); String pdfFileName = pdfFile.getOriginalFilename(); @@ -237,8 +239,8 @@ public class WatermarkController { // Calculating the number of rows and columns. - int watermarkRows = (int) (pageHeight / newWatermarkHeight + 1); - int watermarkCols = (int) (pageWidth / newWatermarkWidth + 1); + int watermarkRows = Math.min((int) (pageHeight / newWatermarkHeight + 1), 10_000); + int watermarkCols = Math.min((int) (pageWidth / newWatermarkWidth + 1), 10_000); // Add the text watermark for (int i = 0; i <= watermarkRows; i++) { @@ -290,9 +292,13 @@ public class WatermarkController { float pageWidth = page.getMediaBox().getWidth(); float pageHeight = page.getMediaBox().getHeight(); int watermarkRows = - (int) ((pageHeight + heightSpacer) / (desiredPhysicalHeight + heightSpacer)); + Math.min( + (int) ((pageHeight + heightSpacer) / (desiredPhysicalHeight + heightSpacer)), + 10_000); int watermarkCols = - (int) ((pageWidth + widthSpacer) / (desiredPhysicalWidth + widthSpacer)); + Math.min( + (int) ((pageWidth + widthSpacer) / (desiredPhysicalWidth + widthSpacer)), + 10_000); for (int i = 0; i < watermarkRows; i++) { for (int j = 0; j < watermarkCols; j++) { diff --git a/app/core/src/main/java/stirling/software/SPDF/model/api/SplitPdfBySectionsRequest.java b/app/core/src/main/java/stirling/software/SPDF/model/api/SplitPdfBySectionsRequest.java index 2f9370261..d1b988491 100644 --- a/app/core/src/main/java/stirling/software/SPDF/model/api/SplitPdfBySectionsRequest.java +++ b/app/core/src/main/java/stirling/software/SPDF/model/api/SplitPdfBySectionsRequest.java @@ -2,6 +2,9 @@ package stirling.software.SPDF.model.api; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; + import lombok.Data; import lombok.EqualsAndHashCode; @@ -33,6 +36,8 @@ public class SplitPdfBySectionsRequest extends PDFFile { defaultValue = "0", minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED) + @Min(value = 0, message = "Horizontal divisions must be non-negative") + @Max(value = 50, message = "Horizontal divisions must not exceed 50") private int horizontalDivisions; @Schema( @@ -40,6 +45,8 @@ public class SplitPdfBySectionsRequest extends PDFFile { defaultValue = "1", minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED) + @Min(value = 0, message = "Vertical divisions must be non-negative") + @Max(value = 50, message = "Vertical divisions must not exceed 50") private int verticalDivisions; @Schema( diff --git a/app/core/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java b/app/core/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java index 88d3ba45b..b03d1b48f 100644 --- a/app/core/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java +++ b/app/core/src/main/java/stirling/software/SPDF/model/api/security/AddWatermarkRequest.java @@ -4,6 +4,9 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Min; + import lombok.Data; import lombok.EqualsAndHashCode; @@ -32,6 +35,7 @@ public class AddWatermarkRequest extends PDFFile { private String alphabet; @Schema(description = "The font size of the watermark text", defaultValue = "30") + @DecimalMin(value = "1.0", message = "Font size must be at least 1.0") private float fontSize; @Schema(description = "The rotation of the watermark in degrees", defaultValue = "0") @@ -41,9 +45,11 @@ public class AddWatermarkRequest extends PDFFile { private float opacity; @Schema(description = "The width spacer between watermark elements", defaultValue = "50") + @Min(value = 0, message = "Width spacer must be non-negative") private int widthSpacer; @Schema(description = "The height spacer between watermark elements", defaultValue = "50") + @Min(value = 0, message = "Height spacer must be non-negative") private int heightSpacer; @Schema(description = "The color for watermark", defaultValue = "#d3d3d3")