View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.io.serialization;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  
23  import java.io.ByteArrayInputStream;
24  import java.io.ByteArrayOutputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.ObjectInputStream;
28  import java.io.ObjectOutputStream;
29  import java.util.ArrayList;
30  import java.util.Random;
31  
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * This is more an example than a test - deserialize our {@link MoreComplexObject}
37   * to verify which settings it requires, as the object uses a number of primitive
38   * and java.* member objects.
39   */
40  public class MoreComplexObjectTest extends AbstractCloseableListTest {
41  
42      private InputStream inputStream;
43      private MoreComplexObject original;
44  
45      private void assertSerialization(final ObjectInputStream ois) throws ClassNotFoundException, IOException {
46          final MoreComplexObject copy = (MoreComplexObject) ois.readObject();
47          assertEquals(original.toString(), copy.toString(), "Expecting same data after deserializing");
48      }
49  
50      @BeforeEach
51      public void setupMoreComplexObject() throws IOException {
52          original = new MoreComplexObject();
53          final ByteArrayOutputStream bos = closeAfterEachTest(new ByteArrayOutputStream());
54          final ObjectOutputStream oos = closeAfterEachTest(new ObjectOutputStream(bos));
55          oos.writeObject(original);
56          inputStream = closeAfterEachTest(new ByteArrayInputStream(bos.toByteArray()));
57      }
58  
59      /** Trusting java.* is probably reasonable and avoids having to be too
60       *  detailed in the accepts.
61       */
62      @Test
63      public void testTrustJavaIncludingArrays() throws IOException, ClassNotFoundException {
64          assertSerialization(closeAfterEachTest(
65                  new ValidatingObjectInputStream(inputStream)
66                  .accept(MoreComplexObject.class)
67                  .accept("java.*", "[Ljava.*")
68          ));
69      }
70  
71      /** Trusting java.lang.* and the array variants of that means we have
72       *  to define a number of accept classes explicitly. Quite safe but
73       *  might become a bit verbose.
74       */
75      @Test
76      public void testTrustJavaLang() throws IOException, ClassNotFoundException {
77          assertSerialization(closeAfterEachTest(
78                  new ValidatingObjectInputStream(inputStream)
79                  .accept(MoreComplexObject.class, ArrayList.class, Random.class)
80                  .accept("java.lang.*", "[Ljava.lang.*")
81          ));
82      }
83  
84      /** Here we accept everything but reject specific classes, using a pure
85       *  blacklist mode.
86       *
87       *  That's not as safe as it's hard to get an exhaustive blacklist, but
88       *  might be ok in controlled environments.
89       */
90      @Test
91      public void testUseBlacklist() throws IOException, ClassNotFoundException {
92          final String [] blacklist = {
93                  "org.apache.commons.collections.functors.InvokerTransformer",
94                  "org.codehaus.groovy.runtime.ConvertedClosure",
95                  "org.codehaus.groovy.runtime.MethodClosure",
96                  "org.springframework.beans.factory.ObjectFactory"
97          };
98          assertSerialization(closeAfterEachTest(
99                  new ValidatingObjectInputStream(inputStream)
100                 .accept("*")
101                 .reject(blacklist)
102         ));
103     }
104 }