kra-new/internal/integration/storage/prefix.go

49 lines
1.4 KiB
Go

package storage
import (
"errors"
"path"
"strings"
)
// normalizeDeletePrefix rejects requests that could accidentally target the
// storage root and returns the canonical key form used by all backends.
func normalizeDeletePrefix(prefix string) (string, error) {
prefix = strings.TrimSpace(strings.ReplaceAll(prefix, "\\", "/"))
prefix = strings.Trim(prefix, "/")
if prefix == "" {
return "", errors.New("storage delete prefix is required")
}
for _, part := range strings.Split(prefix, "/") {
if part == ".." {
return "", errors.New("invalid storage delete prefix")
}
}
clean := path.Clean(prefix)
if clean == "." || clean == ".." || strings.HasPrefix(clean, "../") {
return "", errors.New("invalid storage delete prefix")
}
return clean, nil
}
// advanceDeletePrefixCursor prevents a backend that reports a truncated page
// without a new cursor from making DeletePrefix loop forever.
func advanceDeletePrefixCursor(current, next string, more bool) (string, error) {
if !more {
return "", nil
}
current = strings.TrimSpace(current)
next = strings.TrimSpace(next)
if next == "" || next == current {
return "", errors.New("storage delete prefix pagination made no progress")
}
return next, nil
}
func boundedPrefix(key, prefix string) string {
if strings.HasSuffix(strings.ReplaceAll(prefix, "\\", "/"), "/") && !strings.HasSuffix(key, "/") {
return key + "/"
}
return key
}