Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rhel/dockerfile/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ func (p *labelParser) Run() error {
if strings.Contains(v, `escape=`) {
eq := strings.IndexByte(v, '=')
if eq == -1 {
return fmt.Errorf("botched parser directive: %#q", i.val)
panic("string changed while parsing?")
}
esc, _ := utf8.DecodeRuneInString(v[:eq+1])
esc, _ := utf8.DecodeRuneInString(v[eq+1:])
p.lex.Escape(esc)
p.unquote.Escape(esc)
p.vars.Escape(esc)
Expand Down
68 changes: 32 additions & 36 deletions rhel/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,56 @@ import (
"bytes"
"context"
"encoding/json"
"io/fs"
"os"
"path/filepath"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
"golang.org/x/tools/txtar"
)

func TestGetLabels(t *testing.T) {
var errPrefix = []byte("error:")
ctx := context.Background()
td := os.DirFS("testdata")
de, err := fs.ReadDir(td, ".")

ms, err := filepath.Glob("testdata/*.txtar")
if err != nil {
t.Fatal(err)
}
for _, de := range de {
n := de.Name()
if !strings.HasPrefix(n, "Dockerfile") ||
strings.HasSuffix(n, ".want") ||
strings.HasSuffix(n, ".want.err") {
continue
}
t.Run(n, func(t *testing.T) {
f, err := td.Open(n)
for _, m := range ms {
t.Run(strings.TrimSuffix(filepath.Base(m), filepath.Ext(m)), func(t *testing.T) {
ar, err := txtar.ParseFile(m)
if err != nil {
t.Fatal(err)
t.Fatalf("error parsing archive: %v", err)
}
defer f.Close()
w, err := td.Open(n + ".want")
if err != nil {
t.Fatal(err)
}
defer w.Close()
wantErr, _ := fs.ReadFile(td, n+".want.err")

want := make(map[string]string)
if err := json.NewDecoder(w).Decode(&want); err != nil {
t.Error(err)
}
got, err := GetLabels(ctx, f)
if len(wantErr) == 0 {
if err != nil {
t.Error(err)
}
} else {
if err == nil {
t.Error("got nil, wanted error")
} else {
if got, want := err.Error(), string(bytes.TrimSpace(wantErr)); got != want {
t.Errorf("got: %+#q, want: %+#q", got, want)
var got, want map[string]string
wantErr := bytes.HasPrefix(ar.Comment, errPrefix)
for _, f := range ar.Files {
switch f.Name {
case "Dockerfile":
got, err = GetLabels(ctx, bytes.NewReader(f.Data))
case "Want":
want = make(map[string]string)
if err := json.Unmarshal(f.Data, &want); err != nil {
t.Fatalf("unmarshaling wanted values: %v", err)
}
default:
t.Logf("skipping unknown file: %s", f.Name)
}
}

if wantErr {
got := err.Error()
want := string(bytes.TrimSpace(bytes.TrimPrefix(ar.Comment, errPrefix)))
if got != want {
t.Error(cmp.Diff(got, want))
}
return
}
if err != nil {
t.Errorf("error parsing labels: %v", err)
}
if !cmp.Equal(got, want) {
t.Error(cmp.Diff(got, want))
}
Expand Down
25 changes: 24 additions & 1 deletion rhel/dockerfile/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,31 @@ package dockerfile

import (
"bytes"
"path/filepath"
"testing"

"golang.org/x/tools/txtar"
)

func FuzzLex(f *testing.F) {
ms, err := filepath.Glob("testdata/*.txtar")
if err != nil {
f.Fatal(err)
}
for _, m := range ms {
ar, err := txtar.ParseFile(m)
if err != nil {
f.Fatalf("error parsing archive: %v", err)
}
File:
for _, af := range ar.Files {
if af.Name == "Dockerfile" {
f.Add(af.Data)
break File
}
}
}

f.Fuzz(func(t *testing.T, b []byte) {
l := newLexer()
l.Reset(bytes.NewReader(b))
Expand All @@ -22,4 +43,6 @@ func FuzzLex(f *testing.F) {
})
}

//go:generate sh -c "go run golang.org/x/tools/cmd/file2fuzz -o testdata/fuzz/FuzzLex $(ls -1 testdata/Dockerfile* | grep -v [.]want)"
// To add new files to the fuzz corpus:
//
// go run golang.org/x/tools/cmd/file2fuzz -o testdata/fuzz/FuzzLex [FILE]
5 changes: 5 additions & 0 deletions rhel/dockerfile/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dockerfile

//go:generate -command stringer go run golang.org/x/tools/cmd/stringer
//go:generate stringer -type itemKind
//go:generate stringer -type varExpand -linecomment
3 changes: 0 additions & 3 deletions rhel/dockerfile/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ type item struct {

type itemKind int

//go:generate -command stringer go run golang.org/x/tools/cmd/stringer
//go:generate stringer -type itemKind

const (
itemError itemKind = iota
itemComment
Expand Down
3 changes: 3 additions & 0 deletions rhel/dockerfile/testdata/Colon.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
error: dockerfile: bad expansion of "error": rogue colon
-- Dockerfile --
LABEL a ${error::}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-- Dockerfile --
# Normal comments are fine
FROM scratch

Expand All @@ -7,3 +8,8 @@ LABEL \
C=D
# This comment is stripped despite the apparent continuation

-- Want --
{
"A": "B",
"C": "D"
}
15 changes: 15 additions & 0 deletions rhel/dockerfile/testdata/Default.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- Dockerfile --
LABEL a ${unset}
LABEL b ${unset=set}
LABEL c ${unset}

LABEL null=
LABEL d ${null:=reset}
-- Want --
{
"a": "",
"b": "set",
"c": "set",
"d": "reset",
"null": ""
}
4 changes: 0 additions & 4 deletions rhel/dockerfile/testdata/Dockerfile-Comments.want

This file was deleted.

2 changes: 0 additions & 2 deletions rhel/dockerfile/testdata/Dockerfile-InvalidLabel

This file was deleted.

4 changes: 0 additions & 4 deletions rhel/dockerfile/testdata/Dockerfile-InvalidLabel.want

This file was deleted.

This file was deleted.

15 changes: 0 additions & 15 deletions rhel/dockerfile/testdata/Dockerfile-etcd-rhel7.want

This file was deleted.

3 changes: 0 additions & 3 deletions rhel/dockerfile/testdata/Dockerfile-issue526.want

This file was deleted.

20 changes: 0 additions & 20 deletions rhel/dockerfile/testdata/Dockerfile-nodejs10.want

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

20 changes: 0 additions & 20 deletions rhel/dockerfile/testdata/Dockerfile-ubi7-7.9-516.want

This file was deleted.

22 changes: 0 additions & 22 deletions rhel/dockerfile/testdata/Dockerfile-ubi8-minimal-8.4-208.want

This file was deleted.

3 changes: 3 additions & 0 deletions rhel/dockerfile/testdata/Error.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
error: dockerfile: bad expansion of "unset": should error (error if unset or null)
-- Dockerfile --
LABEL a ${unset:?should error}
8 changes: 8 additions & 0 deletions rhel/dockerfile/testdata/Escape.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Dockerfile --
# escape=ꙮ
LABEL a ꙮ
ꙮ$b
-- Want --
{
"a": "$b"
}
4 changes: 4 additions & 0 deletions rhel/dockerfile/testdata/InvalidLabel.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: invalid assignment syntax: `A=B C=D # Comments not allowed in this position`
-- Dockerfile --
LABEL A=B \
C=D # Comments not allowed in this position
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
-- Dockerfile --
FROM scratch

ENV A="B C" \
D=E

LABEL label="$A $D"
-- Want --
{
"label": "B C E"
}
Loading