You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by jl...@apache.org on 2023/05/22 09:06:44 UTC

[johnzon] 02/11: fix(JOHNZON-397): Create configuration option to set the BigDecimal scale limit

This is an automated email from the ASF dual-hosted git repository.

jlmonteiro pushed a commit to branch johnzon-1.2.x
in repository https://gitbox.apache.org/repos/asf/johnzon.git

commit 164605799273a56d7ffcefc12d49e0913952d734
Author: Jean-Louis Monteiro <jl...@tomitribe.com>
AuthorDate: Thu May 11 11:12:44 2023 +0200

    fix(JOHNZON-397): Create configuration option to set the BigDecimal scale limit
    
    Signed-off-by: Jean-Louis Monteiro <jl...@tomitribe.com>
---
 .../src/main/java/org/apache/johnzon/core/JsonNumberImpl.java |  6 +++---
 .../src/test/java/org/apache/johnzon/core/JsonNumberTest.java |  2 +-
 .../main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java    |  9 ++++++++-
 .../main/java/org/apache/johnzon/mapper/MapperBuilder.java    |  8 +++++++-
 .../src/main/java/org/apache/johnzon/mapper/MapperConfig.java | 11 +++++++++--
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
index e5891cf3..4609aceb 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
@@ -69,13 +69,13 @@ final class JsonNumberImpl implements JsonNumber, Serializable {
 
     @Override
     public BigInteger bigIntegerValue() {
-        checkBigIntegerScale();
+        checkBigDecimalScale();
         return value.toBigInteger();
     }
 
     @Override
     public BigInteger bigIntegerValueExact() {
-        checkBigIntegerScale();
+        checkBigDecimalScale();
         return value.toBigIntegerExact();
     }
 
@@ -120,7 +120,7 @@ final class JsonNumberImpl implements JsonNumber, Serializable {
         }
     }
 
-    private void checkBigIntegerScale() {
+    private void checkBigDecimalScale() {
         // should be fine enough. Maybe we should externalize so users can pick something better if they need to
         // it becomes their responsibility to fix the limit and may expose them to a DoS attack
         final int limit = 1_000;
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java
index 57bbd560..f77773b6 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java
@@ -100,7 +100,7 @@ public class JsonNumberTest {
             long start = System.nanoTime();
             for (int i = 1; i < 100; i++) {
                 // if it takes a second in any machine, that's already too much
-                // depends on the allowed scale in JsonNumberImpl#checkBigIntegerScale
+                // depends on the allowed scale in JsonNumberImpl#checkBigDecimalScale
                 if (TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) > (30 * i)) {
                     fail("took too long: " + TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) + " s" +
                          " to compute " + i + " conversions toBigInteger");
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index 400dfcfa..46f99177 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -108,7 +108,10 @@ public class JohnzonBuilder implements JsonbBuilder {
 
         // todo: global spec toggle to disable all these ones at once?
         builder.setUseBigDecimalForObjectNumbers(
-                config.getProperty("johnzon.use-big-decimal-for-object").map(this::toBool).orElse(true));
+            config.getProperty("johnzon.use-big-decimal-for-object").map(this::toBool).orElse(true));
+        builder.setMaxBigDecimalScale(
+            config.getProperty("johnzon.max-big-decimal-scale").map(this::toInt).orElse(1000));
+
         builder.setSupportEnumContainerDeserialization( // https://github.com/eclipse-ee4j/jakartaee-tck/issues/103
                 toBool(System.getProperty("johnzon.support-enum-container-deserialization", config.getProperty("johnzon.support-enum-container-deserialization")
                         .map(String::valueOf).orElse("true"))));
@@ -361,6 +364,10 @@ public class JohnzonBuilder implements JsonbBuilder {
         return !Boolean.class.isInstance(v) ? Boolean.parseBoolean(v.toString()) : Boolean.class.cast(v);
     }
 
+    private Integer toInt(final Object v) {
+        return !Integer.class.isInstance(v) ? Integer.parseInt(v.toString()) : Integer.class.cast(v);
+    }
+
     private AccessMode toAccessMode(final Object s) {
         if (String.class.isInstance(s)) {
             try {
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
index ef4ca516..013742cb 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
@@ -104,6 +104,7 @@ public class MapperBuilder {
     private Boolean deduplicateObjects = null;
     private boolean useJsRange;
     private boolean useBigDecimalForObjectNumbers;
+    private int maxBigDecimalScale = 1000;
     private boolean supportEnumContainerDeserialization = true;
     private Function<Class<?>, MapperConfig.CustomEnumConverter<?>> enumConverterFactory = type -> new EnumConverter(type);
     private boolean skipAccessModeWrapper;
@@ -233,7 +234,7 @@ public class MapperBuilder {
                         treatByteArrayAsBase64, treatByteArrayAsBase64URL, readAttributeBeforeWrite,
                         accessMode, encoding, attributeOrder, failOnUnknownProperties,
                         serializeValueFilter, useBigDecimalForFloats, deduplicateObjects,
-                        interfaceImplementationMapping, useJsRange, useBigDecimalForObjectNumbers,
+                        interfaceImplementationMapping, useJsRange, useBigDecimalForObjectNumbers, maxBigDecimalScale,
                         supportEnumContainerDeserialization,
                         typeLoader, discriminatorMapper, discriminator,
                         deserializationPredicate, serializationPredicate,
@@ -530,6 +531,11 @@ public class MapperBuilder {
         return this;
     }
 
+    public MapperBuilder setMaxBigDecimalScale(final int maxBigDecimalScale) {
+        this.maxBigDecimalScale = maxBigDecimalScale;
+        return this;
+    }
+
     public MapperBuilder setSupportEnumContainerDeserialization(final boolean supportEnumContainerDeserialization) {
         this.supportEnumContainerDeserialization = supportEnumContainerDeserialization;
         return this;
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java
index 1bc01752..813e61c6 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java
@@ -81,7 +81,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
     private final Boolean deduplicateObjects;
     private final Map<Class<?>, Class<?>> interfaceImplementationMapping;
     private final boolean useBigDecimalForObjectNumbers;
-
+    private int maxBigDecimalScale;
     private final Function<String, Class<?>> typeLoader;
     private final Function<Class<?>, String> discriminatorMapper;
     private final Predicate<Class<?>> serializationPredicate;
@@ -116,6 +116,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
                         final Map<Class<?>, Class<?>> interfaceImplementationMapping,
                         final boolean useJsRange,
                         final boolean useBigDecimalForObjectNumbers,
+                        final int maxBigDecimalScale,
                         final boolean supportEnumMapDeserialization,
                         final Function<String, Class<?>> typeLoader,
                         final Function<Class<?>, String> discriminatorMapper,
@@ -127,7 +128,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
         this(adapters, objectConverterWriters, objectConverterReaders, version, close, skipNull, skipEmptyArray,
                 treatByteArrayAsBase64, treatByteArrayAsBase64URL, readAttributeBeforeWrite, accessMode, encoding,
                 attributeOrder, failOnUnknown, serializeValueFilter, useBigDecimalForFloats, deduplicateObjects, interfaceImplementationMapping,
-                useJsRange, useBigDecimalForObjectNumbers, supportEnumMapDeserialization, typeLoader,
+                useJsRange, useBigDecimalForObjectNumbers, maxBigDecimalScale, supportEnumMapDeserialization, typeLoader,
                 discriminatorMapper, discriminator, deserializationPredicate, serializationPredicate, enumConverterFactory,
                 JohnzonCores.snippetFactory(50, Json.createGeneratorFactory(emptyMap())));
     }
@@ -150,6 +151,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
                         final Map<Class<?>, Class<?>> interfaceImplementationMapping,
                         final boolean useJsRange,
                         final boolean useBigDecimalForObjectNumbers,
+                        final int maxBigDecimalScale,
                         final boolean supportEnumMapDeserialization,
                         final Function<String, Class<?>> typeLoader,
                         final Function<Class<?>, String> discriminatorMapper,
@@ -172,6 +174,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
         this.encoding = encoding;
         this.useJsRange = useJsRange;
         this.useBigDecimalForObjectNumbers = useBigDecimalForObjectNumbers;
+        this.maxBigDecimalScale = maxBigDecimalScale;
         this.supportEnumMapDeserialization = supportEnumMapDeserialization;
         this.typeLoader = typeLoader;
         this.discriminatorMapper = discriminatorMapper;
@@ -238,6 +241,10 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
         return useBigDecimalForObjectNumbers;
     }
 
+    public int getMaxBigDecimalScale() {
+        return maxBigDecimalScale;
+    }
+
     public boolean isUseJsRange() {
         return useJsRange;
     }