1 /*
   2  * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4100915
  27  * @summary Verify that [write/read]ObjectOverride methods get called.
  28  *          Test verifies that ALL methods to write an object can
  29  *          be overridden. However, the testing for reading an object
  30  *          is incomplete. Only test that readObjectOverride is called.
  31  *          An entire protocol would need to be implemented and written
  32  *          out before being able to test the input side of the API.
  33  *
  34  *          Also, would be appropriate that this program verify
  35  *          that if SerializablePermission "enableSubclassImplementation"
  36  *          is not in the security policy and security is enabled, that
  37  *          a security excepiton is thrown when constructing the
  38  *          ObjectOutputStream subclass.
  39  *
  40  *
  41  * @compile AbstractObjectInputStream.java AbstractObjectOutputStream.java XObjectInputStream.java XObjectOutputStream.java Test.java
  42  * @run main Test
  43  * @run main/othervm/policy=Allow.policy Test -expectSecurityException
  44  */
  45 
  46 import java.io.*;
  47 
  48 /**
  49  * Test if customized readObject and writeObject are called.
  50  */
  51 class B implements Serializable {
  52     public int publicIntField;
  53     public static int numWriteObjectCalled = 0;
  54     B(int v) {
  55         publicIntField = v;
  56     }
  57     private void writeObject(ObjectOutputStream os) throws IOException {
  58         numWriteObjectCalled++;
  59         os.defaultWriteObject();
  60     }
  61 
  62     private void readObject(ObjectInputStream is)
  63         throws IOException, ClassNotFoundException
  64     {
  65         is.defaultReadObject();
  66     }
  67 
  68 };
  69 
  70 /**
  71  * Test PutFields interface.
  72  */
  73 
  74 class C implements Serializable {
  75     public int xx1;
  76     public int xx2;
  77     static final ObjectStreamField[] serialPersistentFields = {
  78         new ObjectStreamField("x1", Integer.TYPE),
  79         new ObjectStreamField("x2", Integer.TYPE),
  80         new ObjectStreamField("x3", Integer.TYPE),
  81         new ObjectStreamField("x4", Integer.TYPE)
  82     };
  83     C() {
  84         xx1 = 300;
  85         xx2 = 400;
  86     }
  87 
  88     private void writeObject(ObjectOutputStream os) throws IOException {
  89         ObjectOutputStream.PutField putFields = os.putFields();
  90         putFields.put("x1", xx1);
  91         putFields.put("x2", xx2);
  92         putFields.put("x3", xx1 * 2);
  93         putFields.put("x4", xx2 * 2);
  94         os.writeFields();
  95     }
  96 
  97 };
  98 
  99 
 100 class A implements Serializable {
 101     public int  publicIntField;
 102     public long publicLongField;
 103     public B    publicBField;
 104     public B[]  publicBArray = { new B(4), new B(6)};
 105     public C    publicCField;
 106 
 107     public A() {
 108         publicIntField = 3;
 109         publicLongField = 10L;
 110         publicBField = new B(5);
 111         publicCField = new C();
 112     }
 113 };
 114 
 115 public class Test {
 116     public static void main(String argv[])
 117         throws IOException, ClassNotFoundException
 118     {
 119         boolean expectSecurityException = false;
 120 
 121         if (argv.length > 0 &&
 122             argv[0].compareTo("-expectSecurityException") == 0)
 123             expectSecurityException = true;
 124 
 125         ByteArrayOutputStream baos = new ByteArrayOutputStream(20);
 126         XObjectOutputStream os = null;
 127         try {
 128             os = new XObjectOutputStream(baos);
 129             if (expectSecurityException)
 130                 throw new Error("Assertion failure. " +
 131                                 "Expected a security exception on previous line.");
 132         } catch (SecurityException e) {
 133             if (expectSecurityException) {
 134                 System.err.println("Caught expected security exception.");
 135                 return;
 136             }
 137             throw e;
 138         }
 139         os.writeObject(new A());
 140         os.close();
 141         if (B.numWriteObjectCalled != 3)
 142             throw new Error("Expected B.writeObject() to be called 3 times;" +
 143                             " observed only " + B.numWriteObjectCalled + " times");
 144 
 145         XObjectInputStream is =
 146             new XObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
 147         try {
 148             A a = (A)is.readObject();
 149             throw new Error("Expected readObjectOverride() to be called and throw IOException(not implemented)");
 150         } catch (IOException e) {
 151         }
 152         is.close();
 153     }
 154 };