Skip to content

Commit 550e102

Browse files
committed
dockerfile: fixes
Signed-off-by: Hank Donnay <hdonnay@redhat.com>
1 parent 4782461 commit 550e102

2 files changed

Lines changed: 63 additions & 34 deletions

File tree

rhel/dockerfile/dockerfile.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ func (p *labelParser) Run() error {
100100
if strings.Contains(v, `escape=`) {
101101
eq := strings.IndexByte(v, '=')
102102
if eq == -1 {
103-
return fmt.Errorf("botched parser directive: %#q", i.val)
103+
panic("string changed while parsing?")
104104
}
105-
esc, _ := utf8.DecodeRuneInString(v[:eq+1])
105+
esc, _ := utf8.DecodeRuneInString(v[eq+1:])
106106
p.lex.Escape(esc)
107107
p.unquote.Escape(esc)
108108
p.vars.Escape(esc)

rhel/dockerfile/vars.go

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,22 @@ func (v *Vars) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error
214214
v.state = varEmit
215215
return nDst, nSrc, transform.ErrShortDst
216216
case v.state == varError:
217-
return nDst, nSrc, fmt.Errorf("dockerfile: bad expansion of %q: %s", v.varName.String(), v.varExpand.String())
217+
return nDst, nSrc, fmt.Errorf("dockerfile: bad expansion of %q: %s (%v)",
218+
v.varName.String(),
219+
v.varExpand.String(),
220+
v.expand,
221+
)
218222
}
219223
nDst += n
220224
v.state = varConsume
221225
default:
222226
panic("state botch")
223227
}
224228
}
229+
if v.esc {
230+
// Ended in a "bare" escape character. Just pass it through.
231+
nDst += utf8.EncodeRune(dst[nDst:], v.escchar)
232+
}
225233
if v.state == varBareword && atEOF {
226234
// Hit EOF, so variable name is complete.
227235
n, done := v.emit(dst[nDst:])
@@ -296,9 +304,22 @@ func (v *Vars) emit(dst []byte) (int, bool) {
296304
suffix := v.expand == varTrimSuffix || v.expand == varTrimSuffixGreedy
297305
re, err := convertPattern([]byte(word), greedy, suffix)
298306
if err != nil {
299-
panic("TODO(hank): TrimPrefix/TrimSuffix: " + err.Error())
307+
v.state = varError
308+
return 0, true
309+
}
310+
ms := re.FindStringSubmatch(val)
311+
switch len(ms) {
312+
case 0, 1:
313+
// No match, do nothing.
314+
case 2:
315+
if suffix {
316+
val = strings.TrimSuffix(val, ms[1])
317+
} else {
318+
val = strings.TrimPrefix(val, ms[1])
319+
}
320+
default:
321+
panic(fmt.Sprintf("pattern compiler is acting up; got: %#v", ms))
300322
}
301-
val = re.ReplaceAllLiteralString(val, "")
302323
default:
303324
panic("expand state botch")
304325
}
@@ -311,16 +332,28 @@ func (v *Vars) emit(dst []byte) (int, bool) {
311332

312333
// ConvertPattern transforms "pat" from (something like) the POSIX sh pattern
313334
// language to a regular expression, then returns the compiled regexp.
335+
//
336+
// The resulting regexp reports the prefix/suffix to be removed as the first
337+
// submatch when executed.
338+
//
339+
// This conversion is tricky, because extra hoops are needed to work around the
340+
// leftmost-first behavior.
314341
func convertPattern(pat []byte, greedy bool, suffix bool) (_ *regexp.Regexp, err error) {
315342
var rePat strings.Builder
316343
rePat.Grow(len(pat) * 2) // 🤷
317-
318-
if !greedy {
319-
rePat.WriteString(`(?U)`)
344+
// This is needed to "push" a suffix pattern to the correct place. Note that
345+
// the "greediness" is backwards: this is the input that's _not_ the
346+
// pattern.
347+
pad := `(?:.*)`
348+
if greedy {
349+
pad = `(?:.*?)`
320350
}
321-
if !suffix {
322-
rePat.WriteByte('^')
351+
352+
rePat.WriteByte('^')
353+
if suffix {
354+
rePat.WriteString(pad)
323355
}
356+
rePat.WriteByte('(')
324357
off := 0
325358
r, sz := rune(0), 0
326359
for ; off < len(pat); off += sz {
@@ -332,6 +365,9 @@ func convertPattern(pat []byte, greedy bool, suffix bool) (_ *regexp.Regexp, err
332365
switch r {
333366
case '*': // Kleene star
334367
rePat.WriteString(`.*`)
368+
if !suffix && !greedy {
369+
rePat.WriteByte('?')
370+
}
335371
case '?': // Single char
336372
rePat.WriteByte('.')
337373
case '\\':
@@ -355,9 +391,11 @@ func convertPattern(pat []byte, greedy bool, suffix bool) (_ *regexp.Regexp, err
355391
rePat.WriteRune(r)
356392
}
357393
}
358-
if suffix {
359-
rePat.WriteByte('$')
394+
rePat.WriteByte(')')
395+
if !suffix {
396+
rePat.WriteString(pad)
360397
}
398+
rePat.WriteByte('$')
361399

362400
return regexp.Compile(rePat.String())
363401
}
@@ -430,26 +468,17 @@ const (
430468
type varExpand uint8
431469

432470
const (
433-
// Expand to the named variable or the empty string.
434-
varExpandSimple varExpand = iota
435-
// Expand to the named variable or the provided word.
436-
varExpandDefault
437-
varExpandDefaultNull
438-
// Set the named variable to the provided word if unset, then expand to the named variable.
439-
varSetDefault
440-
varSetDefaultNull
441-
// Expand to the provided word or the empty string.
442-
varExpandAlternate
443-
varExpandAlternateNull
444-
// Error if unset.
445-
varErrIfUnset
446-
varErrIfUnsetNull
447-
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the smallest suffix.
448-
varTrimSuffix
449-
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the largest suffix.
450-
varTrimSuffixGreedy
451-
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the smallest prefix.
452-
varTrimPrefix
453-
// Expand by interpreting "word" as a pattern, then expanding "parameter" and removing the largest prefix.
454-
varTrimPrefixGreedy
471+
varExpandSimple varExpand = iota // simple expansion
472+
varExpandDefault // default expansion
473+
varExpandDefaultNull // default+null expansion
474+
varSetDefault // set default
475+
varSetDefaultNull // set default, incl. null
476+
varExpandAlternate // alternate expansion
477+
varExpandAlternateNull // alternate expanxion, incl. null
478+
varErrIfUnset // error if unset
479+
varErrIfUnsetNull // error if unset or null
480+
varTrimSuffix // trim suffix
481+
varTrimSuffixGreedy // greedy trim suffix
482+
varTrimPrefix // trim prefix
483+
varTrimPrefixGreedy // greedy trim prefix
455484
)

0 commit comments

Comments
 (0)