Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
bug fixed autoType denyList check.
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Dec 11, 2017
1 parent f1cd9f9 commit eebea03
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 50 deletions.
151 changes: 101 additions & 50 deletions src/main/java/com/alibaba/fastjson/parser/ParserConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,7 @@
import java.nio.charset.Charset;
import java.security.AccessControlException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Currency;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -69,6 +55,8 @@
import com.alibaba.fastjson.parser.deserializer.*;
import com.alibaba.fastjson.serializer.*;
import com.alibaba.fastjson.util.*;
import com.alibaba.fastjson.util.IdentityHashMap;
import com.alibaba.fastjson.util.ServiceLoader;

import javax.sql.DataSource;
import javax.xml.datatype.XMLGregorianCalendar;
Expand Down Expand Up @@ -127,13 +115,49 @@ public static ParserConfig getGlobalInstance() {
private static boolean jdk8Error = false;

private boolean autoTypeSupport = AUTO_SUPPORT;
private String[] denyList = "bsh,com.mchange,com.sun.,java.lang.Thread,java.net.Socket,java.rmi,javax.xml,org.apache.bcel,org.apache.commons.beanutils,org.apache.commons.collections.Transformer,org.apache.commons.collections.functors,org.apache.commons.collections4.comparators,org.apache.commons.fileupload,org.apache.myfaces.context.servlet,org.apache.tomcat,org.apache.wicket.util,org.apache.xalan,org.codehaus.groovy.runtime,org.hibernate,org.jboss,org.mozilla.javascript,org.python.core,org.springframework".split(",");
private String[] acceptList = AUTO_TYPE_ACCEPT_LIST;
private long[] denyHashCodes;
private long[] acceptHashCodes;


public final boolean fieldBased;

public boolean compatibleWithJavaBean = TypeUtils.compatibleWithJavaBean;

{
denyHashCodes = new long[]{
-8720046426850100497L,
-8109300701639721088L,
-7966123100503199569L,
-7766605818834748097L,
-6835437086156813536L,
-4082057040235125754L,
-3979025623072794412L,
-2364987994247679115L,
-1872417015366588117L,
-254670111376247151L,
33238344207745342L,
313864100207897507L,
1203232727967308606L,
3547627781654598988L,
3730752432285826863L,
4147696707147271408L,
5450448828334921485L,
5751393439502795295L,
5944107969236155580L,
6742705432718011780L,
7179336928365889465L,
7442624256860549330L,
8838294710098435315L
};

long[] hashCodes = new long[AUTO_TYPE_ACCEPT_LIST.length];
for (int i = 0; i < AUTO_TYPE_ACCEPT_LIST.length; i++) {
hashCodes[i] = TypeUtils.fnv1a_64(AUTO_TYPE_ACCEPT_LIST[i]);
}
Arrays.sort(hashCodes);
acceptHashCodes = hashCodes;
}

public ParserConfig(){
this(false);
}
Expand Down Expand Up @@ -818,33 +842,33 @@ public void addDeny(String name) {
return;
}

for (String item : denyList) {
if (name.equals(item)) {
return; // skip duplication
}
long hash = TypeUtils.fnv1a_64(name);
if (Arrays.binarySearch(this.denyHashCodes, hash) >= 0) {
return;
}

String[] denyList = new String[this.denyList.length + 1];
System.arraycopy(this.denyList, 0, denyList, 0, this.denyList.length);
denyList[denyList.length - 1] = name;
this.denyList = denyList;
long[] hashCodes = new long[this.denyHashCodes.length + 1];
hashCodes[hashCodes.length - 1] = hash;
System.arraycopy(this.denyHashCodes, 0, hashCodes, 0, this.denyHashCodes.length);
Arrays.sort(hashCodes);
this.denyHashCodes = hashCodes;
}

public void addAccept(String name) {
if (name == null || name.length() == 0) {
return;
}

for (String item : acceptList) {
if (name.equals(item)) {
return; // skip duplication
}
long hash = TypeUtils.fnv1a_64(name);
if (Arrays.binarySearch(this.acceptHashCodes, hash) >= 0) {
return;
}

String[] acceptList = new String[this.acceptList.length + 1];
System.arraycopy(this.acceptList, 0, acceptList, 0, this.acceptList.length);
acceptList[acceptList.length - 1] = name;
this.acceptList = acceptList;
long[] hashCodes = new long[this.acceptHashCodes.length + 1];
hashCodes[hashCodes.length - 1] = hash;
System.arraycopy(this.acceptHashCodes, 0, hashCodes, 0, this.acceptHashCodes.length);
Arrays.sort(hashCodes);
this.acceptHashCodes = hashCodes;
}

public Class<?> checkAutoType(String typeName, Class<?> expectClass) {
Expand All @@ -856,27 +880,50 @@ public Class<?> checkAutoType(String typeName, Class<?> expectClass, int feature
return null;
}

if (typeName.length() >= 128) {
if (typeName.length() >= 128 || typeName.length() < 3) {
throw new JSONException("autoType is not support. " + typeName);
}

final String className = typeName.replace('$', '.');
String className = typeName.replace('$', '.');
Class<?> clazz = null;

if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') {
className = className.substring(1, className.length() - 1);
}

final long BASIC = 0xcbf29ce484222325L;
final long PRIME = 0x100000001b3L;

long hash3 = BASIC;
{
char c = className.charAt(0);
hash3 ^= c;
hash3 *= PRIME;
}
{
char c = className.charAt(1);
hash3 ^= c;
hash3 *= PRIME;
}
{
char c = className.charAt(2);
hash3 ^= c;
hash3 *= PRIME;
}

if (autoTypeSupport || expectClass != null) {
for (int i = 0; i < acceptList.length; ++i) {
String accept = acceptList[i];
if (className.startsWith(accept)) {
long hash = hash3;
for (int i = 3; i < className.length(); ++i) {
char c = className.charAt(i);
hash ^= c;
hash *= PRIME;
if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader, false);
if (clazz != null) {
return clazz;
}
}
}

for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny) && TypeUtils.getClassFromMapping(typeName) == null) {
if (Arrays.binarySearch(denyHashCodes, hash) >= 0 && TypeUtils.getClassFromMapping(typeName) == null) {
throw new JSONException("autoType is not support. " + typeName);
}
}
Expand All @@ -901,25 +948,29 @@ public Class<?> checkAutoType(String typeName, Class<?> expectClass, int feature
}

if (!autoTypeSupport) {
for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny)) {
long hash = hash3;
for (int i = 3; i < className.length(); ++i) {
char c = className.charAt(i);
hash ^= c;
hash *= PRIME;

if (Arrays.binarySearch(denyHashCodes, hash) >= 0) {
throw new JSONException("autoType is not support. " + typeName);
}
}
for (int i = 0; i < acceptList.length; ++i) {
String accept = acceptList[i];
if (className.startsWith(accept)) {

if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
if (clazz == null) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader, false);
}

if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}

return clazz;
}
}

}

if (clazz == null) {
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ public void test_0() throws Exception {
JSON.parseObject(text, B.class, config, JSON.DEFAULT_PARSER_FEATURE);
}

public void test_1() throws Exception {
String text = "{}";

ParserConfig config = new ParserConfig();

config.addDeny(null);
config.addDeny("com.alibaba.json.bvt.parser.deser.deny.DenyTest.B");

Exception error = null;
try {
JSON.parseObject("{\"@type\":\"Lcom.alibaba.json.bvt.parser.deser.deny.DenyTest$B;\"}", Object.class, config, JSON.DEFAULT_PARSER_FEATURE);
} catch (JSONException ex) {
error = ex;
}
Assert.assertNotNull(error);

JSON.parseObject(text, B.class, config, JSON.DEFAULT_PARSER_FEATURE);
}


public static class B {

Expand Down

1 comment on commit eebea03

@tututu-patch
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

666

Please sign in to comment.