Skip to content

Commit

Permalink
dockerfile: fixes
Browse files Browse the repository at this point in the history
Signed-off-by: Hank Donnay <[email protected]>
  • Loading branch information
hdonnay committed Feb 7, 2024
1 parent 4782461 commit 550e102
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 34 deletions.
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?")

Check warning on line 103 in rhel/dockerfile/dockerfile.go

View check run for this annotation

Codecov / codecov/patch

rhel/dockerfile/dockerfile.go#L103

Added line #L103 was not covered by tests
}
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
93 changes: 61 additions & 32 deletions rhel/dockerfile/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,22 @@ func (v *Vars) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error
v.state = varEmit
return nDst, nSrc, transform.ErrShortDst
case v.state == varError:
return nDst, nSrc, fmt.Errorf("dockerfile: bad expansion of %q: %s", v.varName.String(), v.varExpand.String())
return nDst, nSrc, fmt.Errorf("dockerfile: bad expansion of %q: %s (%v)",
v.varName.String(),
v.varExpand.String(),
v.expand,
)
}
nDst += n
v.state = varConsume
default:
panic("state botch")
}
}
if v.esc {
// Ended in a "bare" escape character. Just pass it through.
nDst += utf8.EncodeRune(dst[nDst:], v.escchar)
}
if v.state == varBareword && atEOF {
// Hit EOF, so variable name is complete.
n, done := v.emit(dst[nDst:])
Expand Down Expand Up @@ -296,9 +304,22 @@ func (v *Vars) emit(dst []byte) (int, bool) {
suffix := v.expand == varTrimSuffix || v.expand == varTrimSuffixGreedy
re, err := convertPattern([]byte(word), greedy, suffix)
if err != nil {
panic("TODO(hank): TrimPrefix/TrimSuffix: " + err.Error())
v.state = varError
return 0, true

Check warning on line 308 in rhel/dockerfile/vars.go

View check run for this annotation

Codecov / codecov/patch

rhel/dockerfile/vars.go#L307-L308

Added lines #L307 - L308 were not covered by tests
}
ms := re.FindStringSubmatch(val)
switch len(ms) {
case 0, 1:
// No match, do nothing.
case 2:
if suffix {
val = strings.TrimSuffix(val, ms[1])
} else {
val = strings.TrimPrefix(val, ms[1])
}
default:
panic(fmt.Sprintf("pattern compiler is acting up; got: %#v", ms))

Check warning on line 321 in rhel/dockerfile/vars.go

View check run for this annotation

Codecov / codecov/patch

rhel/dockerfile/vars.go#L320-L321

Added lines #L320 - L321 were not covered by tests
}
val = re.ReplaceAllLiteralString(val, "")
default:
panic("expand state botch")
}
Expand All @@ -311,16 +332,28 @@ func (v *Vars) emit(dst []byte) (int, bool) {

// ConvertPattern transforms "pat" from (something like) the POSIX sh pattern
// language to a regular expression, then returns the compiled regexp.
//
// The resulting regexp reports the prefix/suffix to be removed as the first
// submatch when executed.
//
// This conversion is tricky, because extra hoops are needed to work around the
// leftmost-first behavior.
func convertPattern(pat []byte, greedy bool, suffix bool) (_ *regexp.Regexp, err error) {
var rePat strings.Builder
rePat.Grow(len(pat) * 2) // 🤷

if !greedy {
rePat.WriteString(`(?U)`)
// This is needed to "push" a suffix pattern to the correct place. Note that
// the "greediness" is backwards: this is the input that's _not_ the
// pattern.
pad := `(?:.*)`
if greedy {
pad = `(?:.*?)`
}
if !suffix {
rePat.WriteByte('^')

rePat.WriteByte('^')
if suffix {
rePat.WriteString(pad)
}
rePat.WriteByte('(')
off := 0
r, sz := rune(0), 0
for ; off < len(pat); off += sz {
Expand All @@ -332,6 +365,9 @@ func convertPattern(pat []byte, greedy bool, suffix bool) (_ *regexp.Regexp, err
switch r {
case '*': // Kleene star
rePat.WriteString(`.*`)
if !suffix && !greedy {
rePat.WriteByte('?')
}
case '?': // Single char
rePat.WriteByte('.')
case '\\':
Expand All @@ -355,9 +391,11 @@ func convertPattern(pat []byte, greedy bool, suffix bool) (_ *regexp.Regexp, err
rePat.WriteRune(r)
}
}
if suffix {
rePat.WriteByte('$')
rePat.WriteByte(')')
if !suffix {
rePat.WriteString(pad)
}
rePat.WriteByte('$')

return regexp.Compile(rePat.String())
}
Expand Down Expand Up @@ -430,26 +468,17 @@ const (
type varExpand uint8

const (
// Expand to the named variable or the empty string.
varExpandSimple varExpand = iota
// Expand to the named variable or the provided word.
varExpandDefault
varExpandDefaultNull
// Set the named variable to the provided word if unset, then expand to the named variable.
varSetDefault
varSetDefaultNull
// Expand to the provided word or the empty string.
varExpandAlternate
varExpandAlternateNull
// Error if unset.
varErrIfUnset
varErrIfUnsetNull
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the smallest suffix.
varTrimSuffix
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the largest suffix.
varTrimSuffixGreedy
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the smallest prefix.
varTrimPrefix
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the largest prefix.
varTrimPrefixGreedy
varExpandSimple varExpand = iota // simple expansion
varExpandDefault // default expansion
varExpandDefaultNull // default+null expansion
varSetDefault // set default
varSetDefaultNull // set default, incl. null
varExpandAlternate // alternate expansion
varExpandAlternateNull // alternate expanxion, incl. null
varErrIfUnset // error if unset
varErrIfUnsetNull // error if unset or null
varTrimSuffix // trim suffix
varTrimSuffixGreedy // greedy trim suffix
varTrimPrefix // trim prefix
varTrimPrefixGreedy // greedy trim prefix
)

0 comments on commit 550e102

Please sign in to comment.