This is an automated email from the ASF dual-hosted git repository.

julianhyde pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 32ef284f88 [CALCITE-7496] OS-adapter usability
32ef284f88 is described below

commit 32ef284f88e5ca57d0ba8719751188b5fdfd596b
Author: Julian Hyde <[email protected]>
AuthorDate: Tue Apr 28 19:06:30 2026 -0700

    [CALCITE-7496] OS-adapter usability
---
 .../calcite/adapter/os/FilesTableFunction.java     | 38 ++++++++++++++--------
 .../apache/calcite/adapter/os/OsAdapterTest.java   | 16 +++++++++
 2 files changed, 41 insertions(+), 13 deletions(-)

diff --git 
a/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java 
b/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java
index 8c7b3cc815..3df9498c35 100644
--- a/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java
+++ b/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java
@@ -44,8 +44,7 @@
 public class FilesTableFunction {
 
   private static final BigDecimal THOUSAND = BigDecimal.valueOf(1000L);
-  private static final String SINGLE_QUOTE =
-      "Path with single quote characters are not supported";
+
   private FilesTableFunction() {
   }
 
@@ -87,9 +86,28 @@ public static ScannableTable eval(final String path) {
         // %p file name (including argument)
       }
 
+      /** Wraps {@code path} in single quotes for use in a shell command,
+       * throwing if it contains a single quote. */
+      private String quotePath() {
+        return "'" + validatePath(path) + "'";
+      }
+
+      /** Checks that {@code path} is valid and will not cause mischief. */
+      private String validatePath(String path) {
+        if (path.contains("'")) {
+          throw new IllegalArgumentException(
+              "Path with single quote characters is not supported");
+        }
+        if (path.startsWith("-")) {
+          throw new IllegalArgumentException(
+              "Path with leading dash character is not supported");
+        }
+        return path;
+      }
+
       private Enumerable<String> sourceLinux() {
         final String[] args = {
-            "find", path, "-printf", ""
+            "find", "--", validatePath(path), "-printf", ""
               + "%A@\\0" // access_time
               + "%b\\0" // block_count
               + "%C@\\0" // change_time
@@ -115,12 +133,9 @@ private Enumerable<String> sourceLinux() {
       }
 
       private Enumerable<String> sourceMacOs() {
-        if (path.contains("'")) {
-          throw new IllegalArgumentException(SINGLE_QUOTE);
-        }
         // BSD stat format specifiers: 
https://man.freebsd.org/cgi/man.cgi?query=stat
-        final String[] args = {"/bin/sh", "-c", "find '" + path
-              + "' | xargs stat -f "
+        final String[] args = {"/bin/sh", "-c", "find -- " + quotePath()
+              + " -print0 | xargs -0 stat -f "
               + "%a%n" // access_time
               + "%b%n" // block_count
               + "%c%n" // change_time
@@ -146,14 +161,11 @@ private Enumerable<String> sourceMacOs() {
       }
 
       private Enumerable<String> sourceGnuStat() {
-        if (path.contains("'")) {
-          throw new IllegalArgumentException(SINGLE_QUOTE);
-        }
         // GNU stat format specifiers:
         // 
https://www.gnu.org/software/coreutils/manual/html_node/stat-invocation.html
         // format string must have exactly 20 lines per file to match the 
schema
-        final String[] args = {"/bin/sh", "-c", "find '" + path
-              + "' | xargs stat -c '"
+        final String[] args = {"/bin/sh", "-c", "find -- " + quotePath()
+              + " -print0 | xargs -0 stat -c '"
               + "%X\n" // access_time
               + "%b\n" // block_count
               + "%Z\n" // change_time
diff --git 
a/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java 
b/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java
index e1158d5aa6..602c613038 100644
--- a/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java
+++ b/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java
@@ -149,6 +149,22 @@ private static boolean checkProcessExists(String command) {
             "type=f");
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-7496";>[CALCITE-7496]
+   * The 'files(path)' table function should not allow paths with a leading
+   * dash</a>.
+   *
+   * <p>GNU {@code find} treats an argument beginning with '{@code -}' as an
+   * expression primary rather than a filesystem path. This can cause mischief.
+   * This test verifies that leading-dash paths are rejected using the harmless
+   * {@code -name} expression.
+   */
+  @Test void testFilesLeadingDashPath() {
+    assumeFalse(Util.isWindows(), "Skip: the 'files' table does not work on 
Windows");
+    sql("select * from files('-name')")
+        .throws_("Path with leading dash character is not supported");
+  }
+
   @Test void testPs() {
     assumeFalse(Util.isWindows(), "Skip: the 'ps' table does not work on 
Windows");
     assumeToolExists("ps");

Reply via email to