@@ -41,15 +41,10 @@ function parseSubCommand(cmd) {
4141 return false ;
4242}
4343
44- // Parse environment like statements. Note that this does *not* handle
45- // variable interpolation, which will be handled in the evaluator.
46- function parseNameVal ( cmd ) {
47- // This is kind of tricky because we need to support the old
48- // variant: KEY name value
49- // as well as the new one: KEY name=value ...
50- // The trigger to know which one is being used will be whether we hit
51- // a space or = first. space ==> old, "=" ==> new
52-
44+ // Helper to parse words (i.e space delimited or quoted strings) in a statement.
45+ // The quotes are preserved as part of this function and they are stripped later
46+ // as part of processWords().
47+ function parseWords ( rest ) {
5348 var S_inSpaces = 1 ;
5449 var S_inWord = 2 ;
5550 var S_inQuote = 3 ;
@@ -61,7 +56,6 @@ function parseNameVal(cmd) {
6156 var blankOK = false ;
6257 var ch ;
6358 var pos ;
64- var rest = cmd . rest ;
6559
6660 for ( pos = 0 ; pos <= rest . length ; pos ++ ) {
6761 if ( pos != rest . length ) {
@@ -88,15 +82,6 @@ function parseNameVal(cmd) {
8882 phase = S_inSpaces ;
8983 if ( blankOK || word . length > 0 ) {
9084 words . push ( word ) ;
91-
92- // Look for = and if not there assume
93- // we're doing the old stuff and
94- // just read the rest of the line
95- if ( ! word . indexOf ( '=' ) >= 0 ) {
96- word = rest . substr ( pos ) . trim ( ) ;
97- words . push ( word ) ;
98- break ;
99- }
10085 }
10186 word = '' ;
10287 blankOK = false ;
@@ -139,6 +124,20 @@ function parseNameVal(cmd) {
139124 }
140125 }
141126
127+ return words ;
128+ }
129+
130+ // Parse environment like statements. Note that this does *not* handle
131+ // variable interpolation, which will be handled in the evaluator.
132+ function parseNameVal ( cmd ) {
133+ // This is kind of tricky because we need to support the old
134+ // variant: KEY name value
135+ // as well as the new one: KEY name=value ...
136+ // The trigger to know which one is being used will be whether we hit
137+ // a space or = first. space ==> old, "=" ==> new
138+ var word ;
139+ var words = parseWords ( cmd . rest ) ;
140+
142141 cmd . args = { } ;
143142
144143 if ( words . length === 0 ) {
@@ -150,7 +149,7 @@ function parseNameVal(cmd) {
150149 // Old format (KEY name value)
151150 var strs = cmd . rest . split ( TOKEN_WHITESPACE ) ;
152151 if ( strs . length < 2 ) {
153- cmd . error = cmd . name + ' must have two arguments, got ' + rest ;
152+ cmd . error = cmd . name + ' must have two arguments, got ' + cmd . rest ;
154153 return false ;
155154 }
156155
@@ -183,6 +182,19 @@ function parseLabel(cmd) {
183182 return parseNameVal ( cmd ) ;
184183}
185184
185+ // Parses a statement containing one or more keyword definition(s) and/or
186+ // value assignments, like `name1 name2= name3="" name4=value`.
187+ // Note that this is a stricter format than the old format of assignment,
188+ // allowed by parseNameVal(), in a way that this only allows assignment of the
189+ // form `keyword=[<value>]` like `name2=`, `name3=""`, and `name4=value` above.
190+ // In addition, a keyword definition alone is of the form `keyword` like `name1`
191+ // above. And the assignments `name2=` and `name3=""` are equivalent and
192+ // assign an empty value to the respective keywords.
193+ function parseNameOrNameVal ( cmd ) {
194+ cmd . args = parseWords ( cmd . rest ) ;
195+ return true ;
196+ }
197+
186198// Parses a whitespace-delimited set of arguments. The result is a
187199// list of string arguments.
188200function parseStringsWhitespaceDelimited ( cmd ) {
@@ -246,6 +258,7 @@ function parseJsonOrList(cmd) {
246258// be incorporated directly into the existing AST as a next.
247259var commandParsers = {
248260 'ADD' : parseJsonOrList ,
261+ 'ARG' : parseNameOrNameVal ,
249262 'CMD' : parseJsonOrString ,
250263 'COPY' : parseJsonOrList ,
251264 'ENTRYPOINT' : parseJsonOrString ,
@@ -256,6 +269,7 @@ var commandParsers = {
256269 'MAINTAINER' : parseString ,
257270 'ONBUILD' : parseSubCommand ,
258271 'RUN' : parseJsonOrString ,
272+ 'STOPSIGNAL' : parseString ,
259273 'USER' : parseString ,
260274 'VOLUME' : parseJsonOrList ,
261275 'WORKDIR' : parseString
@@ -307,13 +321,14 @@ function parseLine(line, lineno) {
307321
308322 var commandParserFn = commandParsers [ command . name ] ;
309323 if ( ! commandParserFn ) {
310- // Ignore invalid Dockerfile instructions
324+ // Invalid Dockerfile instruction, but allow it and move on.
311325 // log.debug('Invalid Dockerfile command:', command.name);
312- return { command : null , remainder : '' } ;
326+ commandParserFn = parseString ;
313327 }
314328
315329 if ( commandParserFn ( command ) ) {
316330 // Successfully converted the arguments.
331+ command . raw = line ;
317332 delete command . rest ;
318333 }
319334
@@ -353,7 +368,7 @@ function parse(contents, options) {
353368 for ( i = 0 ; i < lines . length ; i ++ ) {
354369 lineno = i + 1 ;
355370 if ( remainder ) {
356- line = remainder + ' ' + lines [ i ] ;
371+ line = remainder + lines [ i ] ;
357372 } else {
358373 line = lines [ i ] ;
359374 }
0 commit comments