You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2019/08/13 17:43:49 UTC

[johnzon] branch master updated: JOHNZON-249 ensure constructor visibility is validated

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

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git


The following commit(s) were added to refs/heads/master by this push:
     new 99f8de1  JOHNZON-249 ensure constructor visibility is validated
99f8de1 is described below

commit 99f8de1aad688a7983eb2b11dea6b15898feece5
Author: Romain Manni-Bucau <rm...@apache.org>
AuthorDate: Tue Aug 13 19:43:43 2019 +0200

    JOHNZON-249 ensure constructor visibility is validated
---
 .../org/apache/johnzon/jsonb/JsonbAccessMode.java  | 18 +++++++--
 .../java/org/apache/johnzon/jsonb/AdapterTest.java |  2 +-
 .../johnzon/jsonb/ConstructorVisibilityTest.java   | 43 ++++++++++++++++++++++
 .../apache/johnzon/jsonb/DefaultMappingTest.java   | 22 +++++------
 .../apache/johnzon/mapper/MappingParserImpl.java   |  2 +-
 5 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
index d9e3e5e..6cf08cf 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
@@ -179,6 +179,7 @@ public class JsonbAccessMode implements AccessMode, Closeable {
     public Factory findFactory(final Class<?> clazz) {
         Constructor<?> constructor = null;
         Method factory = null;
+        boolean invalidConstructorForDeserialization = false;
         for (final Constructor<?> c : clazz.getConstructors()) {
             if (c.isAnnotationPresent(JsonbCreator.class)) {
                 if (constructor != null) {
@@ -196,6 +197,10 @@ public class JsonbAccessMode implements AccessMode, Closeable {
                 factory = m;
             }
         }
+        if (constructor == null && factory == null) {
+            invalidConstructorForDeserialization = Stream.of(clazz.getDeclaredConstructors())
+                    .anyMatch(it -> it.getParameterCount() == 0 && !Modifier.isPublic(it.getModifiers()));
+        }
         final Constructor<?> finalConstructor = constructor;
         final Method finalFactory = factory;
         final Consumer<Object[]> factoryValidator = failOnMissingCreatorValues ?
@@ -261,10 +266,15 @@ public class JsonbAccessMode implements AccessMode, Closeable {
             objectConverters = null;
         }
 
-        return constructor == null && factory == null ? delegate.findFactory(clazz) : (
-                constructor != null ?
-                        constructorFactory(finalConstructor, factoryValidator, types, params, converters, itemConverters, objectConverters) :
-                        methodFactory(clazz, finalFactory, factoryValidator, types, params, converters, itemConverters, objectConverters));
+        if (constructor == null && factory == null && !invalidConstructorForDeserialization) {
+            return delegate.findFactory(clazz);
+        }
+        if (constructor != null || invalidConstructorForDeserialization) {
+            return constructorFactory(finalConstructor, invalidConstructorForDeserialization ? (Consumer<Object[]>) objects -> {
+                throw new JsonbException("No available constructor");
+            } : factoryValidator, types, params, converters, itemConverters, objectConverters);
+        }
+        return methodFactory(clazz, finalFactory, factoryValidator, types, params, converters, itemConverters, objectConverters);
     }
 
     private Factory methodFactory(final Class<?> clazz, final Method finalFactory,
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
index d09becc..8e12cbd 100644
--- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
@@ -239,7 +239,7 @@ public class AdapterTest {
                 doorDTO.status);
     }
 
-    static class DoorDTO {
+    public static class DoorDTO {
         @JsonbTypeAdapter(StatusAdapter.class)
         public DoorStatus status;
     }
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java
new file mode 100644
index 0000000..0b0949c
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.jsonb;
+
+import javax.json.bind.JsonbException;
+
+import org.apache.johnzon.jsonb.test.JsonbRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ConstructorVisibilityTest {
+    @Rule
+    public final JsonbRule jsonb = new JsonbRule();
+
+    @Test(expected = JsonbException.class)
+    public void packageConstructor() {
+        jsonb.fromJson("{}", PackageCons.class);
+    }
+
+    public static class PackageCons {
+        public String value;
+
+        PackageCons() {
+            // no-op
+        }
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
index da59137..33c9fd6 100644
--- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DefaultMappingTest.java
@@ -730,7 +730,7 @@ public class DefaultMappingTest {
         }
     }
 
-    private static class POJO {
+    public static class POJO {
         private Integer id;
         private String name;
 
@@ -756,7 +756,7 @@ public class DefaultMappingTest {
         //other supported attributes
     }
 
-    private static class POJOWithNestedClass {
+    public static class POJOWithNestedClass {
         private Integer id;
         private String name;
         private NestedClass nestedClass;
@@ -815,7 +815,7 @@ public class DefaultMappingTest {
         }
     }
 
-    private static class POJOWithStaticNestedClass {
+    public static class POJOWithStaticNestedClass {
         private Integer id;
         private String name;
 
@@ -865,7 +865,7 @@ public class DefaultMappingTest {
         }
     }
 
-    private static class POJOWithMixedFieldAccess {
+    public static class POJOWithMixedFieldAccess {
         public Integer id = 1;
         public String name = "pojoName";
         public Boolean active = false;
@@ -1190,7 +1190,7 @@ public class DefaultMappingTest {
         assertNull(accessorsClass.protectedField);
     }
 
-    static class AccessorsClass {
+    public static class AccessorsClass {
         private Integer privateField;
 
         protected Integer protectedField;
@@ -1230,14 +1230,14 @@ public class DefaultMappingTest {
         }
     }
 
-    static class OptionalClass {
+    public static class OptionalClass {
         public Optional<String> optionalField = Optional.empty();
 
         public OptionalClass() {
         }
     }
 
-    static class ModifiersClass {
+    public static class ModifiersClass {
         public final String finalField = "finalValue";
         public static String staticField = "staticValue";
         public transient String transientField = "transientValue";
@@ -1247,7 +1247,7 @@ public class DefaultMappingTest {
         }
     }
 
-    static class POJOWithInitialValue {
+    public static class POJOWithInitialValue {
         public Integer id = 4;
         public String name;
 
@@ -1255,7 +1255,7 @@ public class DefaultMappingTest {
         }
     }
 
-    static class AttributesOrderingClass {
+    public static class AttributesOrderingClass {
         public String aField;
         public String cField;
         public String bField;
@@ -1264,7 +1264,7 @@ public class DefaultMappingTest {
         }
     }
 
-    static class AttributesOrderingWithInheritance extends AttributesOrderingClass {
+    public static class AttributesOrderingWithInheritance extends AttributesOrderingClass {
         public String aa;
         public String cc;
         public String bb;
@@ -1273,7 +1273,7 @@ public class DefaultMappingTest {
         }
     }
 
-    static class AttributesOrderingWithCounterClass {
+    public static class AttributesOrderingWithCounterClass {
         private transient int counter = 0;
 
         private String first = "first";
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index 6f79b01..c259756 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -329,7 +329,7 @@ public class MappingParserImpl implements MappingParser {
         }
 
         Object t;
-        if (classMapping.factory.getParameterTypes().length == 0) {
+        if (classMapping.factory.getParameterTypes() == null || classMapping.factory.getParameterTypes().length == 0) {
             t = classMapping.factory.create(null);
         } else {
             t = classMapping.factory.create(createParameters(classMapping, object, jsonPointer));