Properly expand URI vars with regex
Before this commit UriComponents was capable of expanding URI vars that
may have contained a regular expressions (as supported with
@RequestMapping for example). However if the regular expressions
contained any nested "{}" the expand did not work correctly.
This commit sanitizes a URI template source removing any content
between nested "{}" prior to expanding. This works since we only care
about the URI variable name.
Issue: SPR-13311
This commit is contained in:
parent
1a9e42b49d
commit
2e79a30fed
|
|
@ -219,6 +219,9 @@ public abstract class UriComponents implements Serializable {
|
|||
if (source.indexOf('{') == -1) {
|
||||
return source;
|
||||
}
|
||||
if (source.indexOf(':') != -1) {
|
||||
source = sanitizeSource(source);
|
||||
}
|
||||
Matcher matcher = NAMES_PATTERN.matcher(source);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
|
|
@ -236,6 +239,27 @@ public abstract class UriComponents implements Serializable {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove nested "{}" such as in URI vars with regular expressions.
|
||||
*/
|
||||
private static String sanitizeSource(String source) {
|
||||
int level = 0;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (char c : source.toCharArray()) {
|
||||
if (c == '{') {
|
||||
level++;
|
||||
}
|
||||
if (c == '}') {
|
||||
level--;
|
||||
}
|
||||
if (level > 1 || (level == 1 && c == '}')) {
|
||||
continue;
|
||||
}
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getVariableName(String match) {
|
||||
int colonIdx = match.indexOf(':');
|
||||
return (colonIdx != -1 ? match.substring(0, colonIdx) : match);
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
package org.springframework.web.util;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.web.util.UriComponentsBuilder.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
|
|
@ -27,9 +23,17 @@ import java.io.ObjectOutputStream;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @author Phillip Webb
|
||||
|
|
@ -82,6 +86,16 @@ public class UriComponentsTests {
|
|||
assertEquals("http://example.com/1 2 3 4", uriComponents.toUriString());
|
||||
}
|
||||
|
||||
// SPR-13311
|
||||
|
||||
@Test
|
||||
public void expandWithRegexVar() {
|
||||
String template = "/myurl/{name:[a-z]{1,5}}/show";
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(template).build();
|
||||
uriComponents = uriComponents.expand(Collections.singletonMap("name", "test"));
|
||||
assertEquals("/myurl/test/show", uriComponents.getPath());
|
||||
}
|
||||
|
||||
// SPR-12123
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue