Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
bug fixed for autoType support.
  • Loading branch information
wenshao committed Jan 28, 2017
1 parent b05ad72 commit d52085e
Show file tree
Hide file tree
Showing 81 changed files with 1,174 additions and 68 deletions.
Expand Up @@ -319,7 +319,7 @@ public final Object parseObject(final Map object, Object fieldName) {

if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
String typeName = lexer.scanSymbol(symbolTable, '"');
Class<?> clazz = TypeUtils.loadClass(typeName, config.getDefaultClassLoader());
Class<?> clazz = config.checkAutoType(typeName);

if (clazz == null) {
object.put(JSON.DEFAULT_TYPE_KEY, typeName);
Expand Down
210 changes: 176 additions & 34 deletions src/main/java/com/alibaba/fastjson/parser/ParserConfig.java
Expand Up @@ -104,14 +104,9 @@
import com.alibaba.fastjson.serializer.ObjectArrayCodec;
import com.alibaba.fastjson.serializer.ReferenceCodec;
import com.alibaba.fastjson.serializer.StringCodec;
import com.alibaba.fastjson.util.ASMClassLoader;
import com.alibaba.fastjson.util.ASMUtils;
import com.alibaba.fastjson.util.FieldInfo;
import com.alibaba.fastjson.util.IOUtils;
import com.alibaba.fastjson.util.IdentityHashMap;
import com.alibaba.fastjson.util.JavaBeanInfo;
import com.alibaba.fastjson.util.ServiceLoader;
import com.alibaba.fastjson.util.*;

import javax.sql.DataSource;
import javax.xml.datatype.XMLGregorianCalendar;

/**
Expand All @@ -120,31 +115,51 @@
public class ParserConfig {

public final static String DENY_PROPERTY = "fastjson.parser.deny";
public final static String AUTOTYPE_ACCEPT = "fastjson.parser.autoTypeAccept";
public final static String AUTOTYPE_SUPPORT_PROPERTY = "fastjson.parser.autoTypeSupport";

public static final String[] DENYS=readSystemDenyPropety();
public static final String[] DENYS;
private static final String[] AUTO_TYPE_ACCEPT_LIST;
public static final boolean AUTO_SUPPORT;
static {
{
String property = IOUtils.getStringProperty(DENY_PROPERTY);
DENYS = splitItemsFormProperty(property);
}
{
String property = IOUtils.getStringProperty(AUTOTYPE_SUPPORT_PROPERTY);
AUTO_SUPPORT = "true".equals(property);
}
{
String property = IOUtils.getStringProperty(AUTOTYPE_ACCEPT);
AUTO_TYPE_ACCEPT_LIST = splitItemsFormProperty(property);
}
}

public static ParserConfig getGlobalInstance() {
return global;
}

public static ParserConfig global = new ParserConfig();
public static ParserConfig global = new ParserConfig();

private final IdentityHashMap<Type, ObjectDeserializer> derializers = new IdentityHashMap<Type, ObjectDeserializer>();
private final IdentityHashMap<Type, ObjectDeserializer> derializers = new IdentityHashMap<Type, ObjectDeserializer>();

private boolean asmEnable = !ASMUtils.IS_ANDROID;
private boolean asmEnable = !ASMUtils.IS_ANDROID;

public final SymbolTable symbolTable = new SymbolTable(4096);
public final SymbolTable symbolTable = new SymbolTable(4096);

public PropertyNamingStrategy propertyNamingStrategy;

protected ClassLoader defaultClassLoader;

protected ASMDeserializerFactory asmFactory;

private static boolean awtError = false;
private static boolean jdk8Error = false;
private static boolean awtError = false;
private static boolean jdk8Error = false;

private String[] denyList = new String[] { "java.lang.Thread" };
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.codehaus.groovy.runtime,org.hibernate,org.jboss,org.mozilla.javascript,org.python.core,org.springframework".split(",");
private String[] acceptList = new String[0];

public ParserConfig(){
this(null, null);
Expand Down Expand Up @@ -260,8 +275,9 @@ private ParserConfig(ASMDeserializerFactory asmFactory, ClassLoader parentClassL
derializers.put(Comparable.class, JavaObjectDeserializer.instance);
derializers.put(Closeable.class, JavaObjectDeserializer.instance);

addDeny("java.lang.Thread");
addItemsToDeny(DENYS);
addItemsToAccept(AUTO_TYPE_ACCEPT_LIST);

}

private static String[] splitItemsFormProperty(final String property ){
Expand All @@ -270,24 +286,56 @@ private static String[] splitItemsFormProperty(final String property ){
}
return null;
}

public void configFromPropety(Properties properties) {
String property = properties.getProperty(DENY_PROPERTY);
String[] items =splitItemsFormProperty(property);
addItemsToDeny(items);
{
String property = properties.getProperty(DENY_PROPERTY);
String[] items = splitItemsFormProperty(property);
addItemsToDeny(items);
}
{
String property = properties.getProperty(AUTOTYPE_ACCEPT);
String[] items = splitItemsFormProperty(property);
addItemsToAccept(items);
}
{
String property = properties.getProperty(AUTOTYPE_SUPPORT_PROPERTY);
if ("true".equals(property)) {
this.autoTypeSupport = true;
} else if ("false".equals(property)) {
this.autoTypeSupport = false;
}
}
}

private void addItemsToDeny(final String[] items){
if (items!=null){
for (int i = 0; i < items.length; ++i) {
String item = items[i];
this.addDeny(item);
}
if (items == null){
return;
}

for (int i = 0; i < items.length; ++i) {
String item = items[i];
this.addDeny(item);
}
}

public static String[] readSystemDenyPropety() {
String property = IOUtils.getStringProperty(DENY_PROPERTY);
return splitItemsFormProperty(property);

private void addItemsToAccept(final String[] items){
if (items == null){
return;
}

for (int i = 0; i < items.length; ++i) {
String item = items[i];
this.addAccept(item);
}
}

public boolean isAutoTypeSupport() {
return autoTypeSupport;
}

public void setAutoTypeSupport(boolean autoTypeSupport) {
this.autoTypeSupport = autoTypeSupport;
}

public boolean isAsmEnable() {
Expand Down Expand Up @@ -359,12 +407,6 @@ public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {

String className = clazz.getName();
className = className.replace('$', '.');
for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("parser deny : " + className);
}
}

if (className.startsWith("java.awt.") //
&& AwtCodec.support(clazz)) {
Expand Down Expand Up @@ -466,6 +508,24 @@ public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
return derializer;
}

/**
*
* @since 1.2.25
*/
public void initJavaBeanDeserializers(Class<?>... classes) {
if (classes == null) {
return;
}

for (Class<?> type : classes) {
if (type == null) {
continue;
}
ObjectDeserializer deserializer = createJavaBeanDeserializer(type, type);
putDeserializer(type, deserializer);
}
}

public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
boolean asmEnable = this.asmEnable;
if (asmEnable) {
Expand Down Expand Up @@ -698,9 +758,91 @@ public void addDeny(String name) {
return;
}

for (String item : denyList) {
if (name.equals(item)) {
return; // skip duplication
}
}

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;
}

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

for (String item : acceptList) {
if (name.equals(item)) {
return; // skip duplication
}
}

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;
}

public Class<?> checkAutoType(String typeName) {
if (typeName == null) {
return null;
}

final String className = typeName.replace('$', '.');

if (autoTypeSupport) {
for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}

Class<?> clazz = TypeUtils.getClassFromMapping(typeName);
if (clazz == null) {
clazz = derializers.findClass(typeName);
}

if (clazz != null) {
return clazz;
}

for (int i = 0; i < acceptList.length; ++i) {
String accept = acceptList[i];
if (className.startsWith(accept)) {
return TypeUtils.loadClass(typeName, defaultClassLoader);
}
}

if (autoTypeSupport) {
clazz = TypeUtils.loadClass(typeName, defaultClassLoader);
}

if (clazz != null) {
if (ClassLoader.class.isAssignableFrom(clazz) || DataSource.class.isAssignableFrom(clazz)) {
throw new JSONException("autoType is not support. " + typeName);
}

if (derializers.get(clazz) != null) {
return clazz;
}

if (Throwable.class.isAssignableFrom(clazz)) {
return clazz;
}
}

// java.awt.Desktop

if (!autoTypeSupport) {
throw new JSONException("autoType is not support. " + typeName);
}

return clazz;
}
}
Expand Up @@ -10,12 +10,8 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.*;
import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.ParseContext;
import com.alibaba.fastjson.util.TypeUtils;

public class MapDeserializer implements ObjectDeserializer {
Expand Down Expand Up @@ -129,7 +125,9 @@ public static Map parseMap(DefaultJSONParser parser, Map<String, Object> map, Ty

if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"');
Class<?> clazz = TypeUtils.loadClass(typeName, parser.getConfig().getDefaultClassLoader());
final ParserConfig config = parser.getConfig();

Class<?> clazz = config.checkAutoType(typeName);

if (Map.class.isAssignableFrom(clazz) ) {
lexer.nextToken(JSONToken.COMMA);
Expand All @@ -140,7 +138,7 @@ public static Map parseMap(DefaultJSONParser parser, Map<String, Object> map, Ty
continue;
}

ObjectDeserializer deserializer = parser.getConfig().getDeserializer(clazz);
ObjectDeserializer deserializer = config.getDeserializer(clazz);

lexer.nextToken(JSONToken.COMMA);

Expand Down
Expand Up @@ -74,7 +74,7 @@ public FastJsonConfig() {
this.charset = IOUtils.UTF8;

this.serializeConfig = SerializeConfig.getGlobalInstance();
this.parserConfig = ParserConfig.getGlobalInstance();
this.parserConfig = new ParserConfig();

this.serializerFeatures = new SerializerFeature[0];
this.serializeFilters = new SerializeFilter[0];
Expand Down
Expand Up @@ -62,7 +62,6 @@ protected boolean supports(Class<?> paramClass) {
return true;
}

@Override
public Object read(Type type, //
Class<?> contextClass, //
HttpInputMessage inputMessage //
Expand Down
Expand Up @@ -110,7 +110,6 @@ protected boolean supports(Class<?> paramClass) {
return true;
}

@Override
public Object read(Type type, //
Class<?> contextClass, //
HttpInputMessage inputMessage //
Expand Down
Expand Up @@ -38,12 +38,10 @@ public FastJsonpResponseBodyAdvice(String... queryParamNames) {
this.jsonpQueryParamNames = queryParamNames;
}

@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return FastJsonpHttpMessageConverter4.class.isAssignableFrom(converterType);
}

@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
Expand Down
Expand Up @@ -11,12 +11,10 @@

public class FastjsonSockJsMessageCodec extends AbstractSockJsMessageCodec {

@Override
public String[] decode(String content) throws IOException {
return JSON.parseObject(content, String[].class);
}

@Override
public String[] decodeInputStream(InputStream content) throws IOException {
return JSON.parseObject(content, String[].class);
}
Expand Down

0 comments on commit d52085e

Please sign in to comment.