Guard against invalid paths in ResourceUrlProvider

This commit makes sure that no `StringIndexOutOfBoundsException` is
thrown when `getForRequestUrl` is called with a URL that's shorter than
the expected context path.

Issue: SPR-16526
master
Brian Clozel 7 years ago
parent 4f8c4546f1
commit 6d26e61ac7
  1. 8
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java
  2. 12
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java

@ -22,6 +22,7 @@ import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
@ -177,6 +178,9 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
}
int prefixIndex = getLookupPathIndex(request);
int suffixIndex = getEndPathIndex(requestUrl);
if (prefixIndex >= suffixIndex) {
return null;
}
String prefix = requestUrl.substring(0, prefixIndex);
String suffix = requestUrl.substring(suffixIndex);
String lookupPath = requestUrl.substring(prefixIndex, suffixIndex);
@ -194,11 +198,11 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
private int getEndPathIndex(String lookupPath) {
int suffixIndex = lookupPath.length();
int queryIndex = lookupPath.indexOf('?');
if(queryIndex > 0) {
if (queryIndex > 0) {
suffixIndex = queryIndex;
}
int hashIndex = lookupPath.indexOf('#');
if(hashIndex > 0) {
if (hashIndex > 0) {
suffixIndex = Math.min(suffixIndex, hashIndex);
}
return suffixIndex;

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -90,6 +90,16 @@ public class ResourceUrlProviderTests {
assertEquals("/resources/foo.css#hash", resolvedUrl);
}
@Test // SPR-16526
public void getStaticResourceWithMissingContextPath() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setContextPath("/contextpath-longer-than-request-path");
request.setRequestURI("/contextpath-longer-than-request-path/style.css");
String url = "/resources/foo.css";
String resolvedUrl = this.urlProvider.getForRequestUrl(request, url);
assertNull(resolvedUrl);
}
@Test
public void getFingerprintedResourceUrl() {
Map<String, VersionStrategy> versionStrategyMap = new HashMap<>();

Loading…
Cancel
Save