Skip to content

Fix false positive in DockerImageName.isCompatibleWith for library/-prefixed images#11922

Open
TimurRakhmatullin86 wants to merge 1 commit into
testcontainers:mainfrom
TimurRakhmatullin86:fix/dockerimagename-library-compatibility
Open

Fix false positive in DockerImageName.isCompatibleWith for library/-prefixed images#11922
TimurRakhmatullin86 wants to merge 1 commit into
testcontainers:mainfrom
TimurRakhmatullin86:fix/dockerimagename-library-compatibility

Conversation

@TimurRakhmatullin86

Copy link
Copy Markdown

Broken behaviour

DockerImageName.isCompatibleWith() returns true for any image whose repository starts with library/, regardless of what it is compared against:

DockerImageName.parse("library/mysql:8")
    .isCompatibleWith(DockerImageName.parse("postgres")); // true (!)

The library-prefix handling introduced in #6174 derives imageWithLibraryPrefix from this only and then compares it back against this:

DockerImageName imageWithLibraryPrefix = DockerImageName.parse(finalImageName);
if (other.equals(this) || imageWithLibraryPrefix.equals(this)) {

other never takes part in that comparison, so for any registry-less library/… name the check degenerates to parse(this.repository).equals(this), which is always true (parse drops the tag and AnyVersion equals everything). Since assertCompatibleWith(...) guards the constructors of essentially every module (~96 call sites), it silently accepts wrong images instead of failing fast with the asCompatibleSubstituteFor guidance. The existing test testAssertMethodAcceptsCompatibleLibraryPrefix kept passing for this same wrong reason.

Fix

Normalize both sides to the library/-prefixed form before comparing, and only for names without a registry (Docker Hub official images):

  • library/foo:1.2.3 ~ barfalse (was true)
  • library/foo ~ footrue (as before, now for the right reason)
  • foo ~ library/footrue (previously false; same image, now symmetric)
  • Version semantics are unchanged: other stays on the left-hand side of equals, so a tag present in other must still match exactly and an untagged other still acts as a wildcard (library/foo:1.2.3 ~ foo:4.5.6false).
  • Names with an explicit registry are left untouched (some.registry/foolibrary/foo).

Images named library/… that previously passed the check only because of the false positive now fail with the standard compatibility error — that is the intended behaviour of the guard.

Related to #9958: the library/postgres case reported there is what #6174 targeted; the docker.io/… registry-qualified cases from that issue are out of scope for this PR.

Testing

Added regression tests to DockerImageNameCompatibilityTest covering the false positive, prefix symmetry in both directions (with and without tags), registry exclusion, and asCompatibleSubstituteFor interaction. The new tests fail on main and pass with this change; all pre-existing tests pass, checkstyle and spotless are clean.

@TimurRakhmatullin86 TimurRakhmatullin86 requested a review from a team as a code owner July 10, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant