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 56bf55f7f9 keep gdalinfo from opening files and URLs named in the 
document (#3516)
56bf55f7f9 is described below

commit 56bf55f7f997ce344a06666529aa8a1bed63f2b1
Author: Naveed <[email protected]>
AuthorDate: Sat Nov 7 04:03:49 2026 +0530

    keep gdalinfo from opening files and URLs named in the document (#3516)
    
    GDAL picks its driver from the file's content, and the VRT and GTI
    drivers take any file whose first kilobyte contains <VRTDataset or
    <GDALTileIndexDataset. A FITS header followed by a VRT is detected as
    application/fits and handed to GDALParser, and gdalinfo then fetches
    whatever URL the VRT names. Run gdalinfo with those two drivers skipped
    and with no /vsicurl/ name allowed to open.
    
    Generated-by: Claude Code (claude-opus-5-5)
---
 .../org/apache/tika/parser/gdal/GDALParser.java    | 12 ++++-
 .../apache/tika/parser/gdal/TestGDALParser.java    | 58 ++++++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git 
a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/gdal/GDALParser.java
 
b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/gdal/GDALParser.java
index fb81e7328d..662e0bdfa5 100644
--- 
a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/gdal/GDALParser.java
+++ 
b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/gdal/GDALParser.java
@@ -201,6 +201,14 @@ public class GDALParser implements Parser {
         return args;
     }
 
+    // VRT and GTI open any file whose header merely contains their XML, so a 
document of a
+    // type routed here can name other files or URLs for gdalinfo to open.
+    static void restrictEnvironment(Map<String, String> env) {
+        env.merge("GDAL_SKIP", "VRT GTI", (operatorSkip, skip) -> operatorSkip 
+ " " + skip);
+        // the input is always a local file, so no /vsicurl/ name needs to open
+        env.put("CPL_VSIL_CURL_ALLOWED_FILENAME", "");
+    }
+
     @Override
     public Set<MediaType> getSupportedTypes(ParseContext context) {
         return SUPPORTED_TYPES;
@@ -220,7 +228,9 @@ public class GDALParser implements Parser {
 
         String[] runCommand = buildCommandLine(this.command, 
tis.getFile().getPath());
 
-        FileProcessResult result = ProcessUtils.execute(new 
ProcessBuilder(runCommand), context,
+        ProcessBuilder pb = new ProcessBuilder(runCommand);
+        restrictEnvironment(pb.environment());
+        FileProcessResult result = ProcessUtils.execute(pb, context,
                 timeoutMillis, maxStdOut, maxStdErr);
 
         metadata.set(ExternalProcess.IS_TIMEOUT, result.isTimeout());
diff --git 
a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/gdal/TestGDALParser.java
 
b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/gdal/TestGDALParser.java
index d6e87ac387..ce060f9b3f 100644
--- 
a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/gdal/TestGDALParser.java
+++ 
b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/gdal/TestGDALParser.java
@@ -23,6 +23,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.junit.jupiter.api.Test;
 
 import org.apache.tika.TikaTest;
@@ -162,4 +172,52 @@ public class TestGDALParser extends TikaTest {
         assertArrayEquals(new String[]{"gdalinfo", path},
                 GDALParser.buildCommandLine(new GDALParser().getCommand(), 
path));
     }
+
+    @Test
+    public void testDocumentCannotPointGdalinfoAtAUrl() throws Exception {
+        assumeTrue(canRun());
+        try (ServerSocket listener = new ServerSocket(0, 50, 
InetAddress.getLoopbackAddress())) {
+            AtomicInteger connections = new AtomicInteger();
+            Thread acceptor = new Thread(() -> {
+                while (true) {
+                    try (Socket s = listener.accept()) {
+                        connections.incrementAndGet();
+                    } catch (IOException e) {
+                        return;
+                    }
+                }
+            });
+            acceptor.setDaemon(true);
+            acceptor.start();
+
+            String url = "/vsicurl/http://127.0.0.1:"; + 
listener.getLocalPort() + "/from-document";
+            // a FITS header is what routes the file to GDALParser
+            String fitsHeader = String.format(Locale.ROOT, "%-80s%-80s%n",
+                    "SIMPLE  =                    T", "END");
+            String[] documents = {
+                    fitsHeader + "<VRTDataset rasterXSize=\"1\" 
rasterYSize=\"1\">"
+                            + "<VRTRasterBand dataType=\"Byte\" 
band=\"1\"><SimpleSource>"
+                            + "<SourceFilename relativeToVRT=\"0\">" + url + 
"</SourceFilename>"
+                            + 
"<SourceBand>1</SourceBand></SimpleSource></VRTRasterBand>"
+                            + "</VRTDataset>\n",
+                    fitsHeader + "<GDALTileIndexDataset><IndexDataset>" + url
+                            + "</IndexDataset></GDALTileIndexDataset>\n"};
+            for (String document : documents) {
+                try (TikaInputStream tis = TikaInputStream.get(
+                        document.getBytes(StandardCharsets.US_ASCII))) {
+                    new GDALParser().parse(tis, new BodyContentHandler(), new 
Metadata(),
+                            new ParseContext());
+                }
+            }
+            assertEquals(0, connections.get());
+        }
+    }
+
+    @Test
+    public void testOperatorGdalSkipIsKept() {
+        Map<String, String> env = new HashMap<>(Map.of("GDAL_SKIP", "JPEG"));
+        GDALParser.restrictEnvironment(env);
+        assertEquals("JPEG VRT GTI", env.get("GDAL_SKIP"));
+        assertEquals("", env.get("CPL_VSIL_CURL_ALLOWED_FILENAME"));
+    }
 }

Reply via email to