s3tables: fix shared table-location bucket mapping collisions (#8286)

* s3tables: prevent shared table-location bucket mapping overwrite

* Update weed/s3api/bucket_paths.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Chris Lu
2026-02-10 11:28:29 -08:00
committed by GitHub
parent d6825ffce2
commit 0385acba02
6 changed files with 307 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ package s3tables
import (
"crypto/rand"
"crypto/sha1"
"encoding/hex"
"fmt"
"net/url"
@@ -118,6 +119,33 @@ func GetTableLocationMappingPath(tableLocationBucket string) string {
return path.Join(GetTableLocationMappingDir(), tableLocationBucket)
}
// GetTableLocationMappingEntryPath returns the filer path for a table-specific mapping entry.
// Each table gets its own entry so multiple tables can share the same external table-location bucket.
func GetTableLocationMappingEntryPath(tableLocationBucket, tablePath string) string {
return path.Join(GetTableLocationMappingPath(tableLocationBucket), tableLocationMappingEntryName(tablePath))
}
func tableLocationMappingEntryName(tablePath string) string {
normalized := path.Clean("/" + strings.TrimSpace(strings.TrimPrefix(tablePath, "/")))
sum := sha1.Sum([]byte(normalized))
return hex.EncodeToString(sum[:])
}
func tableBucketPathFromTablePath(tablePath string) (string, bool) {
normalized := path.Clean("/" + strings.TrimSpace(strings.TrimPrefix(tablePath, "/")))
tablesPrefix := strings.TrimSuffix(TablesPath, "/") + "/"
if !strings.HasPrefix(normalized, tablesPrefix) {
return "", false
}
remaining := strings.TrimPrefix(normalized, tablesPrefix)
bucketName, _, _ := strings.Cut(remaining, "/")
if bucketName == "" {
return "", false
}
return path.Join(TablesPath, bucketName), true
}
// Metadata structures
type tableBucketMetadata struct {