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   *   https://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  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 = addCloseable(new ByteArrayOutputStream());
54          final ObjectOutputStream oos = addCloseable(new ObjectOutputStream(bos));
55          oos.writeObject(original);
56          inputStream = addCloseable(new ByteArrayInputStream(bos.toByteArray()));
57      }
58  
59      /**
60       * Trusting java.* is probably reasonable and avoids having to be too detailed in the accepts.
61       */
62      @Test
63      void testTrustJavaIncludingArrays() throws IOException, ClassNotFoundException {
64          // @formatter:off
65          assertSerialization(addCloseable(
66                  ValidatingObjectInputStream.builder()
67                  .setInputStream(inputStream)
68                  .accept(MoreComplexObject.class)
69                  .accept("java.*", "[Ljava.*")
70                  .get()
71          ));
72          // @formatter:on
73      }
74  
75      /**
76       * Trusting java.lang.* and the array variants of that means we have to define a number of accept classes explicitly. Quite safe but might become a bit
77       * verbose.
78       */
79      @Test
80      void testTrustJavaLang() throws IOException, ClassNotFoundException {
81          // @formatter:off
82          assertSerialization(addCloseable(
83                  ValidatingObjectInputStream.builder()
84                  .setInputStream(inputStream)
85                  .accept(MoreComplexObject.class, ArrayList.class, Random.class)
86                  .accept("java.lang.*", "[Ljava.lang.*")
87                  .get()
88          ));
89          // @formatter:on
90      }
91  
92      /**
93       * Here we accept everything but reject specific classes, using a pure blacklist mode.
94       *
95       * That's not as safe as it's hard to get an exhaustive blacklist, but might be ok in controlled environments.
96       */
97      @Test
98      void testUseBlacklist() throws IOException, ClassNotFoundException {
99          final String [] blacklist = {
100                 "org.apache.commons.collections.functors.InvokerTransformer",
101                 "org.codehaus.groovy.runtime.ConvertedClosure",
102                 "org.codehaus.groovy.runtime.MethodClosure",
103                 "org.springframework.beans.factory.ObjectFactory"
104         };
105         // @formatter:off
106         assertSerialization(addCloseable(
107                 ValidatingObjectInputStream.builder()
108                 .setInputStream(inputStream)
109                 .accept("*")
110                 .reject(blacklist)
111                 .get()
112         ));
113         // @formatter:on
114     }
115 }