From 422af007dc18b23512782f85c6615ddc4736aca5 Mon Sep 17 00:00:00 2001 From: Ludy Date: Fri, 1 Aug 2025 00:58:56 +0200 Subject: [PATCH] fix(pipeline): allow slashes in pipeline operation values (#4066) # Description of Changes - Extended the validation regex for `operation` in the pipeline processor to allow slashes (`/`), in addition to alphanumeric characters, underscores, and hyphens. - This resolves the issue where valid operation strings (e.g., with subpaths like `/api/v1/general/remove-pages`) were incorrectly rejected. - Added an explicit log message for better debugging in case of invalid `operation` values. --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --- .../api/pipeline/PipelineProcessor.java | 10 ++++++--- .../api/pipeline/PipelineProcessorTest.java | 21 +++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java index 44f2b892a..070d681e4 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java @@ -108,9 +108,13 @@ public class PipelineProcessor { if (inputFileTypes == null) { inputFileTypes = new ArrayList(Arrays.asList("ALL")); } - if (!operation.matches("^[a-zA-Z0-9_-]+$")) { - throw new IllegalArgumentException("Invalid operation value received."); + + if (!apiDocService.isValidOperation(operation, parameters)) { + log.error("Invalid operation or parameters: o:{} p:{}", operation, parameters); + throw new IllegalArgumentException( + "Invalid operation: " + operation + " with parameters: " + parameters); } + String url = getBaseUrl() + operation; List newOutputFiles = new ArrayList<>(); if (!isMultiInputOperation) { @@ -136,7 +140,7 @@ public class PipelineProcessor { // skip // this // file - if (operation.startsWith("filter-") + if (operation.startsWith("/api/v1/filter/filter-") && (response.getBody() == null || response.getBody().length == 0)) { filtersApplied = true; diff --git a/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java b/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java index 60e3f975d..0a40fcd5b 100644 --- a/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java +++ b/app/core/src/test/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessorTest.java @@ -45,23 +45,26 @@ class PipelineProcessorTest { @Test void runPipelineWithFilterSetsFlag() throws Exception { PipelineOperation op = new PipelineOperation(); - op.setOperation("filter-page-count"); + op.setOperation("/api/v1/filter/filter-page-count"); op.setParameters(Map.of()); PipelineConfig config = new PipelineConfig(); config.setOperations(List.of(op)); - Resource file = new ByteArrayResource("data".getBytes()) { - @Override - public String getFilename() { - return "test.pdf"; - } - }; + Resource file = + new ByteArrayResource("data".getBytes()) { + @Override + public String getFilename() { + return "test.pdf"; + } + }; List files = List.of(file); - when(apiDocService.isMultiInput("filter-page-count")).thenReturn(false); - when(apiDocService.getExtensionTypes(false, "filter-page-count")) + when(apiDocService.isMultiInput("/api/v1/filter/filter-page-count")).thenReturn(false); + when(apiDocService.getExtensionTypes(false, "/api/v1/filter/filter-page-count")) .thenReturn(List.of("pdf")); + when(apiDocService.isValidOperation(eq("/api/v1/filter/filter-page-count"), anyMap())) + .thenReturn(true); doReturn(new ResponseEntity<>(new byte[0], HttpStatus.OK)) .when(pipelineProcessor)