Merge branch '7.0.x'

This commit is contained in:
Brian Clozel
2026-09-25 17:08:06 +02:00
6 changed files with 57 additions and 2 deletions
@@ -176,9 +176,12 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport {
return;
}
position += getKeyword().length();
while (Character.isWhitespace(content.charAt(position))) {
while (position < content.length() && Character.isWhitespace(content.charAt(position))) {
position++;
}
if (position == content.length()) {
return;
}
if (content.charAt(position) == '\'') {
position = extractLink(position, '\'', content, result);
}
@@ -194,6 +197,12 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport {
protected int extractLink(int index, char endChar, String content, Set<ContentChunkInfo> result) {
int start = index + 1;
int end = content.indexOf(endChar, start);
if (end == -1) {
if (logger.isTraceEnabled()) {
logger.trace("Unterminated link at index " + start + ", no closing '" + endChar + "'");
}
return content.length();
}
result.add(new ContentChunkInfo(start, end, true));
return end + 1;
}
@@ -183,6 +183,25 @@ class CssLinkResourceTransformerTests {
.verify();
}
@Test
void transformUnclosedUrlFunction() {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/unclosed_url_function.css"));
Resource css = getResource("unclosed_url_function.css");
String expected = """
body { background: url("/static/images/image-f448cd1d5dba82b774f3202c878230b3.png?#iefix") }
div { background: url(images/image.png
""";
StepVerifier.create(this.transformerChain.transform(exchange, css)
.cast(TransformedResource.class))
.consumeNextWith(transformedResource -> {
String result = new String(transformedResource.getByteArray(), UTF_8);
assertThat(result).isEqualToNormalizingNewlines(expected);
})
.expectComplete()
.verify();
}
private Resource getResource(String filePath) {
return new ClassPathResource("test/" + filePath, getClass());
}
@@ -0,0 +1,2 @@
body { background: url("images/image.png?#iefix") }
div { background: url(images/image.png
@@ -140,9 +140,12 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport {
return;
}
position += getKeyword().length();
while (Character.isWhitespace(content.charAt(position))) {
while (position < content.length() && Character.isWhitespace(content.charAt(position))) {
position++;
}
if (position == content.length()) {
return;
}
if (content.charAt(position) == '\'') {
position = extractLink(position, "'", content, result);
}
@@ -158,6 +161,12 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport {
protected int extractLink(int index, String endKey, String content, SortedSet<ContentChunkInfo> linksToAdd) {
int start = index + 1;
int end = content.indexOf(endKey, start);
if (end == -1) {
if (logger.isTraceEnabled()) {
logger.trace("Unterminated link at index " + start + ", no closing \"" + endKey + "\"");
}
return content.length();
}
linksToAdd.add(new ContentChunkInfo(start, end));
return end + endKey.length();
}
@@ -167,6 +167,20 @@ class CssLinkResourceTransformerTests {
assertThat(result).isEqualToNormalizingNewlines(expected);
}
@Test
void transformUnclosedUrlFunction() throws Exception {
this.request = new MockHttpServletRequest("GET", "/static/unclosed_url_function.css");
Resource css = getResource("unclosed_url_function.css");
String expected = """
body { background: url("/static/images/image-f448cd1d5dba82b774f3202c878230b3.png?#iefix") }
div { background: url(images/image.png
""";
TransformedResource actual = (TransformedResource) this.transformerChain.transform(this.request, css);
String result = new String(actual.getByteArray(), UTF_8);
assertThat(result).isEqualToNormalizingNewlines(expected);
}
private Resource getResource(String filePath) {
return new ClassPathResource("test/" + filePath, getClass());
}
@@ -0,0 +1,2 @@
body { background: url("images/image.png?#iefix") }
div { background: url(images/image.png