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 335525301f quote table names in the JDBCTableReader SELECT (#3447)
335525301f is described below

commit 335525301fa382f23c8ff880762326d7423c6d6b
Author: Naveed <[email protected]>
AuthorDate: Fri Oct 30 21:09:38 2026 +0530

    quote table names in the JDBCTableReader SELECT (#3447)
    
    JDBCTableReader.reset appended the table name to "SELECT * from "
    unquoted, and the SQLite and GeoPackage parsers read that name from the
    file's sqlite_master. A name that needs quoting made the parse fail,
    and a crafted name was run as SQL. Quote it as an SQL identifier.
    
    Generated-by: Claude Code (claude-opus-5-5)
---
 .../tika/parser/sqlite3/SQLite3ParserTest.java     | 45 ++++++++++++++++++++++
 .../apache/tika/parser/jdbc/JDBCTableReader.java   |  7 +++-
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git 
a/tika-parsers/tika-parsers-extended/tika-parser-sqlite3-module/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
 
b/tika-parsers/tika-parsers-extended/tika-parser-sqlite3-module/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
index 9961b1aaa9..ebd69e264b 100644
--- 
a/tika-parsers/tika-parsers-extended/tika-parser-sqlite3-module/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
+++ 
b/tika-parsers/tika-parsers-extended/tika-parser-sqlite3-module/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
@@ -19,7 +19,13 @@ package org.apache.tika.parser.sqlite3;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+import java.nio.file.Path;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.Statement;
+
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
 import org.xml.sax.ContentHandler;
 
 import org.apache.tika.TikaTest;
@@ -59,6 +65,45 @@ public class SQLite3ParserTest extends TikaTest {
                 xml);
     }
 
+    @Test
+    public void testTableNamesThatNeedQuoting(@TempDir Path tmp) throws 
Exception {
+        Path db = tmp.resolve("names.db");
+        try (Connection c = DriverManager.getConnection("jdbc:sqlite:" + 
db.toAbsolutePath());
+                Statement st = c.createStatement()) {
+            st.execute("CREATE TABLE \"my table\" (v VARCHAR(30))");
+            st.execute("INSERT INTO \"my table\" VALUES ('in my table')");
+            st.execute("CREATE TABLE \"order\" (v VARCHAR(30))");
+            st.execute("INSERT INTO \"order\" VALUES ('in order')");
+            st.execute("CREATE TABLE \"say \"\"hi\"\"\" (v VARCHAR(30))");
+            st.execute("INSERT INTO \"say \"\"hi\"\"\" VALUES ('in say hi')");
+        }
+        String xml;
+        try (TikaInputStream tis = TikaInputStream.get(db)) {
+            xml = getXML(tis, TikaTest.AUTO_DETECT_PARSER, new Metadata()).xml;
+        }
+        TikaTest.assertContains("in my table", xml);
+        TikaTest.assertContains("in order", xml);
+        TikaTest.assertContains("in say hi", xml);
+    }
+
+    @Test
+    public void testTableNameIsNotRunAsSql(@TempDir Path tmp) throws Exception 
{
+        Path db = tmp.resolve("injection.db");
+        try (Connection c = DriverManager.getConnection("jdbc:sqlite:" + 
db.toAbsolutePath());
+                Statement st = c.createStatement()) {
+            st.execute("CREATE TABLE a (v VARCHAR(30))");
+            st.execute("INSERT INTO a VALUES ('alpha')");
+            st.execute("CREATE TABLE \"a UNION SELECT upper(v) FROM a\" (v 
VARCHAR(30))");
+            st.execute("INSERT INTO \"a UNION SELECT upper(v) FROM a\" VALUES 
('beta')");
+        }
+        String xml;
+        try (TikaInputStream tis = TikaInputStream.get(db)) {
+            xml = getXML(tis, TikaTest.AUTO_DETECT_PARSER, new Metadata()).xml;
+        }
+        TikaTest.assertContains("beta", xml);
+        TikaTest.assertNotContained("ALPHA", xml);
+    }
+
     //code used for creating the test file
 /*
     private Connection getConnection(String dbFileName) throws Exception {
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-jdbc-commons/src/main/java/org/apache/tika/parser/jdbc/JDBCTableReader.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-jdbc-commons/src/main/java/org/apache/tika/parser/jdbc/JDBCTableReader.java
index 309a1d3eeb..83e1d0a26b 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-jdbc-commons/src/main/java/org/apache/tika/parser/jdbc/JDBCTableReader.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-jdbc-commons/src/main/java/org/apache/tika/parser/jdbc/JDBCTableReader.java
@@ -297,7 +297,7 @@ public class JDBCTableReader {
             }
         }
 
-        String sql = "SELECT * from " + tableName;
+        String sql = "SELECT * from " + quoteIdentifier(tableName);
         try {
             Statement st = connection.createStatement();
             results = st.executeQuery(sql);
@@ -310,4 +310,9 @@ public class JDBCTableReader {
     public String getTableName() {
         return tableName;
     }
+
+    //table names come from the file being parsed
+    private static String quoteIdentifier(String name) {
+        return "\"" + name.replace("\"", "\"\"") + "\"";
+    }
 }

Reply via email to