From 7c5050cf804fe2b0f391fe48c691ffc7b3c7cdd0 Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Thu, 4 Aug 2016 11:11:15 -0700 Subject: [PATCH] Prevent StackOverflowError in AbstractJackson2HttpMessageConverter Issue: SPR-14520 --- .../AbstractJackson2HttpMessageConverter.java | 10 +++++-- ...questResponseBodyMethodProcessorTests.java | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index 2d3dd80e2f2..f3942f68f4f 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -356,9 +356,13 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener return resolvedType; } } - resolvedType = resolveVariable(typeVariable, contextType.getSuperType()); - if (resolvedType.resolve() != null) { - return resolvedType; + + ResolvableType superType = contextType.getSuperType(); + if (superType != ResolvableType.NONE) { + resolvedType = resolveVariable(typeVariable, superType); + if (resolvedType.resolve() != null) { + return resolvedType; + } } for (ResolvableType ifc : contextType.getInterfaces()) { resolvedType = resolveVariable(typeVariable, ifc); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java index 2d7d789a83e..8151822b966 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java @@ -692,6 +692,25 @@ public class RequestResponseBodyMethodProcessorTests { assertEquals("UTF-8", this.servletResponse.getCharacterEncoding()); } + @Test // SPR-14520 + public void resolveArgumentTypeVariableWithGenericInterface() throws Exception { + this.servletRequest.setContent("\"foo\"".getBytes("UTF-8")); + this.servletRequest.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + + Method method = MyControllerImplementingInterface.class.getMethod("handle", Object.class); + HandlerMethod handlerMethod = new HandlerMethod(new MyControllerImplementingInterface(), method); + MethodParameter methodParameter = handlerMethod.getMethodParameters()[0]; + + List> converters = new ArrayList<>(); + converters.add(new MappingJackson2HttpMessageConverter()); + + RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); + + String value = (String)processor.readWithMessageConverters(this.request, methodParameter, + methodParameter.getGenericParameterType()); + assertEquals("foo", value); + } + private void assertContentDisposition(RequestResponseBodyMethodProcessor processor, boolean expectContentDisposition, String requestURI, String comment) throws Exception { @@ -1011,4 +1030,13 @@ public class RequestResponseBodyMethodProcessorTests { } } + interface MappingInterface { + default A handle(@RequestBody A arg) { + return arg; + } + } + + static class MyControllerImplementingInterface implements MappingInterface { + } + }