1 /* 2 * Copyright (c) 2016, 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 import java.io.ByteArrayInputStream; 25 import java.io.ByteArrayOutputStream; 26 import java.io.IOException; 27 import java.io.InvalidClassException; 28 import java.io.ObjectInput; 29 import java.io.ObjectInputStream; 30 import java.io.ObjectInputFilter; 31 import java.io.ObjectOutputStream; 32 import java.io.Serializable; 33 import java.rmi.MarshalledObject; 34 import java.util.Objects; 35 36 37 import org.testng.Assert; 38 import org.testng.annotations.Test; 39 import org.testng.annotations.DataProvider; 40 41 /* @test 42 * @run testng/othervm MOFilterTest 43 * 44 * @summary Test MarshalledObject applies ObjectInputFilter 45 */ 46 @Test 47 public class MOFilterTest { 48 49 /** 50 * Two cases are tested. 51 * The filter = null and a filter set to verify the calls to the filter. 52 * @return array objects with test parameters for each test case 53 */ 54 @DataProvider(name = "FilterCases") filterCases()55 public static Object[][] filterCases() { 56 return new Object[][] { 57 {true}, // run the test with the filter 58 {false}, // run the test without the filter 59 60 }; 61 } 62 63 /** 64 * Test that MarshalledObject inherits the ObjectInputFilter from 65 * the stream it was deserialized from. 66 */ 67 @Test(dataProvider="FilterCases") delegatesToMO(boolean withFilter)68 static void delegatesToMO(boolean withFilter) { 69 try { 70 Serializable testobj = Integer.valueOf(5); 71 MarshalledObject<Serializable> mo = new MarshalledObject<>(testobj); 72 Assert.assertEquals(mo.get(), testobj, "MarshalledObject.get returned a non-equals test object"); 73 74 byte[] bytes = writeObjects(mo); 75 76 try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 77 ObjectInputStream ois = new ObjectInputStream(bais)) { 78 79 CountingFilter filter1 = new CountingFilter(); 80 ois.setObjectInputFilter(withFilter ? filter1 : null); 81 MarshalledObject<?> actualMO = (MarshalledObject<?>)ois.readObject(); 82 int count = filter1.getCount(); 83 84 actualMO.get(); 85 int expectedCount = withFilter ? count + 2 : count; 86 int actualCount = filter1.getCount(); 87 Assert.assertEquals(actualCount, expectedCount, "filter called wrong number of times during get()"); 88 } 89 } catch (IOException ioe) { 90 Assert.fail("Unexpected IOException", ioe); 91 } catch (ClassNotFoundException cnf) { 92 Assert.fail("Deserializing", cnf); 93 } 94 } 95 96 /** 97 * Write objects and return a byte array with the bytes. 98 * 99 * @param objects zero or more objects to serialize 100 * @return the byte array of the serialized objects 101 * @throws IOException if an exception occurs 102 */ writeObjects(Object... objects)103 static byte[] writeObjects(Object... objects) throws IOException { 104 byte[] bytes; 105 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); 106 ObjectOutputStream oos = new ObjectOutputStream(baos)) { 107 for (Object o : objects) { 108 oos.writeObject(o); 109 } 110 bytes = baos.toByteArray(); 111 } 112 return bytes; 113 } 114 115 116 static class CountingFilter implements ObjectInputFilter { 117 118 private int count; // count of calls to the filter 119 CountingFilter()120 CountingFilter() { 121 count = 0; 122 } 123 getCount()124 int getCount() { 125 return count; 126 } 127 128 /** 129 * Filter that rejects class Integer and allows others 130 * 131 * @param filterInfo access to the class, arrayLength, etc. 132 * @return {@code STATUS.REJECTED} 133 */ checkInput(FilterInfo filterInfo)134 public ObjectInputFilter.Status checkInput(FilterInfo filterInfo) { 135 count++; 136 return ObjectInputFilter.Status.ALLOWED; 137 } 138 } 139 140 } 141