mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-30 23:53:48 +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:
		
							
								
								
									
										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]] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 CrazyMax
					CrazyMax