cli/command/container: use strings.Cut

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-12-27 16:26:08 +01:00
parent 6c39bc1f60
commit 424401233f
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
2 changed files with 26 additions and 32 deletions

View File

@ -386,13 +386,12 @@ func splitCpArg(arg string) (container, path string) {
return "", arg return "", arg
} }
parts := strings.SplitN(arg, ":", 2) container, path, ok := strings.Cut(arg, ":")
if !ok || strings.HasPrefix(container, ".") {
if len(parts) == 1 || strings.HasPrefix(parts[0], ".") {
// Either there's no `:` in the arg // Either there's no `:` in the arg
// OR it's an explicit local relative path like `./file:name.txt`. // OR it's an explicit local relative path like `./file:name.txt`.
return "", arg return "", arg
} }
return parts[0], parts[1] return container, path
} }

View File

@ -354,14 +354,13 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
toBind := bind toBind := bind
if parsed.Type == string(mounttypes.TypeBind) { if parsed.Type == string(mounttypes.TypeBind) {
if arr := strings.SplitN(bind, ":", 2); len(arr) == 2 { if hostPart, targetPath, ok := strings.Cut(bind, ":"); ok {
hostPart := arr[0]
if strings.HasPrefix(hostPart, "."+string(filepath.Separator)) || hostPart == "." { if strings.HasPrefix(hostPart, "."+string(filepath.Separator)) || hostPart == "." {
if absHostPart, err := filepath.Abs(hostPart); err == nil { if absHostPart, err := filepath.Abs(hostPart); err == nil {
hostPart = absHostPart hostPart = absHostPart
} }
} }
toBind = hostPart + ":" + arr[1] toBind = hostPart + ":" + targetPath
} }
} }
@ -377,11 +376,8 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
// Can't evaluate options passed into --tmpfs until we actually mount // Can't evaluate options passed into --tmpfs until we actually mount
tmpfs := make(map[string]string) tmpfs := make(map[string]string)
for _, t := range copts.tmpfs.GetAll() { for _, t := range copts.tmpfs.GetAll() {
if arr := strings.SplitN(t, ":", 2); len(arr) > 1 { k, v, _ := strings.Cut(t, ":")
tmpfs[arr[0]] = arr[1] tmpfs[k] = v
} else {
tmpfs[arr[0]] = ""
}
} }
var ( var (
@ -820,12 +816,11 @@ func convertToStandardNotation(ports []string) ([]string, error) {
if strings.Contains(publish, "=") { if strings.Contains(publish, "=") {
params := map[string]string{"protocol": "tcp"} params := map[string]string{"protocol": "tcp"}
for _, param := range strings.Split(publish, ",") { for _, param := range strings.Split(publish, ",") {
opt := strings.Split(param, "=") k, v, ok := strings.Cut(param, "=")
if len(opt) < 2 { if !ok || k == "" {
return optsList, errors.Errorf("invalid publish opts format (should be name=value but got '%s')", param) return optsList, errors.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
} }
params[k] = v
params[opt[0]] = opt[1]
} }
optsList = append(optsList, fmt.Sprintf("%s:%s/%s", params["published"], params["target"], params["protocol"])) optsList = append(optsList, fmt.Sprintf("%s:%s/%s", params["published"], params["target"], params["protocol"]))
} else { } else {
@ -846,22 +841,22 @@ func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]st
// takes a local seccomp daemon, reads the file contents for sending to the daemon // takes a local seccomp daemon, reads the file contents for sending to the daemon
func parseSecurityOpts(securityOpts []string) ([]string, error) { func parseSecurityOpts(securityOpts []string) ([]string, error) {
for key, opt := range securityOpts { for key, opt := range securityOpts {
con := strings.SplitN(opt, "=", 2) k, v, ok := strings.Cut(opt, "=")
if len(con) == 1 && con[0] != "no-new-privileges" { if !ok && k != "no-new-privileges" {
if strings.Contains(opt, ":") { k, v, ok = strings.Cut(opt, ":")
con = strings.SplitN(opt, ":", 2) }
} else { if (!ok || v == "") && k != "no-new-privileges" {
// "no-new-privileges" is the only option that does not require a value.
return securityOpts, errors.Errorf("Invalid --security-opt: %q", opt) return securityOpts, errors.Errorf("Invalid --security-opt: %q", opt)
} }
} if k == "seccomp" && v != "unconfined" {
if con[0] == "seccomp" && con[1] != "unconfined" { f, err := os.ReadFile(v)
f, err := os.ReadFile(con[1])
if err != nil { if err != nil {
return securityOpts, errors.Errorf("opening seccomp profile (%s) failed: %v", con[1], err) return securityOpts, errors.Errorf("opening seccomp profile (%s) failed: %v", v, err)
} }
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
if err := json.Compact(b, f); err != nil { if err := json.Compact(b, f); err != nil {
return securityOpts, errors.Errorf("compacting json for seccomp profile (%s) failed: %v", con[1], err) return securityOpts, errors.Errorf("compacting json for seccomp profile (%s) failed: %v", v, err)
} }
securityOpts[key] = fmt.Sprintf("seccomp=%s", b.Bytes()) securityOpts[key] = fmt.Sprintf("seccomp=%s", b.Bytes())
} }
@ -893,12 +888,11 @@ func parseSystemPaths(securityOpts []string) (filtered, maskedPaths, readonlyPat
func parseStorageOpts(storageOpts []string) (map[string]string, error) { func parseStorageOpts(storageOpts []string) (map[string]string, error) {
m := make(map[string]string) m := make(map[string]string)
for _, option := range storageOpts { for _, option := range storageOpts {
if strings.Contains(option, "=") { k, v, ok := strings.Cut(option, "=")
opt := strings.SplitN(option, "=", 2) if !ok {
m[opt[0]] = opt[1]
} else {
return nil, errors.Errorf("invalid storage option") return nil, errors.Errorf("invalid storage option")
} }
m[k] = v
} }
return m, nil return m, nil
} }
@ -919,7 +913,8 @@ func parseDevice(device, serverOS string) (container.DeviceMapping, error) {
func parseLinuxDevice(device string) (container.DeviceMapping, error) { func parseLinuxDevice(device string) (container.DeviceMapping, error) {
var src, dst string var src, dst string
permissions := "rwm" permissions := "rwm"
arr := strings.Split(device, ":") // We expect 3 parts at maximum; limit to 4 parts to detect invalid options.
arr := strings.SplitN(device, ":", 4)
switch len(arr) { switch len(arr) {
case 3: case 3:
permissions = arr[2] permissions = arr[2]