Skip to content

Commit 90a937f

Browse files
authored
Remove the default serializable packages and deprecated the property to introduce org.apache.avro.SERIALIZABLE_CLASSES instead (#3376)
1 parent 82a2bc8 commit 90a937f

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

lang/java/avro/pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@
9090
<artifactId>maven-surefire-plugin</artifactId>
9191
<configuration>
9292
<parallel>none</parallel>
93+
<systemProperties>
94+
<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>
95+
</systemProperties>
9396
</configuration>
9497
<executions>
9598
<execution>

lang/java/avro/src/main/java/org/apache/avro/specific/SpecificDatumReader.java

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,45 @@
2323
import org.apache.avro.generic.GenericDatumReader;
2424
import org.apache.avro.io.ResolvingDecoder;
2525
import org.apache.avro.util.ClassUtils;
26+
2627
import java.io.IOException;
2728
import java.util.ArrayList;
2829
import java.util.Arrays;
2930
import java.util.List;
31+
import java.util.HashSet;
32+
import java.util.Set;
3033

3134
/**
3235
* {@link org.apache.avro.io.DatumReader DatumReader} for generated Java
3336
* classes.
3437
*/
3538
public class SpecificDatumReader<T> extends GenericDatumReader<T> {
3639

40+
/**
41+
* @deprecated prefer to use SERIALIZABLE_CLASSES instead.
42+
*/
43+
@Deprecated
3744
public static final String[] SERIALIZABLE_PACKAGES;
3845

46+
public static final String[] SERIALIZABLE_CLASSES;
47+
3948
static {
40-
SERIALIZABLE_PACKAGES = System.getProperty("org.apache.avro.SERIALIZABLE_PACKAGES",
41-
"java.lang,java.math,java.io,java.net,org.apache.avro.reflect").split(",");
49+
// no serializable classes by default
50+
String serializableClassesProp = System.getProperty("org.apache.avro.SERIALIZABLE_CLASSES");
51+
SERIALIZABLE_CLASSES = (serializableClassesProp == null) ? new String[0] : serializableClassesProp.split(",");
52+
53+
// no serializable packages by default
54+
String serializablePackagesProp = System.getProperty("org.apache.avro.SERIALIZABLE_PACKAGES");
55+
SERIALIZABLE_PACKAGES = (serializablePackagesProp == null) ? new String[0] : serializablePackagesProp.split(",");
4256
}
4357

58+
// The primitive "class names" based on Class.isPrimitive()
59+
private static final Set<String> PRIMITIVES = new HashSet<>(Arrays.asList(Boolean.TYPE.getName(),
60+
Character.TYPE.getName(), Byte.TYPE.getName(), Short.TYPE.getName(), Integer.TYPE.getName(), Long.TYPE.getName(),
61+
Float.TYPE.getName(), Double.TYPE.getName(), Void.TYPE.getName()));
62+
4463
private final List<String> trustedPackages = new ArrayList<>();
64+
private final List<String> trustedClasses = new ArrayList<>();
4565

4666
public SpecificDatumReader() {
4767
this(null, null, SpecificData.get());
@@ -69,12 +89,14 @@ public SpecificDatumReader(Schema writer, Schema reader) {
6989
public SpecificDatumReader(Schema writer, Schema reader, SpecificData data) {
7090
super(writer, reader, data);
7191
trustedPackages.addAll(Arrays.asList(SERIALIZABLE_PACKAGES));
92+
trustedClasses.addAll(Arrays.asList(SERIALIZABLE_CLASSES));
7293
}
7394

7495
/** Construct given a {@link SpecificData}. */
7596
public SpecificDatumReader(SpecificData data) {
7697
super(data);
7798
trustedPackages.addAll(Arrays.asList(SERIALIZABLE_PACKAGES));
99+
trustedClasses.addAll(Arrays.asList(SERIALIZABLE_CLASSES));
78100
}
79101

80102
/** Return the contained {@link SpecificData}. */
@@ -116,8 +138,8 @@ private Class getPropAsClass(Schema schema, String prop) {
116138
if (name == null)
117139
return null;
118140
try {
141+
checkSecurity(name);
119142
Class clazz = ClassUtils.forName(getData().getClassLoader(), name);
120-
checkSecurity(clazz);
121143
return clazz;
122144
} catch (ClassNotFoundException e) {
123145
throw new AvroRuntimeException(e);
@@ -128,31 +150,39 @@ private boolean trustAllPackages() {
128150
return (trustedPackages.size() == 1 && "*".equals(trustedPackages.get(0)));
129151
}
130152

131-
private void checkSecurity(Class clazz) throws ClassNotFoundException {
132-
if (trustAllPackages() || clazz.isPrimitive()) {
153+
private void checkSecurity(String className) throws ClassNotFoundException {
154+
if (trustAllPackages() || PRIMITIVES.contains(className)) {
133155
return;
134156
}
135157

136-
boolean found = false;
137-
Package thePackage = clazz.getPackage();
138-
if (thePackage != null) {
139-
for (String trustedPackage : getTrustedPackages()) {
140-
if (thePackage.getName().equals(trustedPackage) || thePackage.getName().startsWith(trustedPackage + ".")) {
141-
found = true;
142-
break;
143-
}
158+
for (String trustedClass : getTrustedClasses()) {
159+
if (className.equals(trustedClass)) {
160+
return;
144161
}
145162
}
146-
if (!found) {
147-
throw new SecurityException("Forbidden " + clazz
148-
+ "! 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.");
163+
164+
for (String trustedPackage : getTrustedPackages()) {
165+
if (className.startsWith(trustedPackage)) {
166+
return;
167+
}
149168
}
169+
170+
throw new SecurityException("Forbidden " + className
171+
+ "! 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.");
150172
}
151173

174+
/**
175+
* @deprecated Use getTrustedClasses() instead
176+
*/
177+
@Deprecated
152178
public final List<String> getTrustedPackages() {
153179
return trustedPackages;
154180
}
155181

182+
public final List<String> getTrustedClasses() {
183+
return trustedClasses;
184+
}
185+
156186
@Override
157187
protected Object readRecord(Object old, Schema expected, ResolvingDecoder in) throws IOException {
158188
SpecificData data = getSpecificData();

lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ void checkReadWrite(Object object) throws Exception {
615615
}
616616

617617
void checkReadWrite(Object object, Schema s) throws Exception {
618+
618619
ReflectDatumWriter<Object> writer = new ReflectDatumWriter<>(s);
619620
ByteArrayOutputStream out = new ByteArrayOutputStream();
620621
writer.write(object, factory.directBinaryEncoder(out, null));

lang/java/ipc/pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
<forkCount>1</forkCount>
6363
<reuseForks>false</reuseForks>
6464
<parallel>none</parallel>
65+
<systemProperties>
66+
<org.apache.avro.SERIALIZABLE_CLASSES>java.math.BigDecimal,java.math.BigInteger</org.apache.avro.SERIALIZABLE_CLASSES>
67+
</systemProperties>
6568
</configuration>
6669
</plugin>
6770
<plugin>

0 commit comments

Comments
 (0)