This is an automated email from the ASF dual-hosted git repository. liujun pushed a commit to branch whitelist in repository https://gitbox.apache.org/repos/asf/dubbo-hessian-lite.git
commit 7e34368fbf3eed6ce24350d9faed871f82976d8a Author: ken.lj <ken.lj...@gmail.com> AuthorDate: Sun Jun 28 22:19:19 2020 +0800 whitelist patch --- pom.xml | 2 +- .../com/caucho/hessian/io/BasicDeserializer.java | 5 + .../com/caucho/hessian/io/ClassFactory.java | 174 +++++++++++++++++++++ .../caucho/hessian/io/CollectionDeserializer.java | 5 + .../com/caucho/hessian/io/SerializerFactory.java | 22 ++- 5 files changed, 206 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 51633fd..80e32d5 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ <groupId>com.alibaba</groupId> <artifactId>hessian-lite</artifactId> <packaging>jar</packaging> - <version>3.2.7</version> + <version>3.2.8-SNAPSHOT</version> <name>Hessian Lite(Dubbo embed version)</name> <properties> diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/BasicDeserializer.java b/src/main/java/com/alibaba/com/caucho/hessian/io/BasicDeserializer.java index dc631e5..81146ca 100644 --- a/src/main/java/com/alibaba/com/caucho/hessian/io/BasicDeserializer.java +++ b/src/main/java/com/alibaba/com/caucho/hessian/io/BasicDeserializer.java @@ -607,4 +607,9 @@ public class BasicDeserializer extends AbstractDeserializer { throw new UnsupportedOperationException(String.valueOf(this)); } } + + public String toString() + { + return getClass().getSimpleName() + "[" + _code + "]"; + } } diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java b/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java new file mode 100644 index 0000000..b7a3775 --- /dev/null +++ b/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved. + * + * The Apache Software License, Version 1.1 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Caucho Technology (http://www.caucho.com/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Hessian", "Resin", and "Caucho" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * i...@caucho.com. + * + * 5. Products derived from this software may not be called "Resin" + * nor may "Resin" appear in their names without prior written + * permission of Caucho Technology. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Scott Ferguson + */ + +package com.alibaba.com.caucho.hessian.io; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.regex.Pattern; + +/** + * Loads a class from the classloader. + */ +public class ClassFactory +{ + private static ArrayList<Allow> _staticAllowList; + + private ClassLoader _loader; + private boolean _isWhitelist; + + private ArrayList<Allow> _allowList; + + ClassFactory(ClassLoader loader) + { + _loader = loader; + } + + public Class<?> load(String className) + throws ClassNotFoundException + { + if (isAllow(className)) { + return Class.forName(className, false, _loader); + } + else { + return HashMap.class; + } + } + + private boolean isAllow(String className) + { + ArrayList<Allow> allowList = _allowList; + + if (allowList == null) { + return true; + } + + int size = allowList.size(); + for (int i = 0; i < size; i++) { + Allow allow = allowList.get(i); + + Boolean isAllow = allow.allow(className); + + if (isAllow != null) { + return isAllow; + } + } + + return false; + } + + public void setWhitelist(boolean isWhitelist) + { + _isWhitelist = isWhitelist; + + initAllow(); + } + + public void allow(String pattern) + { + initAllow(); + + synchronized (this) { + _allowList.add(new Allow(toPattern(pattern), true)); + } + } + + public void deny(String pattern) + { + initAllow(); + + synchronized (this) { + _allowList.add(new Allow(toPattern(pattern), false)); + } + } + + private String toPattern(String pattern) + { + pattern = pattern.replace(".", "\\."); + pattern = pattern.replace("*", ".*"); + + return pattern; + } + + private void initAllow() + { + synchronized (this) { + if (_allowList == null) { + _allowList = new ArrayList<Allow>(); + _allowList.addAll(_staticAllowList); + } + } + } + + static class Allow { + private Boolean _isAllow; + private Pattern _pattern; + + private Allow(String pattern, boolean isAllow) + { + _isAllow = isAllow; + _pattern = Pattern.compile(pattern); + } + + Boolean allow(String className) + { + if (_pattern.matcher(className).matches()) { + return _isAllow; + } + else { + return null; + } + } + } + + static { + _staticAllowList = new ArrayList<Allow>(); + + _staticAllowList.add(new Allow("java\\..+", true)); + } +} \ No newline at end of file diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/CollectionDeserializer.java b/src/main/java/com/alibaba/com/caucho/hessian/io/CollectionDeserializer.java index fb23606..c9465b6 100644 --- a/src/main/java/com/alibaba/com/caucho/hessian/io/CollectionDeserializer.java +++ b/src/main/java/com/alibaba/com/caucho/hessian/io/CollectionDeserializer.java @@ -160,6 +160,11 @@ public class CollectionDeserializer extends AbstractListDeserializer { return list; } + + public String toString() + { + return getClass().getSimpleName() + "[" + _type + "]"; + } } diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java b/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java index 20c4187..5428228 100644 --- a/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java +++ b/src/main/java/com/alibaba/com/caucho/hessian/io/SerializerFactory.java @@ -239,6 +239,8 @@ public class SerializerFactory extends AbstractSerializerFactory { private Map<String, Object> _typeNotFoundDeserializerMap = new ConcurrentHashMap<>(8); private static final Object PRESENT = new Object(); + private ClassFactory _classFactory; + public SerializerFactory() { this(Thread.currentThread().getContextClassLoader()); } @@ -247,6 +249,23 @@ public class SerializerFactory extends AbstractSerializerFactory { _loader = loader; } + public Class<?> loadSerializedClass(String className) + throws ClassNotFoundException + { + return getClassFactory().load(className); + } + + public ClassFactory getClassFactory() + { + synchronized (this) { + if (_classFactory == null) { + _classFactory = new ClassFactory(getClassLoader()); + } + + return _classFactory; + } + } + private static void addBasic(Class cl, String typeName, int type) { _staticSerializerMap.put(cl, new BasicSerializer(type)); @@ -650,7 +669,8 @@ public class SerializerFactory extends AbstractSerializerFactory { deserializer = new ArrayDeserializer(Object.class); } else if (_unrecognizedTypeCache.get(type) == null) { try { - Class cl = Class.forName(type, false, _loader); +// Class cl = Class.forName(type, false, _loader); + Class cl = loadSerializedClass(type); deserializer = getDeserializer(cl); } catch (Exception e) { log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + _loader + ":\n" + e);