mirror of https://github.com/docker/buildx.git
bake: restrict target name
This fix adds a restriction `[a-zA-Z0-9_-]+` for target name. This is pretty much the same as the container name restriction in moby. Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
parent
11b771c789
commit
c74b2fe7a4
21
bake/bake.go
21
bake/bake.go
|
@ -22,8 +22,13 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var httpPrefix = regexp.MustCompile(`^https?://`)
|
||||
var gitURLPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`)
|
||||
var (
|
||||
httpPrefix = regexp.MustCompile(`^https?://`)
|
||||
gitURLPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`)
|
||||
|
||||
validTargetNameChars = `[a-zA-Z0-9_-]+`
|
||||
targetNamePattern = regexp.MustCompile(`^` + validTargetNameChars + `$`)
|
||||
)
|
||||
|
||||
type File struct {
|
||||
Name string
|
||||
|
@ -176,8 +181,9 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||
|
||||
if len(fs) > 0 {
|
||||
if err := hclparser.Parse(hcl.MergeFiles(fs), hclparser.Opt{
|
||||
LookupVar: os.LookupEnv,
|
||||
Vars: defaults,
|
||||
LookupVar: os.LookupEnv,
|
||||
Vars: defaults,
|
||||
ValidateLabel: validateTargetName,
|
||||
}, &c); err.HasErrors() {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -798,3 +804,10 @@ func parseOutputType(str string) string {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func validateTargetName(name string) error {
|
||||
if !targetNamePattern.MatchString(name) {
|
||||
return errors.Errorf("only %q are allowed", validTargetNameChars)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -788,3 +788,58 @@ group "default" {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTargetName(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
cases := []struct {
|
||||
target string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
target: "a",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
target: "abc",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
target: "a/b",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
target: "a.b",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
target: "_a",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
target: "a_b",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
target: "AbC",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
target: "AbC-0123",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
tt := tt
|
||||
t.Run(tt.target, func(t *testing.T) {
|
||||
_, _, err := ReadTargets(ctx, []File{{
|
||||
Name: "docker-bake.hcl",
|
||||
Data: []byte(`target "` + tt.target + `" {}`),
|
||||
}}, []string{tt.target}, nil, nil)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/compose-spec/compose-go/loader"
|
||||
compose "github.com/compose-spec/compose-go/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func parseCompose(dt []byte) (*compose.Project, error) {
|
||||
|
@ -59,6 +60,10 @@ func ParseCompose(dt []byte) (*Config, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
if err = validateTargetName(s.Name); err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid service name %q", s.Name)
|
||||
}
|
||||
|
||||
var contextPathP *string
|
||||
if s.Build.Context != "" {
|
||||
contextPath := s.Build.Context
|
||||
|
|
|
@ -314,3 +314,55 @@ func newBool(val bool) *bool {
|
|||
b := val
|
||||
return &b
|
||||
}
|
||||
|
||||
func TestServiceName(t *testing.T) {
|
||||
cases := []struct {
|
||||
svc string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
svc: "a",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
svc: "abc",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
svc: "a.b",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
svc: "_a",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
svc: "a_b",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
svc: "AbC",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
svc: "AbC-0123",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
tt := tt
|
||||
t.Run(tt.svc, func(t *testing.T) {
|
||||
_, err := ParseCompose([]byte(`
|
||||
services:
|
||||
` + tt.svc + `:
|
||||
build:
|
||||
context: .
|
||||
`))
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package bake
|
|||
import (
|
||||
"strings"
|
||||
|
||||
hcl "github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclparse"
|
||||
"github.com/moby/buildkit/solver/errdefs"
|
||||
"github.com/moby/buildkit/solver/pb"
|
||||
|
|
|
@ -16,8 +16,9 @@ import (
|
|||
)
|
||||
|
||||
type Opt struct {
|
||||
LookupVar func(string) (string, bool)
|
||||
Vars map[string]string
|
||||
LookupVar func(string) (string, bool)
|
||||
Vars map[string]string
|
||||
ValidateLabel func(string) error
|
||||
}
|
||||
|
||||
type variable struct {
|
||||
|
@ -262,6 +263,12 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||
}
|
||||
}
|
||||
|
||||
if opt.ValidateLabel == nil {
|
||||
opt.ValidateLabel = func(string) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
p := &parser{
|
||||
opt: opt,
|
||||
|
||||
|
@ -446,6 +453,17 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||
continue
|
||||
}
|
||||
|
||||
if err := opt.ValidateLabel(b.Labels[0]); err != nil {
|
||||
return hcl.Diagnostics{
|
||||
&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid name",
|
||||
Detail: err.Error(),
|
||||
Subject: &b.LabelRanges[0],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
lblIndex := setLabel(vv, b.Labels[0])
|
||||
|
||||
oldValue, exists := t.values[b.Labels[0]]
|
||||
|
|
Loading…
Reference in New Issue