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

nkollar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/main by this push:
     new 90a937f28f Remove the default serializable packages and deprecated the 
property to introduce org.apache.avro.SERIALIZABLE_CLASSES instead (#3376)
90a937f28f is described below

commit 90a937f28fac3e583d7efae1e59aacbf6f246d30
Author: JB Onofré <[email protected]>
AuthorDate: Mon May 19 21:07:24 2025 +0200

    Remove the default serializable packages and deprecated the property to 
introduce org.apache.avro.SERIALIZABLE_CLASSES instead (#3376)
---
 lang/java/avro/pom.xml                             |  3 ++
 .../apache/avro/specific/SpecificDatumReader.java  | 62 ++++++++++++++++------
 .../java/org/apache/avro/reflect/TestReflect.java  |  1 +
 lang/java/ipc/pom.xml                              |  3 ++
 4 files changed, 53 insertions(+), 16 deletions(-)

diff --git a/lang/java/avro/pom.xml b/lang/java/avro/pom.xml
index e776c66557..b74bef66fa 100644
--- a/lang/java/avro/pom.xml
+++ b/lang/java/avro/pom.xml
@@ -90,6 +90,9 @@
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
           <parallel>none</parallel>
+          <systemProperties>
+            
<org.apache.avro.SERIALIZABLE_CLASSES>java.math.BigDecimal,java.math.BigInteger,java.net.URI,java.net.URL,java.io.File,java.lang.Integer,org.apache.avro.reflect.TestReflect$R10</org.apache.avro.SERIALIZABLE_CLASSES>
+          </systemProperties>
         </configuration>
         <executions>
           <execution>
diff --git 
a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificDatumReader.java
 
b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificDatumReader.java
index 29c8ac6656..48d4420e75 100644
--- 
a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificDatumReader.java
+++ 
b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificDatumReader.java
@@ -23,10 +23,13 @@ import org.apache.avro.AvroRuntimeException;
 import org.apache.avro.generic.GenericDatumReader;
 import org.apache.avro.io.ResolvingDecoder;
 import org.apache.avro.util.ClassUtils;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * {@link org.apache.avro.io.DatumReader DatumReader} for generated Java
@@ -34,14 +37,31 @@ import java.util.List;
  */
 public class SpecificDatumReader<T> extends GenericDatumReader<T> {
 
+  /**
+   * @deprecated prefer to use SERIALIZABLE_CLASSES instead.
+   */
+  @Deprecated
   public static final String[] SERIALIZABLE_PACKAGES;
 
+  public static final String[] SERIALIZABLE_CLASSES;
+
   static {
-    SERIALIZABLE_PACKAGES = 
System.getProperty("org.apache.avro.SERIALIZABLE_PACKAGES",
-        
"java.lang,java.math,java.io,java.net,org.apache.avro.reflect").split(",");
+    // no serializable classes by default
+    String serializableClassesProp = 
System.getProperty("org.apache.avro.SERIALIZABLE_CLASSES");
+    SERIALIZABLE_CLASSES = (serializableClassesProp == null) ? new String[0] : 
serializableClassesProp.split(",");
+
+    // no serializable packages by default
+    String serializablePackagesProp = 
System.getProperty("org.apache.avro.SERIALIZABLE_PACKAGES");
+    SERIALIZABLE_PACKAGES = (serializablePackagesProp == null) ? new String[0] 
: serializablePackagesProp.split(",");
   }
 
+  // The primitive "class names" based on Class.isPrimitive()
+  private static final Set<String> PRIMITIVES = new 
HashSet<>(Arrays.asList(Boolean.TYPE.getName(),
+      Character.TYPE.getName(), Byte.TYPE.getName(), Short.TYPE.getName(), 
Integer.TYPE.getName(), Long.TYPE.getName(),
+      Float.TYPE.getName(), Double.TYPE.getName(), Void.TYPE.getName()));
+
   private final List<String> trustedPackages = new ArrayList<>();
+  private final List<String> trustedClasses = new ArrayList<>();
 
   public SpecificDatumReader() {
     this(null, null, SpecificData.get());
@@ -69,12 +89,14 @@ public class SpecificDatumReader<T> extends 
GenericDatumReader<T> {
   public SpecificDatumReader(Schema writer, Schema reader, SpecificData data) {
     super(writer, reader, data);
     trustedPackages.addAll(Arrays.asList(SERIALIZABLE_PACKAGES));
+    trustedClasses.addAll(Arrays.asList(SERIALIZABLE_CLASSES));
   }
 
   /** Construct given a {@link SpecificData}. */
   public SpecificDatumReader(SpecificData data) {
     super(data);
     trustedPackages.addAll(Arrays.asList(SERIALIZABLE_PACKAGES));
+    trustedClasses.addAll(Arrays.asList(SERIALIZABLE_CLASSES));
   }
 
   /** Return the contained {@link SpecificData}. */
@@ -116,8 +138,8 @@ public class SpecificDatumReader<T> extends 
GenericDatumReader<T> {
     if (name == null)
       return null;
     try {
+      checkSecurity(name);
       Class clazz = ClassUtils.forName(getData().getClassLoader(), name);
-      checkSecurity(clazz);
       return clazz;
     } catch (ClassNotFoundException e) {
       throw new AvroRuntimeException(e);
@@ -128,31 +150,39 @@ public class SpecificDatumReader<T> extends 
GenericDatumReader<T> {
     return (trustedPackages.size() == 1 && "*".equals(trustedPackages.get(0)));
   }
 
-  private void checkSecurity(Class clazz) throws ClassNotFoundException {
-    if (trustAllPackages() || clazz.isPrimitive()) {
+  private void checkSecurity(String className) throws ClassNotFoundException {
+    if (trustAllPackages() || PRIMITIVES.contains(className)) {
       return;
     }
 
-    boolean found = false;
-    Package thePackage = clazz.getPackage();
-    if (thePackage != null) {
-      for (String trustedPackage : getTrustedPackages()) {
-        if (thePackage.getName().equals(trustedPackage) || 
thePackage.getName().startsWith(trustedPackage + ".")) {
-          found = true;
-          break;
-        }
+    for (String trustedClass : getTrustedClasses()) {
+      if (className.equals(trustedClass)) {
+        return;
       }
     }
-    if (!found) {
-      throw new SecurityException("Forbidden " + clazz
-          + "! This class is not trusted to be included in Avro schema using 
java-class. Please set org.apache.avro.SERIALIZABLE_PACKAGES system property 
with the packages you trust.");
+
+    for (String trustedPackage : getTrustedPackages()) {
+      if (className.startsWith(trustedPackage)) {
+        return;
+      }
     }
+
+    throw new SecurityException("Forbidden " + className
+        + "! This class is not trusted to be included in Avro schema using 
java-class. Please set org.apache.avro.SERIALIZABLE_CLASSES system property 
with the class you trust or org.apache.avro.SERIALIZABLE_PACKAGES system 
property with the packages you trust.");
   }
 
+  /**
+   * @deprecated Use getTrustedClasses() instead
+   */
+  @Deprecated
   public final List<String> getTrustedPackages() {
     return trustedPackages;
   }
 
+  public final List<String> getTrustedClasses() {
+    return trustedClasses;
+  }
+
   @Override
   protected Object readRecord(Object old, Schema expected, ResolvingDecoder 
in) throws IOException {
     SpecificData data = getSpecificData();
diff --git 
a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java 
b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
index 50121b5a0d..08e186268c 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java
@@ -615,6 +615,7 @@ public class TestReflect {
   }
 
   void checkReadWrite(Object object, Schema s) throws Exception {
+
     ReflectDatumWriter<Object> writer = new ReflectDatumWriter<>(s);
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     writer.write(object, factory.directBinaryEncoder(out, null));
diff --git a/lang/java/ipc/pom.xml b/lang/java/ipc/pom.xml
index a12798488b..5d18931d8e 100644
--- a/lang/java/ipc/pom.xml
+++ b/lang/java/ipc/pom.xml
@@ -62,6 +62,9 @@
           <forkCount>1</forkCount>
           <reuseForks>false</reuseForks>
            <parallel>none</parallel>
+          <systemProperties>
+            
<org.apache.avro.SERIALIZABLE_CLASSES>java.math.BigDecimal,java.math.BigInteger</org.apache.avro.SERIALIZABLE_CLASSES>
+          </systemProperties>
         </configuration>
       </plugin>
       <plugin>

Reply via email to