Class ValidatingObjectInputStream

  • All Implemented Interfaces:
    java.io.Closeable, java.io.DataInput, java.io.ObjectInput, java.io.ObjectStreamConstants, java.lang.AutoCloseable

    public class ValidatingObjectInputStream
    extends java.io.ObjectInputStream
    An ObjectInputStream that's restricted to deserialize a limited set of classes.

    Various accept/reject methods allow for specifying which classes can be deserialized.

    Reading safely

    Here is the only way to safely read a HashMap of String keys and Integer values:

    
     // Defining Object fixture
     final HashMap<String, Integer> map1 = new HashMap<>();
     map1.put("1", 1);
     // Writing serialized fixture
     final byte[] byteArray;
     try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             final ObjectOutputStream oos = new ObjectOutputStream(baos)) {
         oos.writeObject(map1);
         oos.flush();
         byteArray = baos.toByteArray();
     }
     // Reading
     try (ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
             ValidatingObjectInputStream vois = ValidatingObjectInputStream.builder()
                 .accept(HashMap.class, Number.class, Integer.class)
                 .setInputStream(bais)
                 .get()) {
         // String.class is automatically accepted
         final HashMap<String, Integer> map2 = (HashMap<String, Integer>) vois.readObject();
         assertEquals(map1, map2);
     }
     // Reusing a configuration
     final ObjectStreamClassPredicate predicate = new ObjectStreamClassPredicate()
         .accept(HashMap.class, Number.class, Integer.class);
     try (ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
             ValidatingObjectInputStream vois = ValidatingObjectInputStream.builder()
                 .setPredicate(predicate)
                 .setInputStream(bais)
                 .get()) {
         // String.class is automatically accepted
         final HashMap<String, Integer> map2 = (HashMap<String, Integer>) vois.readObject();
         assertEquals(map1, map2);
     }
     

    Design inspired by a IBM DeveloperWorks Article.

    Since:
    2.5
    • Field Summary

      • Fields inherited from interface java.io.ObjectStreamConstants

        baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, SC_BLOCK_DATA, SC_ENUM, SC_EXTERNALIZABLE, SC_SERIALIZABLE, SC_WRITE_METHOD, SERIAL_FILTER_PERMISSION, STREAM_MAGIC, STREAM_VERSION, SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION, TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS, TC_CLASSDESC, TC_ENDBLOCKDATA, TC_ENUM, TC_EXCEPTION, TC_LONGSTRING, TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE, TC_RESET, TC_STRING
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      ValidatingObjectInputStream accept​(java.lang.Class<?>... classes)
      Accepts the specified classes for deserialization, unless they are otherwise rejected.
      ValidatingObjectInputStream accept​(java.lang.String... patterns)
      Accepts the wildcard specified classes for deserialization, unless they are otherwise rejected.
      ValidatingObjectInputStream accept​(java.util.regex.Pattern pattern)
      Accepts class names that match the supplied pattern for deserialization, unless they are otherwise rejected.
      ValidatingObjectInputStream accept​(ClassNameMatcher matcher)
      Accepts class names where the supplied ClassNameMatcher matches for deserialization, unless they are otherwise rejected.
      static ValidatingObjectInputStream.Builder builder()
      protected void invalidClassNameFound​(java.lang.String className)
      Called to throw InvalidClassException if an invalid class name is found during deserialization.
      <T> T readObjectCast()
      Delegates to ObjectInputStream.readObject() and casts to the generic T.
      ValidatingObjectInputStream reject​(java.lang.Class<?>... classes)
      Rejects the specified classes for deserialization, even if they are otherwise accepted.
      ValidatingObjectInputStream reject​(java.lang.String... patterns)
      Rejects the wildcard specified classes for deserialization, even if they are otherwise accepted.
      ValidatingObjectInputStream reject​(java.util.regex.Pattern pattern)
      Rejects class names that match the supplied pattern for deserialization, even if they are otherwise accepted.
      ValidatingObjectInputStream reject​(ClassNameMatcher matcher)
      Rejects class names where the supplied ClassNameMatcher matches for deserialization, even if they are otherwise accepted.
      protected java.lang.Class<?> resolveClass​(java.io.ObjectStreamClass osc)  
      • Methods inherited from class java.io.ObjectInputStream

        available, close, defaultReadObject, enableResolveObject, getObjectInputFilter, read, read, readBoolean, readByte, readChar, readClassDescriptor, readDouble, readFields, readFloat, readFully, readFully, readInt, readLine, readLong, readObject, readObjectOverride, readShort, readStreamHeader, readUnshared, readUnsignedByte, readUnsignedShort, readUTF, registerValidation, resolveObject, resolveProxyClass, setObjectInputFilter, skipBytes
      • Methods inherited from class java.io.InputStream

        mark, markSupported, nullInputStream, read, readAllBytes, readNBytes, readNBytes, reset, skip, transferTo
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • Methods inherited from interface java.io.ObjectInput

        read, skip
    • Constructor Detail

      • ValidatingObjectInputStream

        @Deprecated
        public ValidatingObjectInputStream​(java.io.InputStream input)
                                    throws java.io.IOException
        Deprecated.
        Constructs an instance to deserialize the specified input stream. At least one accept method needs to be called to specify which classes can be deserialized, as by default no classes are accepted.
        Parameters:
        input - an input stream
        Throws:
        java.io.IOException - if an I/O error occurs while reading stream header
    • Method Detail

      • accept

        public ValidatingObjectInputStream accept​(java.lang.Class<?>... classes)
        Accepts the specified classes for deserialization, unless they are otherwise rejected.

        The reject list takes precedence over the accept list.

        Parameters:
        classes - Classes to accept
        Returns:
        this instance.
      • accept

        public ValidatingObjectInputStream accept​(ClassNameMatcher matcher)
        Accepts class names where the supplied ClassNameMatcher matches for deserialization, unless they are otherwise rejected.

        The reject list takes precedence over the accept list.

        Parameters:
        matcher - a class name matcher to accept objects.
        Returns:
        this instance.
      • accept

        public ValidatingObjectInputStream accept​(java.util.regex.Pattern pattern)
        Accepts class names that match the supplied pattern for deserialization, unless they are otherwise rejected.

        The reject list takes precedence over the accept list.

        Parameters:
        pattern - a Pattern for compiled regular expression.
        Returns:
        this instance.
      • accept

        public ValidatingObjectInputStream accept​(java.lang.String... patterns)
        Accepts the wildcard specified classes for deserialization, unless they are otherwise rejected.

        The reject list takes precedence over the accept list.

        Parameters:
        patterns - Wildcard file name patterns as defined by FilenameUtils.wildcardMatch.
        Returns:
        this instance.
      • invalidClassNameFound

        protected void invalidClassNameFound​(java.lang.String className)
                                      throws java.io.InvalidClassException
        Called to throw InvalidClassException if an invalid class name is found during deserialization. Can be overridden, for example to log those class names.
        Parameters:
        className - name of the invalid class.
        Throws:
        java.io.InvalidClassException - Thrown with a message containing the class name.
      • readObjectCast

        public <T> T readObjectCast()
                             throws java.lang.ClassNotFoundException,
                                    java.io.IOException
        Delegates to ObjectInputStream.readObject() and casts to the generic T.
        Type Parameters:
        T - The return type.
        Returns:
        Result from ObjectInputStream.readObject().
        Throws:
        java.lang.ClassNotFoundException - Thrown by ObjectInputStream.readObject().
        java.io.IOException - Thrown by ObjectInputStream.readObject().
        java.lang.ClassCastException - Thrown when ObjectInputStream.readObject() does not match T.
        Since:
        2.18.0
      • reject

        public ValidatingObjectInputStream reject​(java.lang.Class<?>... classes)
        Rejects the specified classes for deserialization, even if they are otherwise accepted.

        The reject list takes precedence over the accept list.

        Parameters:
        classes - Classes to reject.
        Returns:
        this instance.
      • reject

        public ValidatingObjectInputStream reject​(ClassNameMatcher matcher)
        Rejects class names where the supplied ClassNameMatcher matches for deserialization, even if they are otherwise accepted.

        The reject list takes precedence over the accept list.

        Parameters:
        matcher - a class name matcher to reject objects.
        Returns:
        this instance.
      • reject

        public ValidatingObjectInputStream reject​(java.util.regex.Pattern pattern)
        Rejects class names that match the supplied pattern for deserialization, even if they are otherwise accepted.

        The reject list takes precedence over the accept list.

        Parameters:
        pattern - a Pattern for compiled regular expression.
        Returns:
        this instance.
      • reject

        public ValidatingObjectInputStream reject​(java.lang.String... patterns)
        Rejects the wildcard specified classes for deserialization, even if they are otherwise accepted.

        The reject list takes precedence over the accept list.

        Parameters:
        patterns - An array of wildcard file name patterns as defined by FilenameUtils.wildcardMatch
        Returns:
        this instance.
      • resolveClass

        protected java.lang.Class<?> resolveClass​(java.io.ObjectStreamClass osc)
                                           throws java.io.IOException,
                                                  java.lang.ClassNotFoundException
        Overrides:
        resolveClass in class java.io.ObjectInputStream
        Throws:
        java.io.IOException
        java.lang.ClassNotFoundException