mirror of
https://github.com/docker/buildx.git
synced 2024-11-22 15:37:16 +08:00
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"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var httpPrefix = regexp.MustCompile(`^https?://`)
|
var (
|
||||||
var gitURLPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`)
|
httpPrefix = regexp.MustCompile(`^https?://`)
|
||||||
|
gitURLPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`)
|
||||||
|
|
||||||
|
validTargetNameChars = `[a-zA-Z0-9_-]+`
|
||||||
|
targetNamePattern = regexp.MustCompile(`^` + validTargetNameChars + `$`)
|
||||||
|
)
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
Name string
|
Name string
|
||||||
@ -176,8 +181,9 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
|
|
||||||
if len(fs) > 0 {
|
if len(fs) > 0 {
|
||||||
if err := hclparser.Parse(hcl.MergeFiles(fs), hclparser.Opt{
|
if err := hclparser.Parse(hcl.MergeFiles(fs), hclparser.Opt{
|
||||||
LookupVar: os.LookupEnv,
|
LookupVar: os.LookupEnv,
|
||||||
Vars: defaults,
|
Vars: defaults,
|
||||||
|
ValidateLabel: validateTargetName,
|
||||||
}, &c); err.HasErrors() {
|
}, &c); err.HasErrors() {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -798,3 +804,10 @@ func parseOutputType(str string) string {
|
|||||||
}
|
}
|
||||||
return ""
|
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"
|
"github.com/compose-spec/compose-go/loader"
|
||||||
compose "github.com/compose-spec/compose-go/types"
|
compose "github.com/compose-spec/compose-go/types"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseCompose(dt []byte) (*compose.Project, error) {
|
func parseCompose(dt []byte) (*compose.Project, error) {
|
||||||
@ -59,6 +60,10 @@ func ParseCompose(dt []byte) (*Config, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = validateTargetName(s.Name); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "invalid service name %q", s.Name)
|
||||||
|
}
|
||||||
|
|
||||||
var contextPathP *string
|
var contextPathP *string
|
||||||
if s.Build.Context != "" {
|
if s.Build.Context != "" {
|
||||||
contextPath := s.Build.Context
|
contextPath := s.Build.Context
|
||||||
|
@ -314,3 +314,55 @@ func newBool(val bool) *bool {
|
|||||||
b := val
|
b := val
|
||||||
return &b
|
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 (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
hcl "github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/hclparse"
|
"github.com/hashicorp/hcl/v2/hclparse"
|
||||||
"github.com/moby/buildkit/solver/errdefs"
|
"github.com/moby/buildkit/solver/errdefs"
|
||||||
"github.com/moby/buildkit/solver/pb"
|
"github.com/moby/buildkit/solver/pb"
|
||||||
|
@ -16,8 +16,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Opt struct {
|
type Opt struct {
|
||||||
LookupVar func(string) (string, bool)
|
LookupVar func(string) (string, bool)
|
||||||
Vars map[string]string
|
Vars map[string]string
|
||||||
|
ValidateLabel func(string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type variable struct {
|
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{
|
p := &parser{
|
||||||
opt: opt,
|
opt: opt,
|
||||||
|
|
||||||
@ -446,6 +453,17 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||||||
continue
|
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])
|
lblIndex := setLabel(vv, b.Labels[0])
|
||||||
|
|
||||||
oldValue, exists := t.values[b.Labels[0]]
|
oldValue, exists := t.values[b.Labels[0]]
|
||||||
|
Loading…
Reference in New Issue
Block a user