From 31331e6ad31fb51e26ce926dfa8f1e06a15af608 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 30 Oct 2012 11:25:10 -0700 Subject: [PATCH] Avoid NPE in ObjectToObjectConverter Bypass ObjectToObject conversion when source and object types are identical and protect against a null source object. Prior to this commit the TypeDescriptor was used to determine if conversion was necessary. This caused issues when comparing a descriptor with annotations to one without. The updated code now compares using TypeDescriptor.getType(). The ObjectToObject converter will now no longer attempt to convert null source objects. Issue: SPR-9933 --- .../support/ObjectToObjectConverter.java | 9 ++++++++- .../support/GenericConversionServiceTests.java | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java index 59921bbe35..163fffe3e9 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java @@ -48,10 +48,17 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter { } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { - return !sourceType.equals(targetType) && hasValueOfMethodOrConstructor(targetType.getType(), sourceType.getType()); + if (sourceType.getType().equals(targetType.getType())) { + // no conversion required + return false; + } + return hasValueOfMethodOrConstructor(targetType.getType(), sourceType.getType()); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (source == null) { + return null; + } Class sourceClass = sourceType.getType(); Class targetClass = targetType.getType(); Method method = getValueOfMethodOn(targetClass, sourceClass); diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java index f312f2d71a..fc2af6d87d 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java @@ -18,6 +18,8 @@ package org.springframework.core.convert.support; import java.awt.Color; import java.awt.SystemColor; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -744,6 +746,22 @@ public class GenericConversionServiceTests { assertEquals("1", result); } + @Test + public void convertNullAnnotatedStringToString() throws Exception { + DefaultConversionService.addDefaultConverters(conversionService); + String source = null; + TypeDescriptor sourceType = new TypeDescriptor(getClass().getField("annotatedString")); + TypeDescriptor targetType = TypeDescriptor.valueOf(String.class); + conversionService.convert(source, sourceType, targetType); + } + + @ExampleAnnotation + public String annotatedString; + + @Retention(RetentionPolicy.RUNTIME) + public static @interface ExampleAnnotation { + } + private static class MyConditionalConverter implements Converter, ConditionalConverter { -- GitLab