From 3f6468e701193c12ae9723699781eece3e3085e6 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Wed, 11 Mar 2026 15:00:23 -0700 Subject: [PATCH 1/3] Fix NPE in DoubleAttributeConverter and FloatAttributeConverter for null input --- .../bugfix-AmazonDynamoDBEnhancedClient-192189d.json | 6 ++++++ .../converter/attribute/DoubleAttributeConverter.java | 4 ++++ .../converter/attribute/FloatAttributeConverter.java | 4 ++++ .../converters/attribute/NumberAttributeConvertersTest.java | 4 ++++ 4 files changed, 18 insertions(+) create mode 100644 .changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json diff --git a/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json b/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json new file mode 100644 index 000000000000..b954147af3bf --- /dev/null +++ b/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "Amazon DynamoDB Enhanced Client", + "contributor": "", + "description": "Fix NullPointerException in `DoubleAttributeConverter` and `FloatAttributeConverter` when input is null." +} diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java index 4eb2b2d91682..34f4b2639dcf 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java @@ -21,6 +21,7 @@ import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter; import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType; import software.amazon.awssdk.enhanced.dynamodb.EnhancedType; +import software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.ConverterUtils; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.PrimitiveConverter; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor; @@ -71,6 +72,9 @@ public AttributeValueType attributeValueType() { @Override public AttributeValue transformFrom(Double input) { + if (input == null) { + return AttributeValues.nullAttributeValue(); + } ConverterUtils.validateDouble(input); return AttributeValue.builder().n(STRING_CONVERTER.toString(input)).build(); } diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java index ab83f06d2d7f..648dac9e467f 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java @@ -21,6 +21,7 @@ import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter; import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType; import software.amazon.awssdk.enhanced.dynamodb.EnhancedType; +import software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.ConverterUtils; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.PrimitiveConverter; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor; @@ -71,6 +72,9 @@ public AttributeValueType attributeValueType() { @Override public AttributeValue transformFrom(Float input) { + if (input == null) { + return AttributeValues.nullAttributeValue(); + } ConverterUtils.validateFloat(input); return AttributeValue.builder().n(STRING_CONVERTER.toString(input)).build(); } diff --git a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java index bfbbf0ca6081..d151c89689f0 100644 --- a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java +++ b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java @@ -151,6 +151,8 @@ public void floatAttributeConverterBehaves() { assertFails(() -> transformFrom(converter, Float.POSITIVE_INFINITY)); assertFails(() -> transformFrom(converter, Float.NaN)); + assertThat(transformFrom(converter, null).nul()).isTrue(); + assertThat(transformFrom(converter, -Float.MAX_VALUE).n()).isEqualTo("-3.4028235E38"); assertThat(Float.parseFloat(transformFrom(converter, -42.42f).n())).isCloseTo(-42.42f, offset(1E-10f)); assertThat(transformFrom(converter, -Float.MIN_VALUE).n()).isEqualTo("-1.4E-45"); @@ -180,6 +182,8 @@ public void doubleAttributeConverterBehaves() { assertFails(() -> transformFrom(converter, Double.POSITIVE_INFINITY)); assertFails(() -> transformFrom(converter, Double.NaN)); + assertThat(transformFrom(converter, null).nul()).isTrue(); + assertThat(transformFrom(converter, -Double.MAX_VALUE).n()).isEqualTo("-1.7976931348623157E308"); assertThat(Double.parseDouble(transformFrom(converter, -42.42d).n())).isCloseTo(-42.42d, offset(1E-10)); assertThat(transformFrom(converter, -Double.MIN_VALUE).n()).isEqualTo("-4.9E-324"); From 9a1f1e89867497f830a922b87106ec05ef58d8ac Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Wed, 11 Mar 2026 15:02:11 -0700 Subject: [PATCH 2/3] Fix NPE in DoubleAttributeConverter and FloatAttributeConverter for null input --- .../bugfix-AmazonDynamoDBEnhancedClient-192189d.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json b/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json index b954147af3bf..549092a8a4a6 100644 --- a/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json +++ b/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-192189d.json @@ -2,5 +2,5 @@ "type": "bugfix", "category": "Amazon DynamoDB Enhanced Client", "contributor": "", - "description": "Fix NullPointerException in `DoubleAttributeConverter` and `FloatAttributeConverter` when input is null." + "description": "Fix NullPointerException in `DoubleAttributeConverter` and `FloatAttributeConverter` when input is null. Fixes [#6639](https://github.com/aws/aws-sdk-java-v2/issues/6639)." } From 20eed833cef223bbcbe089144fdc049017b83b0a Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Thu, 12 Mar 2026 15:04:17 -0700 Subject: [PATCH 3/3] Add null validation in ConverterUtils.validateDouble/validateFloat to replace auto-unboxing NPE --- .../dynamodb/internal/converter/ConverterUtils.java | 2 ++ .../converter/attribute/DoubleAttributeConverter.java | 4 ---- .../converter/attribute/FloatAttributeConverter.java | 4 ---- .../attribute/NumberAttributeConvertersTest.java | 11 +++++++---- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/ConverterUtils.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/ConverterUtils.java index 0f6f20583187..303a3c703139 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/ConverterUtils.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/ConverterUtils.java @@ -39,6 +39,7 @@ private ConverterUtils() { * @param input */ public static void validateDouble(Double input) { + Validate.paramNotNull(input, "input"); Validate.isTrue(!Double.isNaN(input), "NaN is not supported by the default converters."); Validate.isTrue(Double.isFinite(input), "Infinite numbers are not supported by the default converters."); } @@ -48,6 +49,7 @@ public static void validateDouble(Double input) { * @param input */ public static void validateFloat(Float input) { + Validate.paramNotNull(input, "input"); Validate.isTrue(!Float.isNaN(input), "NaN is not supported by the default converters."); Validate.isTrue(Float.isFinite(input), "Infinite numbers are not supported by the default converters."); } diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java index 34f4b2639dcf..4eb2b2d91682 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/DoubleAttributeConverter.java @@ -21,7 +21,6 @@ import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter; import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType; import software.amazon.awssdk.enhanced.dynamodb.EnhancedType; -import software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.ConverterUtils; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.PrimitiveConverter; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor; @@ -72,9 +71,6 @@ public AttributeValueType attributeValueType() { @Override public AttributeValue transformFrom(Double input) { - if (input == null) { - return AttributeValues.nullAttributeValue(); - } ConverterUtils.validateDouble(input); return AttributeValue.builder().n(STRING_CONVERTER.toString(input)).build(); } diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java index 648dac9e467f..ab83f06d2d7f 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/FloatAttributeConverter.java @@ -21,7 +21,6 @@ import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter; import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType; import software.amazon.awssdk.enhanced.dynamodb.EnhancedType; -import software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.ConverterUtils; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.PrimitiveConverter; import software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor; @@ -72,9 +71,6 @@ public AttributeValueType attributeValueType() { @Override public AttributeValue transformFrom(Float input) { - if (input == null) { - return AttributeValues.nullAttributeValue(); - } ConverterUtils.validateFloat(input); return AttributeValue.builder().n(STRING_CONVERTER.toString(input)).build(); } diff --git a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java index d151c89689f0..172db3591202 100644 --- a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java +++ b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/NumberAttributeConvertersTest.java @@ -16,6 +16,7 @@ package software.amazon.awssdk.enhanced.dynamodb.converters.attribute; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.data.Offset.offset; import static software.amazon.awssdk.enhanced.dynamodb.converters.attribute.ConverterTestUtils.assertFails; import static software.amazon.awssdk.enhanced.dynamodb.converters.attribute.ConverterTestUtils.transformFrom; @@ -150,8 +151,9 @@ public void floatAttributeConverterBehaves() { assertFails(() -> transformFrom(converter, Float.NEGATIVE_INFINITY)); assertFails(() -> transformFrom(converter, Float.POSITIVE_INFINITY)); assertFails(() -> transformFrom(converter, Float.NaN)); - - assertThat(transformFrom(converter, null).nul()).isTrue(); + assertThatThrownBy(() -> transformFrom(converter, null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("input must not be null"); assertThat(transformFrom(converter, -Float.MAX_VALUE).n()).isEqualTo("-3.4028235E38"); assertThat(Float.parseFloat(transformFrom(converter, -42.42f).n())).isCloseTo(-42.42f, offset(1E-10f)); @@ -181,8 +183,9 @@ public void doubleAttributeConverterBehaves() { assertFails(() -> transformFrom(converter, Double.NEGATIVE_INFINITY)); assertFails(() -> transformFrom(converter, Double.POSITIVE_INFINITY)); assertFails(() -> transformFrom(converter, Double.NaN)); - - assertThat(transformFrom(converter, null).nul()).isTrue(); + assertThatThrownBy(() -> transformFrom(converter, null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("input must not be null"); assertThat(transformFrom(converter, -Double.MAX_VALUE).n()).isEqualTo("-1.7976931348623157E308"); assertThat(Double.parseDouble(transformFrom(converter, -42.42d).n())).isCloseTo(-42.42d, offset(1E-10));