Merge pull request #27873 from duglin/fixContChar

Fix case where \ at EOF made the builder ignore the command
This commit is contained in:
John Howard 2016-11-03 10:30:15 -07:00 committed by GitHub
commit ecf405b64d
4 changed files with 43 additions and 7 deletions

View file

@ -238,7 +238,7 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
for k, v := range b.options.Labels {
line += fmt.Sprintf("%q='%s' ", k, v)
}
_, node, err := parser.ParseLine(line, &b.directive)
_, node, err := parser.ParseLine(line, &b.directive, false)
if err != nil {
return "", err
}

View file

@ -35,7 +35,7 @@ func parseSubCommand(rest string, d *Directive) (*Node, map[string]bool, error)
return nil, nil, nil
}
_, child, err := ParseLine(rest, d)
_, child, err := ParseLine(rest, d, false)
if err != nil {
return nil, nil, err
}

View file

@ -95,7 +95,7 @@ func init() {
}
// ParseLine parses a line and returns the remainder.
func ParseLine(line string, d *Directive) (string, *Node, error) {
func ParseLine(line string, d *Directive, ignoreCont bool) (string, *Node, error) {
// Handle the parser directive '# escape=<char>. Parser directives must precede
// any builder instruction or other comments, and cannot be repeated.
if d.LookingForDirectives {
@ -122,7 +122,7 @@ func ParseLine(line string, d *Directive) (string, *Node, error) {
return "", nil, nil
}
if d.LineContinuationRegex.MatchString(line) {
if !ignoreCont && d.LineContinuationRegex.MatchString(line) {
line = d.LineContinuationRegex.ReplaceAllString(line, "")
return line, nil, nil
}
@ -165,7 +165,7 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) {
}
scannedLine := strings.TrimLeftFunc(string(scannedBytes), unicode.IsSpace)
currentLine++
line, child, err := ParseLine(scannedLine, d)
line, child, err := ParseLine(scannedLine, d, false)
if err != nil {
return nil, err
}
@ -187,7 +187,7 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) {
if strings.TrimSpace(newline) == "" {
break
}
line, child, err = ParseLine(line+newline, d)
line, child, err = ParseLine(line+newline, d, false)
if err != nil {
return nil, err
}
@ -197,7 +197,13 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) {
}
}
if child == nil && line != "" {
_, child, err = ParseLine(line, d)
// When we call ParseLine we'll pass in 'true' for
// the ignoreCont param if we're at the EOF. This will
// prevent the func from returning immediately w/o
// parsing the line thinking that there's more input
// to come.
_, child, err = ParseLine(line, d, scanner.Err() == nil)
if err != nil {
return nil, err
}

View file

@ -7237,3 +7237,33 @@ func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
c.Assert(err, checker.IsNil)
c.Assert(strings.TrimSpace(out), checker.Equals, "3")
}
func (s *DockerSuite) TestBuildContChar(c *check.C) {
name := "testbuildcontchar"
_, out, err := buildImageWithOut(name,
`FROM busybox\`, true)
c.Assert(err, checker.IsNil)
c.Assert(out, checker.Contains, "Step 1/1 : FROM busybox")
_, out, err = buildImageWithOut(name,
`FROM busybox
RUN echo hi \`, true)
c.Assert(err, checker.IsNil)
c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox")
c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi\n")
_, out, err = buildImageWithOut(name,
`FROM busybox
RUN echo hi \\`, true)
c.Assert(err, checker.IsNil)
c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox")
c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi \\\n")
_, out, err = buildImageWithOut(name,
`FROM busybox
RUN echo hi \\\`, true)
c.Assert(err, checker.IsNil)
c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox")
c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi \\\\\n")
}