Came from looking at issue #27545
Signed-off-by: Doug Davis <dug@us.ibm.com>
| ... | ... |
@@ -238,7 +238,7 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri |
| 238 | 238 |
for k, v := range b.options.Labels {
|
| 239 | 239 |
line += fmt.Sprintf("%q='%s' ", k, v)
|
| 240 | 240 |
} |
| 241 |
- _, node, err := parser.ParseLine(line, &b.directive) |
|
| 241 |
+ _, node, err := parser.ParseLine(line, &b.directive, false) |
|
| 242 | 242 |
if err != nil {
|
| 243 | 243 |
return "", err |
| 244 | 244 |
} |
| ... | ... |
@@ -95,7 +95,7 @@ func init() {
|
| 95 | 95 |
} |
| 96 | 96 |
|
| 97 | 97 |
// ParseLine parses a line and returns the remainder. |
| 98 |
-func ParseLine(line string, d *Directive) (string, *Node, error) {
|
|
| 98 |
+func ParseLine(line string, d *Directive, ignoreCont bool) (string, *Node, error) {
|
|
| 99 | 99 |
// Handle the parser directive '# escape=<char>. Parser directives must precede |
| 100 | 100 |
// any builder instruction or other comments, and cannot be repeated. |
| 101 | 101 |
if d.LookingForDirectives {
|
| ... | ... |
@@ -122,7 +122,7 @@ func ParseLine(line string, d *Directive) (string, *Node, error) {
|
| 122 | 122 |
return "", nil, nil |
| 123 | 123 |
} |
| 124 | 124 |
|
| 125 |
- if d.LineContinuationRegex.MatchString(line) {
|
|
| 125 |
+ if !ignoreCont && d.LineContinuationRegex.MatchString(line) {
|
|
| 126 | 126 |
line = d.LineContinuationRegex.ReplaceAllString(line, "") |
| 127 | 127 |
return line, nil, nil |
| 128 | 128 |
} |
| ... | ... |
@@ -165,7 +165,7 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) {
|
| 165 | 165 |
} |
| 166 | 166 |
scannedLine := strings.TrimLeftFunc(string(scannedBytes), unicode.IsSpace) |
| 167 | 167 |
currentLine++ |
| 168 |
- line, child, err := ParseLine(scannedLine, d) |
|
| 168 |
+ line, child, err := ParseLine(scannedLine, d, false) |
|
| 169 | 169 |
if err != nil {
|
| 170 | 170 |
return nil, err |
| 171 | 171 |
} |
| ... | ... |
@@ -187,7 +187,7 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) {
|
| 187 | 187 |
if strings.TrimSpace(newline) == "" {
|
| 188 | 188 |
break |
| 189 | 189 |
} |
| 190 |
- line, child, err = ParseLine(line+newline, d) |
|
| 190 |
+ line, child, err = ParseLine(line+newline, d, false) |
|
| 191 | 191 |
if err != nil {
|
| 192 | 192 |
return nil, err |
| 193 | 193 |
} |
| ... | ... |
@@ -197,7 +197,13 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) {
|
| 197 | 197 |
} |
| 198 | 198 |
} |
| 199 | 199 |
if child == nil && line != "" {
|
| 200 |
- _, child, err = ParseLine(line, d) |
|
| 200 |
+ // When we call ParseLine we'll pass in 'true' for |
|
| 201 |
+ // the ignoreCont param if we're at the EOF. This will |
|
| 202 |
+ // prevent the func from returning immediately w/o |
|
| 203 |
+ // parsing the line thinking that there's more input |
|
| 204 |
+ // to come. |
|
| 205 |
+ |
|
| 206 |
+ _, child, err = ParseLine(line, d, scanner.Err() == nil) |
|
| 201 | 207 |
if err != nil {
|
| 202 | 208 |
return nil, err |
| 203 | 209 |
} |
| ... | ... |
@@ -7237,3 +7237,33 @@ func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
|
| 7237 | 7237 |
c.Assert(err, checker.IsNil) |
| 7238 | 7238 |
c.Assert(strings.TrimSpace(out), checker.Equals, "3") |
| 7239 | 7239 |
} |
| 7240 |
+ |
|
| 7241 |
+func (s *DockerSuite) TestBuildContChar(c *check.C) {
|
|
| 7242 |
+ name := "testbuildcontchar" |
|
| 7243 |
+ |
|
| 7244 |
+ _, out, err := buildImageWithOut(name, |
|
| 7245 |
+ `FROM busybox\`, true) |
|
| 7246 |
+ c.Assert(err, checker.IsNil) |
|
| 7247 |
+ c.Assert(out, checker.Contains, "Step 1/1 : FROM busybox") |
|
| 7248 |
+ |
|
| 7249 |
+ _, out, err = buildImageWithOut(name, |
|
| 7250 |
+ `FROM busybox |
|
| 7251 |
+ RUN echo hi \`, true) |
|
| 7252 |
+ c.Assert(err, checker.IsNil) |
|
| 7253 |
+ c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox") |
|
| 7254 |
+ c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi\n") |
|
| 7255 |
+ |
|
| 7256 |
+ _, out, err = buildImageWithOut(name, |
|
| 7257 |
+ `FROM busybox |
|
| 7258 |
+ RUN echo hi \\`, true) |
|
| 7259 |
+ c.Assert(err, checker.IsNil) |
|
| 7260 |
+ c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox") |
|
| 7261 |
+ c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi \\\n") |
|
| 7262 |
+ |
|
| 7263 |
+ _, out, err = buildImageWithOut(name, |
|
| 7264 |
+ `FROM busybox |
|
| 7265 |
+ RUN echo hi \\\`, true) |
|
| 7266 |
+ c.Assert(err, checker.IsNil) |
|
| 7267 |
+ c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox") |
|
| 7268 |
+ c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi \\\\\n") |
|
| 7269 |
+} |