View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.serialization;
17  
18  import io.netty.util.internal.ObjectUtil;
19  
20  import java.io.BufferedReader;
21  import java.io.DataInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.ObjectInput;
25  import java.io.StreamCorruptedException;
26  
27  /**
28   * An {@link ObjectInput} which is interoperable with {@link ObjectEncoder}
29   * and {@link ObjectEncoderOutputStream}.
30   * <p>
31   * <strong>Security:</strong> serialization can be a security liability,
32   * and should not be used without defining a list of classes that are
33   * allowed to be desirialized. Such a list can be specified with the
34   * <tt>jdk.serialFilter</tt> system property, for instance.
35   * See the <a href="https://docs.oracle.com/en/java/javase/17/core/serialization-filtering1.html">
36   * serialization filtering</a> article for more information.
37   *
38   * @deprecated This class has been deprecated with no replacement,
39   * because serialization can be a security liability
40   */
41  @Deprecated
42  public class ObjectDecoderInputStream extends InputStream implements
43          ObjectInput {
44  
45      private final DataInputStream in;
46      private final int maxObjectSize;
47      private final ClassResolver classResolver;
48  
49      /**
50       * Creates a new {@link ObjectInput}.
51       *
52       * @param in
53       *        the {@link InputStream} where the serialized form will be
54       *        read from
55       */
56      public ObjectDecoderInputStream(InputStream in) {
57          this(in, null);
58      }
59  
60      /**
61       * Creates a new {@link ObjectInput}.
62       *
63       * @param in
64       *        the {@link InputStream} where the serialized form will be
65       *        read from
66       * @param classLoader
67       *        the {@link ClassLoader} which will load the class of the
68       *        serialized object
69       */
70      public ObjectDecoderInputStream(InputStream in, ClassLoader classLoader) {
71          this(in, classLoader, 1048576);
72      }
73  
74      /**
75       * Creates a new {@link ObjectInput}.
76       *
77       * @param in
78       *        the {@link InputStream} where the serialized form will be
79       *        read from
80       * @param maxObjectSize
81       *        the maximum byte length of the serialized object.  if the length
82       *        of the received object is greater than this value,
83       *        a {@link StreamCorruptedException} will be raised.
84       */
85      public ObjectDecoderInputStream(InputStream in, int maxObjectSize) {
86          this(in, null, maxObjectSize);
87      }
88  
89      /**
90       * Creates a new {@link ObjectInput}.
91       *
92       * @param in
93       *        the {@link InputStream} where the serialized form will be
94       *        read from
95       * @param classLoader
96       *        the {@link ClassLoader} which will load the class of the
97       *        serialized object
98       * @param maxObjectSize
99       *        the maximum byte length of the serialized object.  if the length
100      *        of the received object is greater than this value,
101      *        a {@link StreamCorruptedException} will be raised.
102      */
103     public ObjectDecoderInputStream(InputStream in, ClassLoader classLoader, int maxObjectSize) {
104         ObjectUtil.checkNotNull(in, "in");
105         ObjectUtil.checkPositive(maxObjectSize, "maxObjectSize");
106 
107         if (in instanceof DataInputStream) {
108             this.in = (DataInputStream) in;
109         } else {
110             this.in = new DataInputStream(in);
111         }
112         classResolver = ClassResolvers.weakCachingResolver(classLoader);
113         this.maxObjectSize = maxObjectSize;
114     }
115 
116     @Override
117     public Object readObject() throws ClassNotFoundException, IOException {
118         int dataLen = readInt();
119         if (dataLen <= 0) {
120             throw new StreamCorruptedException("invalid data length: " + dataLen);
121         }
122         if (dataLen > maxObjectSize) {
123             throw new StreamCorruptedException(
124                     "data length too big: " + dataLen + " (max: " + maxObjectSize + ')');
125         }
126 
127         return new CompactObjectInputStream(in, classResolver).readObject();
128     }
129 
130     @Override
131     public int available() throws IOException {
132         return in.available();
133     }
134 
135     @Override
136     public void close() throws IOException {
137         in.close();
138     }
139 
140     // Suppress a warning since the class is not thread-safe
141     @Override
142     public void mark(int readlimit) {
143         in.mark(readlimit);
144     }
145 
146     @Override
147     public boolean markSupported() {
148         return in.markSupported();
149     }
150 
151     // Suppress a warning since the class is not thread-safe
152     @Override
153     public int read() throws IOException {
154         return in.read();
155     }
156 
157     @Override
158     public final int read(byte[] b, int off, int len) throws IOException {
159         return in.read(b, off, len);
160     }
161 
162     @Override
163     public final int read(byte[] b) throws IOException {
164         return in.read(b);
165     }
166 
167     @Override
168     public final boolean readBoolean() throws IOException {
169         return in.readBoolean();
170     }
171 
172     @Override
173     public final byte readByte() throws IOException {
174         return in.readByte();
175     }
176 
177     @Override
178     public final char readChar() throws IOException {
179         return in.readChar();
180     }
181 
182     @Override
183     public final double readDouble() throws IOException {
184         return in.readDouble();
185     }
186 
187     @Override
188     public final float readFloat() throws IOException {
189         return in.readFloat();
190     }
191 
192     @Override
193     public final void readFully(byte[] b, int off, int len) throws IOException {
194         in.readFully(b, off, len);
195     }
196 
197     @Override
198     public final void readFully(byte[] b) throws IOException {
199         in.readFully(b);
200     }
201 
202     @Override
203     public final int readInt() throws IOException {
204         return in.readInt();
205     }
206 
207     /**
208      * @deprecated Use {@link BufferedReader#readLine()} instead.
209      */
210     @Override
211     @Deprecated
212     public final String readLine() throws IOException {
213         return in.readLine();
214     }
215 
216     @Override
217     public final long readLong() throws IOException {
218         return in.readLong();
219     }
220 
221     @Override
222     public final short readShort() throws IOException {
223         return in.readShort();
224     }
225 
226     @Override
227     public final int readUnsignedByte() throws IOException {
228         return in.readUnsignedByte();
229     }
230 
231     @Override
232     public final int readUnsignedShort() throws IOException {
233         return in.readUnsignedShort();
234     }
235 
236     @Override
237     public final String readUTF() throws IOException {
238         return in.readUTF();
239     }
240 
241     @Override
242     public void reset() throws IOException {
243         in.reset();
244     }
245 
246     @Override
247     public long skip(long n) throws IOException {
248         return in.skip(n);
249     }
250 
251     @Override
252     public final int skipBytes(int n) throws IOException {
253         return in.skipBytes(n);
254     }
255 }