From a265f150acf0846ccecccd382ebc0adb190174b3 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 1 Mar 2022 17:38:19 +0000 Subject: [PATCH] Improve parsing of numeric default values Previously, all integral numbers were parsed as integers. This caused two problems: 1. Compilation would fail if the default value for a long wasn't a valid integer. 2. The default value for a byte or short could be out of range, resulting in the generation of invalid metadata and an error that could have been caught at compile time not being caught until runtime. This commit updates the parsing of all numeric values to use the parse method of the target primitive type. For example, Short.parseShort(String) is now used to parse a short. Fixes gh-30020 --- ...onstructorParameterPropertyDescriptor.java | 38 ++++++++----------- ...uctorParameterPropertyDescriptorTests.java | 29 ++++++++------ 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConstructorParameterPropertyDescriptor.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConstructorParameterPropertyDescriptor.java index d2fdc0787d..dfc6f00653 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConstructorParameterPropertyDescriptor.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConstructorParameterPropertyDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 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. @@ -18,6 +18,7 @@ package org.springframework.boot.configurationprocessor; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; import javax.lang.model.element.AnnotationMirror; @@ -106,21 +107,14 @@ class ConstructorParameterPropertyDescriptor extends PropertyDescriptor T parseNumber(String value, Function parser, + PrimitiveType primitiveType) { try { - return Integer.valueOf(value); + return parser.apply(value); } catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Invalid number representation '%s'", value)); - } - } - - private Double parseFloatingPoint(String value) { - try { - return Double.valueOf(value); - } - catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Invalid floating point representation '%s'", value)); + throw new IllegalArgumentException( + String.format("Invalid %s representation '%s'", primitiveType, value)); } } @@ -131,22 +125,22 @@ class ConstructorParameterPropertyDescriptor extends PropertyDescriptor { TypeElement ownerElement = roundEnv.getRootElement(ImmutablePrimitiveProperties.class); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "flag")).hasDefaultValue(false); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "octet")).hasDefaultValue(0); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "octet")).hasDefaultValue((byte) 0); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "letter")).hasDefaultValue(null); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "number")).hasDefaultValue(0); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "number")) + .hasDefaultValue((short) 0); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "counter")).hasDefaultValue(0); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "value")).hasDefaultValue(0L); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "percentage")).hasDefaultValue(0); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "percentage")).hasDefaultValue(0F); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "ratio")).hasDefaultValue(0D); }); } @@ -170,12 +171,14 @@ class ConstructorParameterPropertyDescriptorTests extends PropertyDescriptorTest process(ImmutablePrimitiveWithDefaultsProperties.class, (roundEnv, metadataEnv) -> { TypeElement ownerElement = roundEnv.getRootElement(ImmutablePrimitiveWithDefaultsProperties.class); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "flag")).hasDefaultValue(true); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "octet")).hasDefaultValue(120); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "octet")) + .hasDefaultValue((byte) 120); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "letter")).hasDefaultValue("a"); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "number")).hasDefaultValue(1000); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "number")) + .hasDefaultValue((short) 1000); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "counter")).hasDefaultValue(42); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "value")).hasDefaultValue(2000); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "percentage")).hasDefaultValue(0.5); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "value")).hasDefaultValue(2000L); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "percentage")).hasDefaultValue(0.5F); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "ratio")).hasDefaultValue(42.42); }); } @@ -185,12 +188,14 @@ class ConstructorParameterPropertyDescriptorTests extends PropertyDescriptorTest process(ImmutablePrimitiveWrapperWithDefaultsProperties.class, (roundEnv, metadataEnv) -> { TypeElement ownerElement = roundEnv.getRootElement(ImmutablePrimitiveWrapperWithDefaultsProperties.class); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "flag")).hasDefaultValue(true); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "octet")).hasDefaultValue(120); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "octet")) + .hasDefaultValue((byte) 120); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "letter")).hasDefaultValue("a"); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "number")).hasDefaultValue(1000); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "number")) + .hasDefaultValue((short) 1000); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "counter")).hasDefaultValue(42); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "value")).hasDefaultValue(2000); - assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "percentage")).hasDefaultValue(0.5); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "value")).hasDefaultValue(2000L); + assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "percentage")).hasDefaultValue(0.5F); assertItemMetadata(metadataEnv, createPropertyDescriptor(ownerElement, "ratio")).hasDefaultValue(42.42); }); }