mirror of https://github.com/docker/cli.git
cli/command/container: use strings.Cut
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
6c39bc1f60
commit
424401233f
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Reference in New Issue