Skip to content

Commit 7c5050c

Browse files
committed
Prevent StackOverflowError in AbstractJackson2HttpMessageConverter
Issue: SPR-14520
1 parent 14ae8be commit 7c5050c

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,13 @@ private ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableT
356356
return resolvedType;
357357
}
358358
}
359-
resolvedType = resolveVariable(typeVariable, contextType.getSuperType());
360-
if (resolvedType.resolve() != null) {
361-
return resolvedType;
359+
360+
ResolvableType superType = contextType.getSuperType();
361+
if (superType != ResolvableType.NONE) {
362+
resolvedType = resolveVariable(typeVariable, superType);
363+
if (resolvedType.resolve() != null) {
364+
return resolvedType;
365+
}
362366
}
363367
for (ResolvableType ifc : contextType.getInterfaces()) {
364368
resolvedType = resolveVariable(typeVariable, ifc);

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,25 @@ public void defaultCharset() throws Exception {
692692
assertEquals("UTF-8", this.servletResponse.getCharacterEncoding());
693693
}
694694

695+
@Test // SPR-14520
696+
public void resolveArgumentTypeVariableWithGenericInterface() throws Exception {
697+
this.servletRequest.setContent("\"foo\"".getBytes("UTF-8"));
698+
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
699+
700+
Method method = MyControllerImplementingInterface.class.getMethod("handle", Object.class);
701+
HandlerMethod handlerMethod = new HandlerMethod(new MyControllerImplementingInterface(), method);
702+
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
703+
704+
List<HttpMessageConverter<?>> converters = new ArrayList<>();
705+
converters.add(new MappingJackson2HttpMessageConverter());
706+
707+
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
708+
709+
String value = (String)processor.readWithMessageConverters(this.request, methodParameter,
710+
methodParameter.getGenericParameterType());
711+
assertEquals("foo", value);
712+
}
713+
695714
private void assertContentDisposition(RequestResponseBodyMethodProcessor processor,
696715
boolean expectContentDisposition, String requestURI, String comment) throws Exception {
697716

@@ -1011,4 +1030,13 @@ public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodPa
10111030
}
10121031
}
10131032

1033+
interface MappingInterface<A> {
1034+
default A handle(@RequestBody A arg) {
1035+
return arg;
1036+
}
1037+
}
1038+
1039+
static class MyControllerImplementingInterface implements MappingInterface<String> {
1040+
}
1041+
10141042
}

0 commit comments

Comments
 (0)