Files
seaweedfs/weed/s3api/s3tables/utils_location_test.go
T
Chris LuandDevin 6f93f87446 s3tables: confine caller-supplied metadataLocation to the table's namespace
CreateTable/RegisterTable/UpdateTable (and the view equivalents) validate
the location only for bucket and traversal, so a tenant can register a
table whose location resolves into another namespace's directory and
DeleteTable will purge it. Require the location to live under the
caller's namespace subtree, the boundary per-namespace delegation uses.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-12 02:41:28 -07:00

41 lines
2.0 KiB
Go

package s3tables
import "testing"
func TestValidateMetadataLocation(t *testing.T) {
tests := []struct {
name string
loc string
bucket string
namespace string
wantErr bool
}{
{"empty allowed", "", "bkt", "ns", false},
{"own namespace", "s3://bkt/ns/t/metadata/v1.metadata.json", "bkt", "ns", false},
{"own namespace arbitrary layout", "s3://bkt/ns/warehouse/t/metadata/v1.metadata.json", "bkt", "ns", false},
{"cross bucket rejected", "s3://other/ns/t/metadata/v1.metadata.json", "bkt", "ns", true},
{"cross namespace rejected", "s3://bkt/nsa/t/metadata/v1.metadata.json", "bkt", "ns", true},
{"cross namespace data dir rejected", "s3://bkt/nsa/vtab/data/metadata/v1.metadata.json", "bkt", "ns", true},
{"namespace prefix rejected", "s3://bkt/nsa/vtab/metadata/v1.metadata.json", "bkt", "ns", true},
{"outside namespace tree rejected", "s3://bkt/shared/t/metadata/v1.metadata.json", "bkt", "ns", true},
{"namespace dir without table path rejected", "s3://bkt/ns", "bkt", "ns", true},
{"bucket only rejected", "s3://bkt", "bkt", "ns", true},
{"bucket with trailing slash rejected", "s3://bkt/", "bkt", "ns", true},
{"slash-only path rejected", "s3://bkt///", "bkt", "ns", true},
{"dotdot in path rejected", "s3://bkt/../victim/metadata/v1.metadata.json", "bkt", "ns", true},
{"dotdot mid path rejected", "s3://bkt/ns/../../victim/metadata/v1.metadata.json", "bkt", "ns", true},
{"dot segment rejected", "s3://bkt/ns/./t/metadata/v1.metadata.json", "bkt", "ns", true},
{"backslash segment rejected", "s3://bkt/ns/\\t/metadata/v1.metadata.json", "bkt", "ns", true},
{"non-s3 scheme rejected", "file:///bkt/ns/t", "bkt", "ns", true},
{"empty location string", "s3://", "bkt", "ns", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateMetadataLocation(tt.loc, tt.bucket, tt.namespace)
if (err != nil) != tt.wantErr {
t.Fatalf("ValidateMetadataLocation(%q, %q, %q) err = %v, wantErr = %v", tt.loc, tt.bucket, tt.namespace, err, tt.wantErr)
}
})
}
}