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());
+ }
+}