`
leonzhx
  • 浏览: 766678 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Item 77: For instance control, prefer enum types to readResolve

阅读更多

1.  The readResolve feature allows you to substitute another instance for the one created by readObject. If the class of an object being deserialized defines a readResolve method with the proper declaration, this method is invoked on the newly created object after it is deserialized. The object reference returned by this method is then returned in place of the newly created object.

 

2.  If you depend on readResolve for instance control, all instance fields with object reference types must be declared transient. Otherwise, it is possible for a determined attacker to secure a reference to the deserialized object before its readResolve method is run. Here’s how it works in more detail. First, write a “stealer” class that has both a readResolve method and an instance field that refers to the serialized singleton in which the stealer “hides.” In the serialization stream, replace the singleton’s nontransient field with an instance of the stealer. You now have a circularity: the singleton contains the stealer and the stealer refers to the singleton. Because the singleton contains the stealer, the stealer’s readResolve method runs first when the singleton is deserialized. As a result, when the stealer’s readResolve method runs, its instance field still refers to the partially deserialized (and as yet unresolved) singleton. The stealer’s readResolve method copies the reference from its instance field into a static field, so that the reference can be accessed after the readResolve method runs. The method then returns a value of the correct type for the field in which it’s hiding. If it didn’t do this, the VM would throw a ClassCastException when the serialization system tried to store the stealer reference into this field:

// Broken singleton - has nontransient object reference field!
public class Elvis implements Serializable {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { }
    private String[] favoriteSongs = { "Hound Dog", "Heartbreak Hotel" };
    public void printFavorites() {
        System.out.println(Arrays.toString(favoriteSongs));
    }
    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}

public class ElvisStealer implements Serializable {
    static Elvis impersonator;
    private Elvis payload;
    private Object readResolve() {
        // Save a reference to the "unresolved" Elvis instance
        impersonator = payload;
        // Return an object of correct type for favorites field
        return new String[] { "A Fool Such as I" };
    }
    private static final long serialVersionUID = 0;
}

public class ElvisImpersonator {
    // Byte stream could not have come from real Elvis instance!
    private static final byte[] serializedForm = new byte[] {
        (byte)0xac, (byte)0xed, 0x00, 0x05, 0x73, 0x72, 0x00, 0x05,
        0x45, 0x6c, 0x76, 0x69, 0x73, (byte)0x84, (byte)0xe6,
        (byte)0x93, 0x33, (byte)0xc3, (byte)0xf4, (byte)0x8b,
        0x32, 0x02, 0x00, 0x01, 0x4c, 0x00, 0x0d, 0x66, 0x61, 0x76,
        0x6f, 0x72, 0x69, 0x74, 0x65, 0x53, 0x6f, 0x6e, 0x67, 0x73,
        0x74, 0x00, 0x12, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
        0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
        0x3b, 0x78, 0x70, 0x73, 0x72, 0x00, 0x0c, 0x45, 0x6c, 0x76,
        0x69, 0x73, 0x53, 0x74, 0x65, 0x61, 0x6c, 0x65, 0x72, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
        0x4c, 0x00, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
        0x74, 0x00, 0x07, 0x4c, 0x45, 0x6c, 0x76, 0x69, 0x73, 0x3b,
        0x78, 0x70, 0x71, 0x00, 0x7e, 0x00, 0x02
    };
    public static void main(String[] args) {
        // Initializes ElvisStealer.impersonator and returns
        // the real Elvis (which is Elvis.INSTANCE)
        Elvis elvis = (Elvis) deserialize(serializedForm);
        Elvis impersonator = ElvisStealer.impersonator;
        elvis.printFavorites();
        impersonator.printFavorites();
    }
}

 

3.  If instead you write your serializable instance-controlled class as an enum, you get an ironclad guarantee that there can be no instances besides the declared constants. The JVM makes this guarantee, and you can depend on it. It requires no special care on your part.

 

4.  If you place a readResolve method on a final class, it should be private. If you place a readResolve method on a nonfinal class, you must carefully consider its accessibility. If a readResolve method is protected or public and a subclass does not override it, deserializing a serialized subclass instance will produce a superclass instance, which is likely to cause a ClassCastException.

 

分享到:
评论

相关推荐

    Effective Java 3rd edition(Effective Java第三版英文原版)附第二版

    目录如下: 1 Introduction 2 Creating and Destroying Objects ...Item 89: For instance control, prefer enum types to readResolve Item 90: Consider serialization proxies instead of serialized instances

    Effective C# (Covers C# 4.0) Mar 2010

    Item 13: Use Proper Initialization for Static Class Members 77 Item 14: Minimize Duplicate Initialization Logic 79 Item 15: Utilize using and try/finally for Resource Cleanup 87 Item 16: Avoid ...

    tcping查看端口及IP链路情况

    -w 0.5 : for instance, wait 0.5 seconds for a response -d : include date and time on each line -b 1 : enable beeps (1 for on-down, 2 for on-up, 3 for on-change, 4 for always) -r 5 : for instance,...

    leaflet-prefer-canvas:将L_PREFER_CANVAS选项添加到流星的传单地图中

    传单首选画布使用meteorhacks:inject-initial软件包注入L_PREFER_CANVAS = true; 选项,然后加载您喜欢的传单包。 这被添加到您的文档头中: <head> [removed]L_PREFER_CANVAS = true;[removed] ... style...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Therefore, we prefer to minimize includes, particularly includes of header files in other header files. You can significantly minimize the number of header files you need to include in your own ...

    Effective C++(第三版)

    prefer pass-by-reference-to-const to pass-by-value. 条款21:必须返回对象时,别妄想返回其reference don't try to return a reference when you must return an object. 条款22:将成员变量声明为private ...

    Pro.SQL.Server.Internals

    This book is an excellent choice for people who prefer to understand and fix the root cause of a problem rather than applying a 'band aid' to it. Table of Contents Part I: Tables and Indexes Chapter...

    prefer.js:HTTP首选标头中间件

    var prefer = req.prefer; if (prefer.handling === 'strict') { // strict handling } else if (prefer.handling === 'lenient') { // lenient handling } if (prefer.respondAsync) { // client prefers ...

    plsqldev12.0.6.1832x32主程序+ v12中文包+keygen

    Users that prefer a menu-like system to preserve screen real estate can select to automatically hide the ribbon. In the preferences you can select an option to revert to the familiar toolbar layout ...

    专享:prefer的用法__(全).pdf

    专享:prefer的用法__(全).pdf

    Beginning Perl for Bioinformatics

    if you'd prefer, other places to install the module can be found in the book or in the Perl documentation. EXAMPLES The file begperlbio_examples.tar.gz contains all the numbered examples from the ...

    plsqldev12.0.6.1832x64主程序+ v12中文包+keygen

    Users that prefer a menu-like system to preserve screen real estate can select to automatically hide the ribbon. In the preferences you can select an option to revert to the familiar toolbar layout ...

    PLSQL.Developer(X32) v12.0.1.1814主程序+ v11中文包+keygen

    Users that prefer a menu-like system to preserve screen real estate can select to automatically hide the ribbon. In the preferences you can select an option to revert to the familiar toolbar layout ...

    plsqldev12.0.4.1826x32主程序+ v12中文包+keygen

    Users that prefer a menu-like system to preserve screen real estate can select to automatically hide the ribbon. In the preferences you can select an option to revert to the familiar toolbar layout ...

    PLSQL.Developer(X64) v12.0.1.1814 主程序+ v11中文包+keygen

    Users that prefer a menu-like system to preserve screen real estate can select to automatically hide the ribbon. In the preferences you can select an option to revert to the familiar toolbar layout ...

    plsqldev12.0.4.1826x64主程序+ v12中文包+keygen

    Users that prefer a menu-like system to preserve screen real estate can select to automatically hide the ribbon. In the preferences you can select an option to revert to the familiar toolbar layout ...

    The DevOps 2.4 Toolkit: Continuous Deployment To Kubernetes

    Minikube and Docker for Mac or Windows should undoubtedly be there for those who prefer to "play" with Docker locally. AWS is the biggest hosting provider so Kubernetes Operations (kops) must be ...

    VclZip pro v3.10.1

    Much faster processing due to linking to Zlib object files for compression and decompression routines. Blocked Zip Files (spanned zip archives split onto hard drive) - Now completely compatible ...

    julia-1.1.0-win64

    We believe there are many good reasons to prefer dynamic languages for these applications, and we do not expect their use to diminish. Fortunately, modern language design and compiler techniques make...

Global site tag (gtag.js) - Google Analytics