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 90f31b113c TIKA-4904: refuse otherTesseractConfig in per-request 
tesseract config (#3193)
90f31b113c is described below

commit 90f31b113c010ef4bede8bf47dbe4e399243ceb8
Author: Tim Allison <[email protected]>
AuthorDate: Fri Sep 18 13:05:06 2026 -0400

    TIKA-4904: refuse otherTesseractConfig in per-request tesseract config 
(#3193)
---
 CHANGES.txt                                        |  5 ++++
 .../parsers/tesseract-ocr-parser.adoc              |  4 +++-
 docs/modules/ROOT/pages/security.adoc              |  4 +++-
 .../apache/tika/parser/ocr/TesseractOCRConfig.java | 15 +++++++++---
 .../tika/parser/ocr/TesseractOCRConfigTest.java    | 16 +++++++++++++
 .../tika/server/standard/TikaResourceTest.java     | 27 ++++++++++++++++++++++
 6 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 82516f4584..dd69d9883c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,10 @@
 Release 4.1.0 - unreleased
 
+   * Per-request tesseract-ocr-parser config no longer accepts
+     otherTesseractConfig; tesseract variables such as debug_file name
+     files the binary opens, so the -c pass-through is server-side
+     configuration only (TIKA-4904).
+
    * ICC tone-curve and lookup-table tags (rTRC and friends) are no longer
      written to icc:* by default; "jpeg-parser": {"includeIccCurvesAndLuts":
      true} (likewise tiff-, heif-, bpg-, web-p- and raw-tiff-parser) restores
diff --git 
a/docs/modules/ROOT/pages/configuration/parsers/tesseract-ocr-parser.adoc 
b/docs/modules/ROOT/pages/configuration/parsers/tesseract-ocr-parser.adoc
index d5db51f8e8..7900f419e3 100644
--- a/docs/modules/ROOT/pages/configuration/parsers/tesseract-ocr-parser.adoc
+++ b/docs/modules/ROOT/pages/configuration/parsers/tesseract-ocr-parser.adoc
@@ -65,6 +65,8 @@ include::example$tesseract-full.json[]
 icon:github[] 
https://github.com/apache/tika/blob/main/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/resources/config-examples/tesseract-full.json[View
 source on GitHub]
 
 Arbitrary Tesseract variables go in `otherTesseractConfig` as a name-to-value 
map, as in the
-example above. Converting a 3.x config? See
+example above. The map is server-side configuration only: a per-request 
`tesseract-ocr-parser`
+block that carries it is rejected, because variables such as `debug_file` name 
files the
+tesseract binary opens. Converting a 3.x config? See
 xref:migration-to-4x/migrating-to-4x.adoc[Migrating to 4.x] — the automatic 
converter rewrites the
 old `otherTesseractSettings` list for you.
diff --git a/docs/modules/ROOT/pages/security.adoc 
b/docs/modules/ROOT/pages/security.adoc
index b7f7f936d7..10c6b8bce3 100644
--- a/docs/modules/ROOT/pages/security.adoc
+++ b/docs/modules/ROOT/pages/security.adoc
@@ -75,7 +75,9 @@ callers — that requirement stands regardless of how the flags 
are set. All def
 * `allowPipes` gates the `/pipes` and `/async` endpoints (process-isolated 
fetching and parsing
   through your fetchers/emitters). Selecting either without it causes the 
server to refuse to start.
 * `allowPerRequestConfig` gates per-request parser configuration — the 
`/config` endpoints and the
-  multipart `config` part; when off, such requests are rejected with HTTP 403.
+  multipart `config` part; when off, such requests are rejected with HTTP 403. 
A caller who
+  reaches it can choose how documents parse, including options that spawn 
external processes
+  such as OCR, and can defeat memory and timeout limits.
 
 *tika-grpc* is *more exposed by default* than tika-server: it ships with no 
transport security and
 no per-caller authorization, and its `FetchAndParse` surface is always on. 
`allowPerRequestConfig`
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
index 62b209cfe1..fc99f51ca9 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
@@ -571,12 +571,15 @@ public class TesseractOCRConfig implements Serializable {
     }
 
     /**
-     * Runtime-only TesseractOCRConfig that prevents modification of paths.
-     * Used to enforce immutability of parser-level paths during parse-time 
configuration.
+     * Runtime-only TesseractOCRConfig that prevents modification of paths and 
of the
+     * {@code -c} pass-through map. Used to enforce immutability of 
parser-level paths
+     * during parse-time configuration.
      * <p>
      * This class is deserialized by ConfigDeserializer (in 
tika-serialization) which uses
      * Jackson to populate fields via setters. If the JSON contains any path 
fields, the
-     * overridden setters will throw TikaConfigException.
+     * overridden setters will throw TikaConfigException. {@code 
otherTesseractConfig} is
+     * refused as well: tesseract variables such as {@code debug_file} name 
files the
+     * binary opens, so the map is operator configuration only.
      */
     public static class RuntimeConfig extends TesseractOCRConfig {
 
@@ -609,6 +612,12 @@ public class TesseractOCRConfig implements Serializable {
         public void setTrustedPageSeparator(String pageSeparator) {
             throw new IllegalArgumentException("Cannot use 
setTrustedPageSeparator at runtime. " + "Use setPageSeparator instead.");
         }
+
+        @Override
+        public void addOtherTesseractConfig(String key, String value) {
+            throw new IllegalArgumentException("Cannot set 
otherTesseractConfig at runtime. " +
+                    "Tesseract variables must be configured at parser 
initialization time.");
+        }
     }
 
     public enum OUTPUT_TYPE {
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/test/java/org/apache/tika/parser/ocr/TesseractOCRConfigTest.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/test/java/org/apache/tika/parser/ocr/TesseractOCRConfigTest.java
index b41eaeb821..1f75741893 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/test/java/org/apache/tika/parser/ocr/TesseractOCRConfigTest.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/test/java/org/apache/tika/parser/ocr/TesseractOCRConfigTest.java
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.fail;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 import org.junit.jupiter.api.Test;
 
@@ -231,6 +232,21 @@ public class TesseractOCRConfigTest extends TikaTest {
         config.addOtherTesseractConfig("good", "good");
     }
 
+    @Test
+    public void testRuntimeConfigRefusesOtherParameters() {
+        TesseractOCRConfig.RuntimeConfig config = new 
TesseractOCRConfig.RuntimeConfig();
+        assertThrows(IllegalArgumentException.class, () -> {
+            config.addOtherTesseractConfig("debug_file", "/tmp/anywhere");
+        });
+        assertThrows(IllegalArgumentException.class, () -> {
+            config.setOtherTesseractConfig(Map.of("tessedit_char_whitelist", 
"0123456789"));
+        });
+        // nothing to refuse
+        config.setOtherTesseractConfig(Map.of());
+        config.setOtherTesseractConfig(null);
+        assertTrue(config.getOtherTesseractConfig().isEmpty());
+    }
+
     @Test
     public void testBadLanguageCode() throws Exception {
         TesseractOCRConfig tesseractOCRConfig = new TesseractOCRConfig();
diff --git 
a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaResourceTest.java
 
b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaResourceTest.java
index 3ad98d20e2..8820c6bccd 100644
--- 
a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaResourceTest.java
+++ 
b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaResourceTest.java
@@ -561,6 +561,33 @@ public class TikaResourceTest extends CXFTestBase {
         assertEquals(422, response.getStatus());
     }
 
+    @Test
+    public void testOtherTesseractConfigNotSettableAtRuntime() throws 
Exception {
+        assumeTrue(new TesseractOCRParser().hasTesseract(), "Tesseract not 
installed, skipping test");
+
+        // -c pass-through names files tesseract opens (debug_file); 
server-side only
+        String configJson = """
+                {
+                  "tesseract-ocr-parser": {
+                    "otherTesseractConfig": {
+                      "debug_file": "/tmp/tika-should-never-write-this"
+                    }
+                  }
+                }
+                """;
+        ContentDisposition fileCd = new ContentDisposition("form-data; 
name=\"file\"; filename=\"testOCR.pdf\"");
+        Attachment fileAtt = new Attachment("file",
+                
ClassLoader.getSystemResourceAsStream("test-documents/testOCR.pdf"), fileCd);
+        Attachment configAtt = new Attachment("config", "application/json",
+                new 
java.io.ByteArrayInputStream(configJson.getBytes(StandardCharsets.UTF_8)));
+
+        Response response = WebClient
+                .create(endPoint + TIKA_PATH + "/config")
+                .type("multipart/form-data")
+                .post(new MultipartBody(Arrays.asList(fileAtt, configAtt)));
+        assertEquals(422, response.getStatus());
+    }
+
     @Test
     public void testFloatInConfig() throws Exception {
         String configJson = """

Reply via email to