Skip to content

Commit 4ed519a

Browse files
a-orenclaude
andcommitted
fix(dockerfile): handle quoted and space-containing ARG default values
Change ARG_LINE_PATTERN from \\S+ to .+ so values with spaces are fully captured, and strip surrounding quotes before storing the default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bdc3e41 commit 4ed519a

5 files changed

Lines changed: 50 additions & 2 deletions

File tree

src/main/java/io/github/guacsec/trustifyda/providers/DockerfileProvider.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public final class DockerfileProvider extends Provider {
5050
Pattern.compile("^FROM\\s+", Pattern.CASE_INSENSITIVE);
5151

5252
private static final Pattern ARG_LINE_PATTERN =
53-
Pattern.compile("^ARG\\s+([A-Za-z_][A-Za-z0-9_]*)=(\\S+)", Pattern.CASE_INSENSITIVE);
53+
Pattern.compile("^ARG\\s+([A-Za-z_][A-Za-z0-9_]*)=(.+)", Pattern.CASE_INSENSITIVE);
5454

5555
private static final Pattern VAR_REF_PATTERN =
5656
Pattern.compile("\\$\\{([^}]+)}|\\$([A-Za-z_][A-Za-z0-9_]*)");
@@ -144,7 +144,12 @@ static List<String> parseAllFromImages(Path dockerfile) throws IOException {
144144
String trimmed = line.trim();
145145
var argMatcher = ARG_LINE_PATTERN.matcher(trimmed);
146146
if (argMatcher.find()) {
147-
argDefaults.put(argMatcher.group(1), argMatcher.group(2));
147+
String val = argMatcher.group(2).trim();
148+
if ((val.startsWith("\"") && val.endsWith("\""))
149+
|| (val.startsWith("'") && val.endsWith("'"))) {
150+
val = val.substring(1, val.length() - 1);
151+
}
152+
argDefaults.put(argMatcher.group(1), val);
148153
continue;
149154
}
150155
var fromMatcher = FROM_LINE_PATTERN.matcher(trimmed);

src/test/java/io/github/guacsec/trustifyda/providers/Dockerfile_Provider_Test.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,36 @@ void resolves_arg_substitution_with_bare_syntax() throws IOException {
188188
assertThat(images).hasSize(1).containsExactly("ubuntu:22.04");
189189
}
190190

191+
/** Verifies that double-quoted ARG default values are unquoted before resolution. */
192+
@Test
193+
void resolves_arg_with_double_quoted_value() throws IOException {
194+
var dockerfile = TEST_MANIFESTS.resolve("arg_double_quoted/Dockerfile");
195+
196+
List<String> images = DockerfileProvider.parseAllFromImages(dockerfile);
197+
198+
assertThat(images).hasSize(1).containsExactly("ubuntu:22.04");
199+
}
200+
201+
/** Verifies that single-quoted ARG default values are unquoted before resolution. */
202+
@Test
203+
void resolves_arg_with_single_quoted_value() throws IOException {
204+
var dockerfile = TEST_MANIFESTS.resolve("arg_single_quoted/Dockerfile");
205+
206+
List<String> images = DockerfileProvider.parseAllFromImages(dockerfile);
207+
208+
assertThat(images).hasSize(1).containsExactly("ubuntu:22.04");
209+
}
210+
211+
/** Verifies that ARG values with spaces are captured fully when quoted. */
212+
@Test
213+
void resolves_arg_with_spaces_in_quoted_value() throws IOException {
214+
var dockerfile = TEST_MANIFESTS.resolve("arg_value_with_spaces/Dockerfile");
215+
216+
List<String> images = DockerfileProvider.parseAllFromImages(dockerfile);
217+
218+
assertThat(images).hasSize(1).containsExactly("ubuntu:22.04");
219+
}
220+
191221
/** Verifies that ARG without default value causes the FROM line to be skipped. */
192222
@Test
193223
void skips_arg_substitution_without_default_value() {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ARG BASE_IMAGE="ubuntu:22.04"
2+
FROM ${BASE_IMAGE}
3+
4+
RUN echo hello
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ARG BASE_IMAGE='ubuntu:22.04'
2+
FROM ${BASE_IMAGE}
3+
4+
RUN echo hello
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ARG LABEL="my app label"
2+
ARG BASE_IMAGE=ubuntu:22.04
3+
FROM ${BASE_IMAGE}
4+
5+
LABEL description=${LABEL}

0 commit comments

Comments
 (0)