This is an automated email from the ASF dual-hosted git repository.

tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/main by this push:
     new 144e85b026 refuse imageGraphicsEngineFactoryClass in per-request pdf 
config (#3313)
144e85b026 is described below

commit 144e85b0263ac1b71599fab973ad54660ff7f4ab
Author: Naveed <[email protected]>
AuthorDate: Fri Oct 9 21:17:33 2026 +0530

    refuse imageGraphicsEngineFactoryClass in per-request pdf config (#3313)
---
 .../java/org/apache/tika/parser/pdf/PDFParser.java | 10 +++
 .../apache/tika/parser/pdf/PDFParserConfig.java    | 34 +++++++++
 .../parser/pdf/PDFParserRuntimeConfigTest.java     | 84 ++++++++++++++++++++++
 3 files changed, 128 insertions(+)

diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
index 4e947b62ba..7738d085d6 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
@@ -272,6 +272,16 @@ public class PDFParser implements Parser, RenderingParser, 
EnrichingParser {
     }
 
     private PDFParserConfig getConfig(ParseContext parseContext) throws 
TikaException, IOException {
+        if (parseContext.hasJsonConfig("pdf-parser")
+                && !parseContext.getJsonConfig("pdf-parser").trusted()) {
+            // resolved for its guards only: per-request JSON may not name an 
image graphics
+            // engine factory, operator JSON (config file, presets) still may
+            ParseContextConfig.getConfig(
+                    parseContext,
+                    "pdf-parser",
+                    PDFParserConfig.RuntimeConfig.class,
+                    new PDFParserConfig.RuntimeConfig());
+        }
         PDFParserConfig config = ParseContextConfig.getConfig(
                 parseContext,
                 "pdf-parser",
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParserConfig.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParserConfig.java
index 49f3413ae0..efe0c740ec 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParserConfig.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParserConfig.java
@@ -22,6 +22,7 @@ import org.apache.pdfbox.text.PDFTextStripper;
 
 import org.apache.tika.parser.pages.PagesConfig;
 import org.apache.tika.parser.pdf.image.ImageGraphicsEngineFactory;
+import org.apache.tika.utils.StringUtils;
 
 /**
  * Config for PDFParser.
@@ -740,6 +741,39 @@ public class PDFParserConfig implements Serializable {
         return throwOnEncryptedPayload;
     }
 
+    /**
+     * Runtime-only PDFParserConfig that refuses the image graphics engine 
factory, which
+     * {@link PDFParserConfig#setImageGraphicsEngineFactoryClass(String)} 
loads and
+     * instantiates by name.
+     * <p>
+     * This class is deserialized by ConfigDeserializer (in 
tika-serialization), which populates
+     * fields via setters, so a per-request {@code pdf-parser} block naming a 
factory throws
+     * here. The factory is operator configuration.
+     */
+    public static class RuntimeConfig extends PDFParserConfig {
+
+        private static final long serialVersionUID = 6492570218190936987L;
+
+        @Override
+        public void setImageGraphicsEngineFactoryClass(String className) {
+            if (!StringUtils.isBlank(className)) {
+                throw new IllegalArgumentException("Cannot modify 
imageGraphicsEngineFactoryClass"
+                        + " at runtime. The image graphics engine factory must 
be configured at"
+                        + " parser initialization time.");
+            }
+        }
+
+        @Override
+        public void setImageGraphicsEngineFactory(
+                ImageGraphicsEngineFactory imageGraphicsEngineFactory) {
+            if (imageGraphicsEngineFactory != null) {
+                throw new IllegalArgumentException("Cannot modify 
imageGraphicsEngineFactory at"
+                        + " runtime. The image graphics engine factory must be 
configured at"
+                        + " parser initialization time.");
+            }
+        }
+    }
+
     /** @deprecated since 4.1.0; see {@link #setImageStrategy}. */
     @Deprecated
     public enum IMAGE_STRATEGY {
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserRuntimeConfigTest.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserRuntimeConfigTest.java
new file mode 100644
index 0000000000..227f20bcd9
--- /dev/null
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserRuntimeConfigTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.parser.pdf;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import org.apache.tika.TikaTest;
+import org.apache.tika.parser.ParseContext;
+
+/**
+ * {@code imageGraphicsEngineFactoryClass} instantiates the class it names, so 
it is operator
+ * configuration: a per-request {@code pdf-parser} block must not set it, an 
operator-authored
+ * one still may.
+ */
+public class PDFParserRuntimeConfigTest extends TikaTest {
+
+    private static final String PDF = "testPDF.pdf";
+
+    /** Stands in for any class on the parse classpath; records that its 
constructor ran. */
+    public static class ConstructorWitness {
+
+        static volatile boolean constructed;
+
+        public ConstructorWitness() {
+            constructed = true;
+        }
+    }
+
+    @Test
+    public void testPerRequestConfigCannotNameEngineFactory() {
+        ConstructorWitness.constructed = false;
+        ParseContext context = new ParseContext();
+        context.setJsonConfig("pdf-parser", 
"{\"imageGraphicsEngineFactoryClass\": \""
+                + ConstructorWitness.class.getName() + "\"}");
+        Exception e = assertThrows(Exception.class, () -> getXML(PDF, new 
PDFParser(), context));
+        assertFalse(ConstructorWitness.constructed,
+                "a class named by a per-request config was instantiated");
+        assertTrue(rootMessage(e).contains("imageGraphicsEngineFactory"), 
rootMessage(e));
+    }
+
+    @Test
+    public void testPerRequestConfigStillMerges() throws Exception {
+        ParseContext context = new ParseContext();
+        context.setJsonConfig("pdf-parser", "{\"sortByPosition\": true}");
+        getXML(PDF, new PDFParser(), context);
+        assertTrue(context.get(PDFParserConfig.class).isSortByPosition());
+    }
+
+    @Test
+    public void testOperatorConfigSetsEngineFactory() throws Exception {
+        ParseContext context = new ParseContext();
+        context.setJsonConfig("pdf-parser", 
"{\"imageGraphicsEngineFactoryClass\": \""
+                + MyCustomImageGraphicsEngineFactory.class.getName() + "\"}", 
true);
+        getXML(PDF, new PDFParser(), context);
+        assertEquals(MyCustomImageGraphicsEngineFactory.class,
+                
context.get(PDFParserConfig.class).getImageGraphicsEngineFactory().getClass());
+    }
+
+    private static String rootMessage(Throwable t) {
+        while (t.getCause() != null) {
+            t = t.getCause();
+        }
+        return String.valueOf(t.getMessage());
+    }
+}

Reply via email to