From c35e17b038da2b99c1f6b40721c973ec976b4eff Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Mon, 22 Jun 2026 17:43:17 +0800 Subject: [PATCH] Refactor NumberToDataSizeConverter to use DataSize.ofBytes(long) directly Prior to this commit, a `Number` was converted to a `String` and then the string was parsed/matched using regular expressions back into a suitable `long` which was inefficient and also prevented valid data size values such as 10.0. To address those issues, this commit refactors NumberToDataSizeConverter to use DataSize.ofBytes(long) directly, first checking that the supplied Number does not have a fractional part. Closes gh-36956 Signed-off-by: Yanming Zhou --- .../core/convert/support/NumberToDataSizeConverter.java | 9 +++++++-- .../convert/converter/DefaultConversionServiceTests.java | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java index a0a6145efde..0231b64f1a0 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java @@ -23,15 +23,20 @@ import org.springframework.util.unit.DataSize; * Converts from a {@link Number} to a {@link DataSize}. * * @author YeongJae Min + * @author Yanming Zhou * @since 7.1 - * @see DataSize#parse(CharSequence) + * @see DataSize#ofBytes(long) * @see StringToDataSizeConverter */ final class NumberToDataSizeConverter implements Converter { @Override public DataSize convert(Number source) { - return DataSize.parse(source.toString()); + long bytes = source.longValue(); + if (source.doubleValue() - bytes != 0) { + throw new IllegalArgumentException("'" + source + "' is not a valid data size"); + } + return DataSize.ofBytes(bytes); } } diff --git a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java index 51202425e41..b6378d187d7 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java @@ -76,6 +76,8 @@ import static org.assertj.core.api.Assertions.entry; * @author Juergen Hoeller * @author Stephane Nicoll * @author Sam Brannen + * @author YeongJae Min + * @author Yanming Zhou */ class DefaultConversionServiceTests { @@ -258,12 +260,16 @@ class DefaultConversionServiceTests { void numberToDataSizeWithDecimalNumber() { assertThatExceptionOfType(ConversionFailedException.class) .isThrownBy(() -> conversionService.convert(10.5, DataSize.class)); + assertThatExceptionOfType(ConversionFailedException.class) + .isThrownBy(() -> conversionService.convert(new BigDecimal("10.5"), DataSize.class)); } @Test // gh-36830 void numberToDataSize() { assertThat(conversionService.convert(10, DataSize.class)).isEqualTo(DataSize.ofBytes(10)); assertThat(conversionService.convert(-10L, DataSize.class)).isEqualTo(DataSize.ofBytes(-10)); + assertThat(conversionService.convert(new BigDecimal("10"), DataSize.class)).isEqualTo(DataSize.ofBytes(10)); + assertThat(conversionService.convert(new BigDecimal("10.0"), DataSize.class)).isEqualTo(DataSize.ofBytes(10)); } @Test