Skip to content

Commit 195fac7

Browse files
committed
FIX - Catastrophic Backtracking for images with illegal char in tag
- Simplify regular expression checking for validity of Image Reference to fix Catastrophic Backtracking for long custom images with illegal characters in tag #39246
1 parent 4fd0e29 commit 195fac7

File tree

4 files changed

+63
-5
lines changed
  • spring-boot-project
    • spring-boot-docker-compose/src
    • spring-boot-tools/spring-boot-buildpack-platform/src

4 files changed

+63
-5
lines changed

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/core/Regex.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ final class Regex implements CharSequence {
5050
private static final Regex PATH_COMPONENT;
5151
static {
5252
Regex segment = Regex.of("[a-z0-9]+");
53-
Regex separator = Regex.group("[._]|__|[-]*");
53+
Regex separator = Regex.group("[._-]{1,2}");
5454
Regex separatedSegment = Regex.group(separator, segment).oneOrMoreTimes();
5555
PATH_COMPONENT = Regex.of(segment, Regex.group(separatedSegment).zeroOrOnce());
5656
}

spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/core/ImageReferenceTests.java

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,14 @@
1616

1717
package org.springframework.boot.docker.compose.core;
1818

19+
import java.time.Duration;
20+
1921
import org.junit.jupiter.api.Test;
22+
import org.testcontainers.shaded.org.awaitility.Awaitility;
2023

2124
import static org.assertj.core.api.Assertions.assertThat;
2225
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
26+
import static org.assertj.core.api.Assertions.fail;
2327

2428
/**
2529
* Tests for {@link ImageReference}.
@@ -165,4 +169,30 @@ void equalsAndHashCode() {
165169
assertThat(r1).isEqualTo(r1).isEqualTo(r2).isNotEqualTo(r3);
166170
}
167171

172+
@Test
173+
void ofSimpleNameWithSingleCharacterSuffix() {
174+
ImageReference reference = ImageReference.of("ubuntu-a");
175+
assertThat(reference.getDomain()).isEqualTo("docker.io");
176+
assertThat(reference.getName()).isEqualTo("library/ubuntu-a");
177+
assertThat(reference.getTag()).isNull();
178+
assertThat(reference.getDigest()).isNull();
179+
assertThat(reference).hasToString("docker.io/library/ubuntu-a");
180+
}
181+
182+
183+
@Test
184+
void ofWhenImageNameIsVeryLongAndHasIllegalCharacter() {
185+
Awaitility.await()
186+
.timeout(Duration.ofSeconds(2))
187+
.until(() -> {
188+
try {
189+
ImageReference.of("docker.io/library/this-image-has-a-long-name-with-an-invalid-tag-which-is-at-danger-of-catastrophic-backtracking:1.0.0+1234");
190+
fail("Image Reference contains an illegal character and should have thrown an IllegalArgumentException");
191+
}
192+
catch (IllegalArgumentException ignored) {
193+
}
194+
return true;
195+
});
196+
}
197+
168198
}

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Regex.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ final class Regex implements CharSequence {
5050
private static final Regex PATH_COMPONENT;
5151
static {
5252
Regex segment = Regex.of("[a-z0-9]+");
53-
Regex separator = Regex.group("[._]|__|[-]*");
53+
Regex separator = Regex.group("[._-]{1,2}");
5454
Regex separatedSegment = Regex.group(separator, segment).oneOrMoreTimes();
5555
PATH_COMPONENT = Regex.of(segment, Regex.group(separatedSegment).zeroOrOnce());
5656
}

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,12 +17,15 @@
1717
package org.springframework.boot.buildpack.platform.docker.type;
1818

1919
import java.io.File;
20+
import java.time.Duration;
2021

2122
import org.junit.jupiter.api.Test;
23+
import org.testcontainers.shaded.org.awaitility.Awaitility;
2224

2325
import static org.assertj.core.api.Assertions.assertThat;
2426
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
2527
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
28+
import static org.assertj.core.api.Assertions.fail;
2629

2730
/**
2831
* Tests for {@link ImageReference}.
@@ -306,4 +309,29 @@ void inTaglessForm() {
306309
assertThat(updated).hasToString("docker.io/library/ubuntu");
307310
}
308311

312+
@Test
313+
void ofSimpleNameWithSingleCharacterSuffix() {
314+
ImageReference reference = ImageReference.of("ubuntu-a");
315+
assertThat(reference.getDomain()).isEqualTo("docker.io");
316+
assertThat(reference.getName()).isEqualTo("library/ubuntu-a");
317+
assertThat(reference.getTag()).isNull();
318+
assertThat(reference.getDigest()).isNull();
319+
assertThat(reference).hasToString("docker.io/library/ubuntu-a");
320+
}
321+
322+
@Test
323+
void ofWhenIsVeryLongAndHasIllegalCharacter() {
324+
Awaitility.await()
325+
.timeout(Duration.ofSeconds(2))
326+
.until(() -> {
327+
try {
328+
ImageReference.of("docker.io/library/this-image-has-a-long-name-with-an-invalid-tag-which-is-at-danger-of-catastrophic-backtracking:1.0.0+1234");
329+
fail("Contains an illegal character and should have thrown an IllegalArgumentException");
330+
}
331+
catch (IllegalArgumentException ignored) {
332+
}
333+
return true;
334+
});
335+
}
336+
309337
}

0 commit comments

Comments
 (0)