35 lines
1.1 KiB
Go
35 lines
1.1 KiB
Go
package pathsafe
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
var (
|
|
ErrOpaqueSegmentRequired = errors.New("opaque identifier is required")
|
|
ErrOpaqueSegmentInvalid = errors.New("opaque identifier must contain only ASCII letters, digits, '.', '_', or '-'")
|
|
)
|
|
|
|
// ValidateOpaqueSegment validates an identity token that occupies exactly one
|
|
// portable local-path and object-key segment. It deliberately does not trim or
|
|
// normalize input: callers must reject rather than silently rewrite identity.
|
|
func ValidateOpaqueSegment(value string) error {
|
|
if value == "" {
|
|
return ErrOpaqueSegmentRequired
|
|
}
|
|
if value == "." || value == ".." {
|
|
return fmt.Errorf("%w: dot segments are not allowed", ErrOpaqueSegmentInvalid)
|
|
}
|
|
for index := 0; index < len(value); index++ {
|
|
character := value[index]
|
|
if (character >= 'a' && character <= 'z') ||
|
|
(character >= 'A' && character <= 'Z') ||
|
|
(character >= '0' && character <= '9') ||
|
|
character == '.' || character == '_' || character == '-' {
|
|
continue
|
|
}
|
|
return fmt.Errorf("%w: invalid byte at offset %d", ErrOpaqueSegmentInvalid, index)
|
|
}
|
|
return nil
|
|
}
|