You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/07/22 02:14:29 UTC
(texera) branch gh-readonly-queue/main/pr-6701-5da2a719104856b988b8d0eb45fd71606ff111c4 created (now 08126417c1)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-6701-5da2a719104856b988b8d0eb45fd71606ff111c4
in repository https://gitbox.apache.org/repos/asf/texera.git
at 08126417c1 test(file-service): cover DatasetResource path validation (#6701)
This branch includes the following new commits:
new 08126417c1 test(file-service): cover DatasetResource path validation (#6701)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(texera) 01/01: test(file-service): cover DatasetResource path validation (#6701)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-6701-5da2a719104856b988b8d0eb45fd71606ff111c4
in repository https://gitbox.apache.org/repos/asf/texera.git
commit 08126417c16e2def054813a1fc1df50ebe16b75c
Author: Matthew B. <mg...@uci.edu>
AuthorDate: Tue Jul 21 18:57:47 2026 -0700
test(file-service): cover DatasetResource path validation (#6701)
### What changes were proposed in this PR?
- Add DatasetResourcePathSpec, a lightweight unit spec calling the
companion validateAndNormalizeFilePathOrThrow directly.
- Cover the empty-path, normalize-to-null, absolute-path, and
normalized-relative-path branches.
### Any related issues, documentation, discussions?
Closes: #6700
### How was this PR tested?
- Run: `sbt "FileService/testOnly *DatasetResourcePathSpec"`, expect all
7 tests passing.
- Test-only change; no production code is modified.
### Was this PR authored or co-authored using generative AI tooling?
Co-authored with Claude Opus 4.8 in compliance with ASF
---
.../service/resource/DatasetResourcePathSpec.scala | 80 ++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/file-service/src/test/scala/org/apache/texera/service/resource/DatasetResourcePathSpec.scala b/file-service/src/test/scala/org/apache/texera/service/resource/DatasetResourcePathSpec.scala
new file mode 100644
index 0000000000..63bea046f3
--- /dev/null
+++ b/file-service/src/test/scala/org/apache/texera/service/resource/DatasetResourcePathSpec.scala
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.texera.service.resource
+
+import jakarta.ws.rs.BadRequestException
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+// Focused unit tests for the DatasetResource companion helper
+// validateAndNormalizeFilePathOrThrow, which guards every upload/lookup path.
+// These call the pure companion method directly and avoid the heavy
+// DatasetResourceSpec integration harness (DB + LakeFS).
+class DatasetResourcePathSpec extends AnyFlatSpec with Matchers {
+
+ "validateAndNormalizeFilePathOrThrow" should "reject a null path" in {
+ val ex = intercept[BadRequestException] {
+ DatasetResource.validateAndNormalizeFilePathOrThrow(null)
+ }
+ ex.getMessage shouldBe "Path cannot be empty"
+ }
+
+ it should "reject an empty path" in {
+ val ex = intercept[BadRequestException] {
+ DatasetResource.validateAndNormalizeFilePathOrThrow("")
+ }
+ ex.getMessage shouldBe "Path cannot be empty"
+ }
+
+ it should "reject a whitespace-only path" in {
+ val ex = intercept[BadRequestException] {
+ DatasetResource.validateAndNormalizeFilePathOrThrow(" ")
+ }
+ ex.getMessage shouldBe "Path cannot be empty"
+ }
+
+ it should "reject a path that normalizes to null (escapes above root)" in {
+ // FilenameUtils.normalize returns null when the path traverses above the
+ // root, e.g. a leading "../".
+ val ex = intercept[BadRequestException] {
+ DatasetResource.validateAndNormalizeFilePathOrThrow("../secret.txt")
+ }
+ ex.getMessage shouldBe "Invalid path"
+ }
+
+ it should "reject an absolute path" in {
+ val ex = intercept[BadRequestException] {
+ DatasetResource.validateAndNormalizeFilePathOrThrow("/etc/passwd")
+ }
+ ex.getMessage shouldBe "Absolute paths not allowed"
+ }
+
+ it should "return a normalized relative path unchanged when already clean" in {
+ DatasetResource.validateAndNormalizeFilePathOrThrow(
+ "california/irvine/tw1.csv"
+ ) shouldBe "california/irvine/tw1.csv"
+ }
+
+ it should "collapse interior '.' and '..' segments in a relative path" in {
+ DatasetResource.validateAndNormalizeFilePathOrThrow(
+ "a/./b/../c.csv"
+ ) shouldBe "a/c.csv"
+ }
+}