// SPDX-FileCopyrightText: Copyright The Lima Authors1// SPDX-License-Identifier: Apache-2.023// From https://github.com/containerd/containerd/blob/v2.1.1/pkg/identifiers/validate.go4// SPDX-FileCopyrightText: Copyright The containerd Authors5// LICENSE: https://github.com/containerd/containerd/blob/v2.1.1/LICENSE6// NOTICE: https://github.com/containerd/containerd/blob/v2.1.1/NOTICE78/*9Copyright The containerd Authors.1011Licensed under the Apache License, Version 2.0 (the "License");12you may not use this file except in compliance with the License.13You may obtain a copy of the License at1415http://www.apache.org/licenses/LICENSE-2.01617Unless required by applicable law or agreed to in writing, software18distributed under the License is distributed on an "AS IS" BASIS,19WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.20See the License for the specific language governing permissions and21limitations under the License.22*/2324// Package identifiers provides common validation for identifiers and keys25// across Lima (originally from containerd).26//27// Identifiers in Lima must be a alphanumeric, allowing limited28// underscores, dashes and dots.29//30// While the character set may be expanded in the future, identifiers31// are guaranteed to be safely used as filesystem path components.32package identifiers3334import (35"errors"36"fmt"37"regexp"38)3940const (41maxLength = 7642alphanum = `[A-Za-z0-9]+`43separators = `[._-]`44)4546// identifierRe defines the pattern for valid identifiers.47var identifierRe = regexp.MustCompile(reAnchor(alphanum + reGroup(separators+reGroup(alphanum)) + "*"))4849// Validate returns nil if the string s is a valid identifier.50//51// Identifiers are similar to the domain name rules according to RFC 1035, section 2.3.1. However52// rules in this package are relaxed to allow numerals to follow period (".") and mixed case is53// allowed.54//55// In general identifiers that pass this validation should be safe for use as filesystem path components.56func Validate(s string) error {57if s == "" {58return errors.New("identifier must not be empty")59}6061if len(s) > maxLength {62return fmt.Errorf("identifier %q greater than maximum length (%d characters)", s, maxLength)63}6465if !identifierRe.MatchString(s) {66return fmt.Errorf("identifier %q must match %v", s, identifierRe)67}68return nil69}7071func reGroup(s string) string {72return `(?:` + s + `)`73}7475func reAnchor(s string) string {76return `^` + s + `$`77}787980