Skip to content

Commit 6c576a5

Browse files
Fix DockerImageName compatibility check when digest is present (#10527)
Strip tag from repository when parsing images with both tag and digest (e.g., postgres:16.8@sha256:...) to prevent tag leaking into repository name.
1 parent 6a02d00 commit 6c576a5

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

core/src/main/java/org/testcontainers/utility/DockerImageName.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ public DockerImageName(String fullImageName) {
8787
}
8888

8989
if (remoteName.contains("@sha256:")) {
90-
repository = remoteName.split("@sha256:")[0];
90+
String beforeDigest = remoteName.split("@sha256:")[0];
91+
repository = beforeDigest.contains(":") ? beforeDigest.split(":")[0] : beforeDigest;
9192
versioning = new Sha256Versioning(remoteName.split("@sha256:")[1]);
9293
} else if (remoteName.contains(":")) {
9394
repository = remoteName.split(":")[0];

core/src/test/java/org/testcontainers/utility/DockerImageNameCompatibilityTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,33 @@ void testImageWithClaimedCompatibilityForVersion() {
8585
.isFalse();
8686
}
8787

88+
@Test
89+
void testDigestOnlyImageIsCompatible() {
90+
DockerImageName subject = DockerImageName.parse("postgres@sha256:1234abcd1234abcd1234abcd1234abcd");
91+
92+
assertThat(subject.isCompatibleWith(DockerImageName.parse("postgres")))
93+
.as("postgres@sha256:... ~= postgres")
94+
.isTrue();
95+
}
96+
97+
@Test
98+
void testTagAndDigestImageIsCompatible() {
99+
DockerImageName subject = DockerImageName.parse("postgres:16.8@sha256:1234abcd1234abcd1234abcd1234abcd");
100+
101+
assertThat(subject.isCompatibleWith(DockerImageName.parse("postgres")))
102+
.as("postgres:16.8@sha256:... ~= postgres")
103+
.isTrue();
104+
}
105+
106+
@Test
107+
void testTagAndDigestImageWithRegistryIsCompatible() {
108+
DockerImageName subject = DockerImageName.parse("registry.foo.com/repo:tag@sha256:1234abcd1234abcd1234abcd1234abcd");
109+
110+
assertThat(subject.isCompatibleWith(DockerImageName.parse("registry.foo.com/repo")))
111+
.as("registry.foo.com/repo:tag@sha256:... ~= registry.foo.com/repo")
112+
.isTrue();
113+
}
114+
88115
@Test
89116
void testAssertMethodAcceptsCompatible() {
90117
DockerImageName subject = DockerImageName.parse("foo").asCompatibleSubstituteFor("bar");

core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.testcontainers.utility;
22

33
import org.junit.jupiter.api.Nested;
4+
import org.junit.jupiter.api.Test;
45
import org.junit.jupiter.params.ParameterizedTest;
56
import org.junit.jupiter.params.provider.Arguments;
67
import org.junit.jupiter.params.provider.MethodSource;
@@ -24,6 +25,8 @@ public static String[] getNames() {
2425
"registry.foo.com:1234/repo_here/my-name:1.0",
2526
"registry.foo.com:1234/repo-here/my-name@sha256:1234abcd1234abcd1234abcd1234abcd",
2627
"registry.foo.com:1234/my-name@sha256:1234abcd1234abcd1234abcd1234abcd",
28+
"myname:latest@sha256:1234abcd1234abcd1234abcd1234abcd",
29+
"registry.foo.com:1234/repo-here/my-name:1.0@sha256:1234abcd1234abcd1234abcd1234abcd",
2730
"1.2.3.4/my-name:1.0",
2831
"1.2.3.4:1234/my-name:1.0",
2932
"1.2.3.4/repo-here/my-name:1.0",
@@ -147,4 +150,37 @@ void testParsing(
147150
}
148151
}
149152
}
153+
154+
@Nested
155+
class TagAndDigestParsing {
156+
157+
@Test
158+
void testTagAndDigestStripsTagFromRepository() {
159+
DockerImageName imageName = DockerImageName.parse("myname:latest@sha256:1234abcd1234abcd1234abcd1234abcd");
160+
161+
assertThat(imageName.getRegistry()).isEqualTo("");
162+
assertThat(imageName.getUnversionedPart()).isEqualTo("myname");
163+
assertThat(imageName.getVersionPart()).isEqualTo("sha256:1234abcd1234abcd1234abcd1234abcd");
164+
}
165+
166+
@Test
167+
void testTagAndDigestWithRepoPath() {
168+
DockerImageName imageName = DockerImageName.parse("repo/myname:1.0@sha256:1234abcd1234abcd1234abcd1234abcd");
169+
170+
assertThat(imageName.getRegistry()).isEqualTo("");
171+
assertThat(imageName.getUnversionedPart()).isEqualTo("repo/myname");
172+
assertThat(imageName.getVersionPart()).isEqualTo("sha256:1234abcd1234abcd1234abcd1234abcd");
173+
}
174+
175+
@Test
176+
void testTagAndDigestWithRegistry() {
177+
DockerImageName imageName = DockerImageName.parse(
178+
"registry.foo.com:1234/repo-here/my-name:1.0@sha256:1234abcd1234abcd1234abcd1234abcd"
179+
);
180+
181+
assertThat(imageName.getRegistry()).isEqualTo("registry.foo.com:1234");
182+
assertThat(imageName.getUnversionedPart()).isEqualTo("registry.foo.com:1234/repo-here/my-name");
183+
assertThat(imageName.getVersionPart()).isEqualTo("sha256:1234abcd1234abcd1234abcd1234abcd");
184+
}
185+
}
150186
}

0 commit comments

Comments
 (0)