hymn

忽有故人心头过,回首山河已是秋。

  menu
132 文章
0 浏览
0 当前访客
ღゝ◡╹)ノ❤️

序列化代理

EnumSet :反序列化使用 反序列化代理

private static class SerializationProxy <E extends Enum<E>>
        implements java.io.Serializable
    {
        /**
         * The element type of this enum set.
         *
         * @serial
         */
        private final Class<E> elementType;

        /**
         * The elements contained in this enum set.
         *
         * @serial
         */
        private final Enum<?>[] elements;

        SerializationProxy(EnumSet<E> set) {
            elementType = set.elementType;
            elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
        }

        // instead of cast to E, we should perhaps use elementType.cast()
        // to avoid injection of forged stream, but it will slow the implementation
        @SuppressWarnings("unchecked")
        private Object readResolve() {
            EnumSet<E> result = EnumSet.noneOf(elementType);
            for (Enum<?> e : elements)
                result.add((E)e);
            return result;
        }

        private static final long serialVersionUID = 362491234563181265L;
    }

    Object writeReplace() {
        return new SerializationProxy<>(this);
    }

    // readObject method for the serialization proxy pattern
    // See Effective Java, Second Ed., Item 78.
    private void readObject(java.io.ObjectInputStream stream)
        throws java.io.InvalidObjectException {
        throw new java.io.InvalidObjectException("Proxy required");
    }

writeReplace: 这个方法的存在就是导致系统产生一个 SerializationProxy实例,代替外围类的实例。换句话说 writeReplace 方法在序列化之前,将外围类的实例转变成了它的序列化代理。

  有了 writeReplace 方法之后,序列化系统永远不会产生外围类的序列化实例,但是攻击者有可能伪造企图违反该类约束条件的示例。为了防止此类攻击,只需要在外围类中添加如下 readObject 方法。


标题:序列化代理
作者:hymn
地址:https://dxyhymn.com/articles/2020/12/08/1607397011878.html