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 = """