3838import java .nio .charset .Charset ;
3939import java .security .AccessControlException ;
4040import java .text .SimpleDateFormat ;
41- import java .util .ArrayList ;
42- import java .util .Calendar ;
43- import java .util .Collection ;
44- import java .util .Currency ;
45- import java .util .HashMap ;
46- import java .util .HashSet ;
47- import java .util .LinkedHashMap ;
48- import java .util .List ;
49- import java .util .Locale ;
50- import java .util .Map ;
51- import java .util .Properties ;
52- import java .util .Set ;
53- import java .util .TimeZone ;
54- import java .util .TreeMap ;
55- import java .util .UUID ;
41+ import java .util .*;
5642import java .util .concurrent .ConcurrentHashMap ;
5743import java .util .concurrent .ConcurrentMap ;
5844import java .util .concurrent .atomic .AtomicBoolean ;
6955import com .alibaba .fastjson .parser .deserializer .*;
7056import com .alibaba .fastjson .serializer .*;
7157import com .alibaba .fastjson .util .*;
58+ import com .alibaba .fastjson .util .IdentityHashMap ;
59+ import com .alibaba .fastjson .util .ServiceLoader ;
7260
7361import javax .sql .DataSource ;
7462import javax .xml .datatype .XMLGregorianCalendar ;
@@ -127,13 +115,49 @@ public static ParserConfig getGlobalInstance() {
127115 private static boolean jdk8Error = false ;
128116
129117 private boolean autoTypeSupport = AUTO_SUPPORT ;
130- 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 ("," );
131- private String [] acceptList = AUTO_TYPE_ACCEPT_LIST ;
118+ private long [] denyHashCodes ;
119+ private long [] acceptHashCodes ;
120+
132121
133122 public final boolean fieldBased ;
134123
135124 public boolean compatibleWithJavaBean = TypeUtils .compatibleWithJavaBean ;
136125
126+ {
127+ denyHashCodes = new long []{
128+ -8720046426850100497L ,
129+ -8109300701639721088L ,
130+ -7966123100503199569L ,
131+ -7766605818834748097L ,
132+ -6835437086156813536L ,
133+ -4082057040235125754L ,
134+ -3979025623072794412L ,
135+ -2364987994247679115L ,
136+ -1872417015366588117L ,
137+ -254670111376247151L ,
138+ 33238344207745342L ,
139+ 313864100207897507L ,
140+ 1203232727967308606L ,
141+ 3547627781654598988L ,
142+ 3730752432285826863L ,
143+ 4147696707147271408L ,
144+ 5450448828334921485L ,
145+ 5751393439502795295L ,
146+ 5944107969236155580L ,
147+ 6742705432718011780L ,
148+ 7179336928365889465L ,
149+ 7442624256860549330L ,
150+ 8838294710098435315L
151+ };
152+
153+ long [] hashCodes = new long [AUTO_TYPE_ACCEPT_LIST .length ];
154+ for (int i = 0 ; i < AUTO_TYPE_ACCEPT_LIST .length ; i ++) {
155+ hashCodes [i ] = TypeUtils .fnv1a_64 (AUTO_TYPE_ACCEPT_LIST [i ]);
156+ }
157+ Arrays .sort (hashCodes );
158+ acceptHashCodes = hashCodes ;
159+ }
160+
137161 public ParserConfig (){
138162 this (false );
139163 }
@@ -818,33 +842,33 @@ public void addDeny(String name) {
818842 return ;
819843 }
820844
821- for (String item : denyList ) {
822- if (name .equals (item )) {
823- return ; // skip duplication
824- }
845+ long hash = TypeUtils .fnv1a_64 (name );
846+ if (Arrays .binarySearch (this .denyHashCodes , hash ) >= 0 ) {
847+ return ;
825848 }
826849
827- String [] denyList = new String [this .denyList .length + 1 ];
828- System .arraycopy (this .denyList , 0 , denyList , 0 , this .denyList .length );
829- denyList [denyList .length - 1 ] = name ;
830- this .denyList = denyList ;
850+ long [] hashCodes = new long [this .denyHashCodes .length + 1 ];
851+ hashCodes [hashCodes .length - 1 ] = hash ;
852+ System .arraycopy (this .denyHashCodes , 0 , hashCodes , 0 , this .denyHashCodes .length );
853+ Arrays .sort (hashCodes );
854+ this .denyHashCodes = hashCodes ;
831855 }
832856
833857 public void addAccept (String name ) {
834858 if (name == null || name .length () == 0 ) {
835859 return ;
836860 }
837861
838- for (String item : acceptList ) {
839- if (name .equals (item )) {
840- return ; // skip duplication
841- }
862+ long hash = TypeUtils .fnv1a_64 (name );
863+ if (Arrays .binarySearch (this .acceptHashCodes , hash ) >= 0 ) {
864+ return ;
842865 }
843866
844- String [] acceptList = new String [this .acceptList .length + 1 ];
845- System .arraycopy (this .acceptList , 0 , acceptList , 0 , this .acceptList .length );
846- acceptList [acceptList .length - 1 ] = name ;
847- this .acceptList = acceptList ;
867+ long [] hashCodes = new long [this .acceptHashCodes .length + 1 ];
868+ hashCodes [hashCodes .length - 1 ] = hash ;
869+ System .arraycopy (this .acceptHashCodes , 0 , hashCodes , 0 , this .acceptHashCodes .length );
870+ Arrays .sort (hashCodes );
871+ this .acceptHashCodes = hashCodes ;
848872 }
849873
850874 public Class <?> checkAutoType (String typeName , Class <?> expectClass ) {
@@ -856,27 +880,50 @@ public Class<?> checkAutoType(String typeName, Class<?> expectClass, int feature
856880 return null ;
857881 }
858882
859- if (typeName .length () >= 128 ) {
883+ if (typeName .length () >= 128 || typeName . length () < 3 ) {
860884 throw new JSONException ("autoType is not support. " + typeName );
861885 }
862886
863- final String className = typeName .replace ('$' , '.' );
887+ String className = typeName .replace ('$' , '.' );
864888 Class <?> clazz = null ;
865889
890+ if (className .charAt (0 ) == 'L' && className .charAt (className .length () - 1 ) == ';' ) {
891+ className = className .substring (1 , className .length () - 1 );
892+ }
893+
894+ final long BASIC = 0xcbf29ce484222325L ;
895+ final long PRIME = 0x100000001b3L ;
896+
897+ long hash3 = BASIC ;
898+ {
899+ char c = className .charAt (0 );
900+ hash3 ^= c ;
901+ hash3 *= PRIME ;
902+ }
903+ {
904+ char c = className .charAt (1 );
905+ hash3 ^= c ;
906+ hash3 *= PRIME ;
907+ }
908+ {
909+ char c = className .charAt (2 );
910+ hash3 ^= c ;
911+ hash3 *= PRIME ;
912+ }
913+
866914 if (autoTypeSupport || expectClass != null ) {
867- for (int i = 0 ; i < acceptList .length ; ++i ) {
868- String accept = acceptList [i ];
869- if (className .startsWith (accept )) {
915+ long hash = hash3 ;
916+ for (int i = 3 ; i < className .length (); ++i ) {
917+ char c = className .charAt (i );
918+ hash ^= c ;
919+ hash *= PRIME ;
920+ if (Arrays .binarySearch (acceptHashCodes , hash ) >= 0 ) {
870921 clazz = TypeUtils .loadClass (typeName , defaultClassLoader , false );
871922 if (clazz != null ) {
872923 return clazz ;
873924 }
874925 }
875- }
876-
877- for (int i = 0 ; i < denyList .length ; ++i ) {
878- String deny = denyList [i ];
879- if (className .startsWith (deny ) && TypeUtils .getClassFromMapping (typeName ) == null ) {
926+ if (Arrays .binarySearch (denyHashCodes , hash ) >= 0 && TypeUtils .getClassFromMapping (typeName ) == null ) {
880927 throw new JSONException ("autoType is not support. " + typeName );
881928 }
882929 }
@@ -901,25 +948,29 @@ public Class<?> checkAutoType(String typeName, Class<?> expectClass, int feature
901948 }
902949
903950 if (!autoTypeSupport ) {
904- for (int i = 0 ; i < denyList .length ; ++i ) {
905- String deny = denyList [i ];
906- if (className .startsWith (deny )) {
951+ long hash = hash3 ;
952+ for (int i = 3 ; i < className .length (); ++i ) {
953+ char c = className .charAt (i );
954+ hash ^= c ;
955+ hash *= PRIME ;
956+
957+ if (Arrays .binarySearch (denyHashCodes , hash ) >= 0 ) {
907958 throw new JSONException ("autoType is not support. " + typeName );
908959 }
909- }
910- for (int i = 0 ; i < acceptList .length ; ++i ) {
911- String accept = acceptList [i ];
912- if (className .startsWith (accept )) {
960+
961+ if (Arrays .binarySearch (acceptHashCodes , hash ) >= 0 ) {
913962 if (clazz == null ) {
914963 clazz = TypeUtils .loadClass (typeName , defaultClassLoader , false );
915964 }
916965
917966 if (expectClass != null && expectClass .isAssignableFrom (clazz )) {
918967 throw new JSONException ("type not match. " + typeName + " -> " + expectClass .getName ());
919968 }
969+
920970 return clazz ;
921971 }
922972 }
973+
923974 }
924975
925976 if (clazz == null ) {
0 commit comments