src/java.base/share/classes/java/io/ObjectInputFilter.java
author rriggs
Wed, 28 Mar 2018 14:15:41 -0400
changeset 49438 879cf9f18688
parent 47722 ce6ff74192fc
child 52427 3c6aa484536c
permissions -rw-r--r--
8197595: Serialization javadoc should link to security best practices Reviewed-by: lancea, mullan, ahgross
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     1
/*
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     2
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     4
 *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    10
 *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    15
 * accompanied this code).
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    16
 *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    20
 *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    23
 * questions.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    24
 */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    25
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    26
package java.io;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    27
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    28
import java.security.AccessController;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    29
import java.security.PrivilegedAction;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    30
import java.security.Security;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    31
import java.util.ArrayList;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    32
import java.util.List;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    33
import java.util.Objects;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    34
import java.util.Optional;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    35
import java.util.function.Function;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    36
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
    37
import jdk.internal.misc.SharedSecrets;
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    38
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    39
/**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    40
 * Filter classes, array lengths, and graph metrics during deserialization.
49438
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    41
 *
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    42
 * <p><strong>Warning: Deserialization of untrusted data is inherently dangerous
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    43
 * and should be avoided. Untrusted data should be carefully validated according to the
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    44
 * "Serialization and Deserialization" section of the
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    45
 * {@extLink secure_coding_guidelines_javase Secure Coding Guidelines for Java SE}.
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    46
 * {@extLink serialization_filter_guide Serialization Filtering} describes best
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    47
 * practices for defensive use of serial filters.
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    48
 * </strong></p>
879cf9f18688 8197595: Serialization javadoc should link to security best practices
rriggs
parents: 47722
diff changeset
    49
 *
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    50
 * If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    51
 * method is called to validate classes, the length of each array,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    52
 * the number of objects being read from the stream, the depth of the graph,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    53
 * and the total number of bytes read from the stream.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    54
 * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    55
 * A filter can be set via {@link ObjectInputStream#setObjectInputFilter setObjectInputFilter}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    56
 * for an individual ObjectInputStream.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    57
 * A filter can be set via {@link Config#setSerialFilter(ObjectInputFilter) Config.setSerialFilter}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    58
 * to affect every {@code ObjectInputStream} that does not otherwise set a filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    59
 * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    60
 * A filter determines whether the arguments are {@link Status#ALLOWED ALLOWED}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    61
 * or {@link Status#REJECTED REJECTED} and should return the appropriate status.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    62
 * If the filter cannot determine the status it should return
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    63
 * {@link Status#UNDECIDED UNDECIDED}.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    64
 * Filters should be designed for the specific use case and expected types.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    65
 * A filter designed for a particular use may be passed a class that is outside
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    66
 * of the scope of the filter. If the purpose of the filter is to black-list classes
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    67
 * then it can reject a candidate class that matches and report UNDECIDED for others.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    68
 * A filter may be called with class equals {@code null}, {@code arrayLength} equal -1,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    69
 * the depth, number of references, and stream size and return a status
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    70
 * that reflects only one or only some of the values.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    71
 * This allows a filter to specific about the choice it is reporting and
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    72
 * to use other filters without forcing either allowed or rejected status.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    73
 *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    74
 * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    75
 * Typically, a custom filter should check if a process-wide filter
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    76
 * is configured and defer to it if so. For example,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    77
 * <pre>{@code
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    78
 * ObjectInputFilter.Status checkInput(FilterInfo info) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    79
 *     ObjectInputFilter serialFilter = ObjectInputFilter.Config.getSerialFilter();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    80
 *     if (serialFilter != null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    81
 *         ObjectInputFilter.Status status = serialFilter.checkInput(info);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    82
 *         if (status != ObjectInputFilter.Status.UNDECIDED) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    83
 *             // The process-wide filter overrides this filter
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    84
 *             return status;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    85
 *         }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    86
 *     }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    87
 *     if (info.serialClass() != null &&
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    88
 *         Remote.class.isAssignableFrom(info.serialClass())) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    89
 *         return Status.REJECTED;      // Do not allow Remote objects
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    90
 *     }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    91
 *     return Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    92
 * }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    93
 *}</pre>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    94
 * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    95
 * Unless otherwise noted, passing a {@code null} argument to a
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    96
 * method in this interface and its nested classes will cause a
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    97
 * {@link NullPointerException} to be thrown.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    98
 *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
    99
 * @see ObjectInputStream#setObjectInputFilter(ObjectInputFilter)
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   100
 * @since 9
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   101
 */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   102
@FunctionalInterface
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   103
public interface ObjectInputFilter {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   104
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   105
    /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   106
     * Check the class, array length, number of object references, depth,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   107
     * stream size, and other available filtering information.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   108
     * Implementations of this method check the contents of the object graph being created
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   109
     * during deserialization. The filter returns {@link Status#ALLOWED Status.ALLOWED},
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   110
     * {@link Status#REJECTED Status.REJECTED}, or {@link Status#UNDECIDED Status.UNDECIDED}.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   111
     *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   112
     * @param filterInfo provides information about the current object being deserialized,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   113
     *             if any, and the status of the {@link ObjectInputStream}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   114
     * @return  {@link Status#ALLOWED Status.ALLOWED} if accepted,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   115
     *          {@link Status#REJECTED Status.REJECTED} if rejected,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   116
     *          {@link Status#UNDECIDED Status.UNDECIDED} if undecided.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   117
     */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   118
    Status checkInput(FilterInfo filterInfo);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   119
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   120
    /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   121
     * FilterInfo provides access to information about the current object
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   122
     * being deserialized and the status of the {@link ObjectInputStream}.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   123
     * @since 9
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   124
     */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   125
    interface FilterInfo {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   126
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   127
         * The class of an object being deserialized.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   128
         * For arrays, it is the array type.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   129
         * For example, the array class name of a 2 dimensional array of strings is
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   130
         * "{@code [[Ljava.lang.String;}".
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   131
         * To check the array's element type, iteratively use
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   132
         * {@link Class#getComponentType() Class.getComponentType} while the result
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   133
         * is an array and then check the class.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   134
         * The {@code serialClass is null} in the case where a new object is not being
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   135
         * created and to give the filter a chance to check the depth, number of
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   136
         * references to existing objects, and the stream size.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   137
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   138
         * @return class of an object being deserialized; may be null
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   139
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   140
        Class<?> serialClass();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   141
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   142
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   143
         * The number of array elements when deserializing an array of the class.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   144
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   145
         * @return the non-negative number of array elements when deserializing
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   146
         * an array of the class, otherwise -1
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   147
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   148
        long arrayLength();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   149
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   150
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   151
         * The current depth.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   152
         * The depth starts at {@code 1} and increases for each nested object and
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   153
         * decrements when each nested object returns.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   154
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   155
         * @return the current depth
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   156
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   157
        long depth();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   158
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   159
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   160
         * The current number of object references.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   161
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   162
         * @return the non-negative current number of object references
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   163
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   164
        long references();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   165
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   166
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   167
         * The current number of bytes consumed.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   168
         * @implSpec  {@code streamBytes} is implementation specific
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   169
         * and may not be directly related to the object in the stream
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   170
         * that caused the callback.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   171
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   172
         * @return the non-negative current number of bytes consumed
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   173
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   174
        long streamBytes();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   175
    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   176
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   177
    /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   178
     * The status of a check on the class, array length, number of references,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   179
     * depth, and stream size.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   180
     *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   181
     * @since 9
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   182
     */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   183
    enum Status {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   184
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   185
         * The status is undecided, not allowed and not rejected.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   186
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   187
        UNDECIDED,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   188
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   189
         * The status is allowed.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   190
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   191
        ALLOWED,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   192
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   193
         * The status is rejected.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   194
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   195
        REJECTED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   196
    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   197
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   198
    /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   199
     * A utility class to set and get the process-wide filter or create a filter
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   200
     * from a pattern string. If a process-wide filter is set, it will be
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   201
     * used for each {@link ObjectInputStream} that does not set its own filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   202
     * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   203
     * When setting the filter, it should be stateless and idempotent,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   204
     * reporting the same result when passed the same arguments.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   205
     * <p>
42223
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   206
     * The filter is configured during the initialization of the {@code ObjectInputFilter.Config}
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   207
     * class. For example, by calling {@link #getSerialFilter() Config.getSerialFilter}.
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   208
     * If the system property {@code jdk.serialFilter} is defined, it is used
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   209
     * to configure the filter.
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   210
     * If the system property is not defined, and the {@link java.security.Security}
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   211
     * property {@code jdk.serialFilter} is defined then it is used to configure the filter.
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   212
     * Otherwise, the filter is not configured during initialization.
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   213
     * The syntax for each property is the same as for the
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   214
     * {@link #createFilter(String) createFilter} method.
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   215
     * If a filter is not configured, it can be set with
a55f957f6e4e 8169645: ObjectInputFilter Config spec is ambiguous regarding overriding the filter via System properties
rriggs
parents: 41230
diff changeset
   216
     * {@link #setSerialFilter(ObjectInputFilter) Config.setSerialFilter}.
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   217
     *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   218
     * @since 9
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   219
     */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   220
    final class Config {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   221
        /* No instances. */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   222
        private Config() {}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   223
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   224
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   225
         * Lock object for process-wide filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   226
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   227
        private final static Object serialFilterLock = new Object();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   228
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   229
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   230
         * Debug: Logger
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   231
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   232
        private final static System.Logger configLog;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   233
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   234
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   235
         * Logger for debugging.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   236
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   237
        static void filterLog(System.Logger.Level level, String msg, Object... args) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   238
            if (configLog != null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   239
                configLog.log(level, msg, args);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   240
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   241
        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   242
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   243
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   244
         * The name for the process-wide deserialization filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   245
         * Used as a system property and a java.security.Security property.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   246
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   247
        private final static String SERIAL_FILTER_PROPNAME = "jdk.serialFilter";
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   248
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   249
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   250
         * The process-wide filter; may be null.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   251
         * Lookup the filter in java.security.Security or
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   252
         * the system property.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   253
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   254
        private final static ObjectInputFilter configuredFilter;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   255
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   256
        static {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   257
            configuredFilter = AccessController
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   258
                    .doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   259
                        String props = System.getProperty(SERIAL_FILTER_PROPNAME);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   260
                        if (props == null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   261
                            props = Security.getProperty(SERIAL_FILTER_PROPNAME);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   262
                        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   263
                        if (props != null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   264
                            System.Logger log =
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   265
                                    System.getLogger("java.io.serialization");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   266
                            log.log(System.Logger.Level.INFO,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   267
                                    "Creating serialization filter from {0}", props);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   268
                            try {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   269
                                return createFilter(props);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   270
                            } catch (RuntimeException re) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   271
                                log.log(System.Logger.Level.ERROR,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   272
                                        "Error configuring filter: {0}", re);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   273
                            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   274
                        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   275
                        return null;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   276
                    });
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   277
            configLog = (configuredFilter != null) ? System.getLogger("java.io.serialization") : null;
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   278
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   279
            // Setup shared secrets for RegistryImpl to use.
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   280
            SharedSecrets.setJavaObjectInputFilterAccess(Config::createFilter2);
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   281
        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   282
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   283
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   284
         * Current configured filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   285
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   286
        private static ObjectInputFilter serialFilter = configuredFilter;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   287
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   288
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   289
         * Returns the process-wide serialization filter or {@code null} if not configured.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   290
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   291
         * @return the process-wide serialization filter or {@code null} if not configured
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   292
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   293
        public static ObjectInputFilter getSerialFilter() {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   294
            synchronized (serialFilterLock) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   295
                return serialFilter;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   296
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   297
        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   298
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   299
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   300
         * Set the process-wide filter if it has not already been configured or set.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   301
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   302
         * @param filter the serialization filter to set as the process-wide filter; not null
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   303
         * @throws SecurityException if there is security manager and the
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   304
         *       {@code SerializablePermission("serialFilter")} is not granted
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   305
         * @throws IllegalStateException if the filter has already been set {@code non-null}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   306
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   307
        public static void setSerialFilter(ObjectInputFilter filter) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   308
            Objects.requireNonNull(filter, "filter");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   309
            SecurityManager sm = System.getSecurityManager();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   310
            if (sm != null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   311
                sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   312
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   313
            synchronized (serialFilterLock) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   314
                if (serialFilter != null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   315
                    throw new IllegalStateException("Serial filter can only be set once");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   316
                }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   317
                serialFilter = filter;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   318
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   319
        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   320
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   321
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   322
         * Returns an ObjectInputFilter from a string of patterns.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   323
         * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   324
         * Patterns are separated by ";" (semicolon). Whitespace is significant and
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   325
         * is considered part of the pattern.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   326
         * If a pattern includes an equals assignment, "{@code =}" it sets a limit.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   327
         * If a limit appears more than once the last value is used.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   328
         * <ul>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   329
         *     <li>maxdepth={@code value} - the maximum depth of a graph</li>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   330
         *     <li>maxrefs={@code value}  - the maximum number of internal references</li>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   331
         *     <li>maxbytes={@code value} - the maximum number of bytes in the input stream</li>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   332
         *     <li>maxarray={@code value} - the maximum array length allowed</li>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   333
         * </ul>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   334
         * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   335
         * Other patterns match or reject class or package name
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   336
         * as returned from {@link Class#getName() Class.getName()} and
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   337
         * if an optional module name is present
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44263
diff changeset
   338
         * {@link Module#getName() class.getModule().getName()}.
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   339
         * Note that for arrays the element type is used in the pattern,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   340
         * not the array type.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   341
         * <ul>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   342
         * <li>If the pattern starts with "!", the class is rejected if the remaining pattern is matched;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   343
         *     otherwise the class is allowed if the pattern matches.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   344
         * <li>If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   345
         *     if the module name matches the module name of the class then
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   346
         *     the remaining pattern is matched with the class name.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   347
         *     If there is no "/", the module name is not compared.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   348
         * <li>If the pattern ends with ".**" it matches any class in the package and all subpackages.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   349
         * <li>If the pattern ends with ".*" it matches any class in the package.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   350
         * <li>If the pattern ends with "*", it matches any class with the pattern as a prefix.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   351
         * <li>If the pattern is equal to the class name, it matches.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   352
         * <li>Otherwise, the pattern is not matched.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   353
         * </ul>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   354
         * <p>
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   355
         * The resulting filter performs the limit checks and then
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   356
         * tries to match the class, if any. If any of the limits are exceeded,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   357
         * the filter returns {@link Status#REJECTED Status.REJECTED}.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   358
         * If the class is an array type, the class to be matched is the element type.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   359
         * Arrays of any number of dimensions are treated the same as the element type.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   360
         * For example, a pattern of "{@code !example.Foo}",
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   361
         * rejects creation of any instance or array of {@code example.Foo}.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   362
         * The first pattern that matches, working from left to right, determines
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   363
         * the {@link Status#ALLOWED Status.ALLOWED}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   364
         * or {@link Status#REJECTED Status.REJECTED} result.
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   365
         * If the limits are not exceeded and no pattern matches the class,
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   366
         * the result is {@link Status#UNDECIDED Status.UNDECIDED}.
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   367
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   368
         * @param pattern the pattern string to parse; not null
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   369
         * @return a filter to check a class being deserialized;
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   370
         *          {@code null} if no patterns
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   371
         * @throws IllegalArgumentException if the pattern string is illegal or
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   372
         *         malformed and cannot be parsed.
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   373
         *         In particular, if any of the following is true:
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   374
         * <ul>
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   375
         * <li>   if a limit is missing the name or the name is not one of
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   376
         *        "maxdepth", "maxrefs", "maxbytes", or "maxarray"
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   377
         * <li>   if the value of the limit can not be parsed by
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   378
         *        {@link Long#parseLong Long.parseLong} or is negative
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   379
         * <li>   if the pattern contains "/" and the module name is missing
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   380
         *        or the remaining pattern is empty
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   381
         * <li>   if the package is missing for ".*" and ".**"
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   382
         * </ul>
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   383
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   384
        public static ObjectInputFilter createFilter(String pattern) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   385
            Objects.requireNonNull(pattern, "pattern");
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   386
            return Global.createFilter(pattern, true);
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   387
        }
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   388
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   389
        /**
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   390
         * Returns an ObjectInputFilter from a string of patterns that
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   391
         * checks only the length for arrays, not the component type.
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   392
         *
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   393
         * @param pattern the pattern string to parse; not null
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   394
         * @return a filter to check a class being deserialized;
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   395
         *          {@code null} if no patterns
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   396
         */
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   397
        static ObjectInputFilter createFilter2(String pattern) {
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   398
            Objects.requireNonNull(pattern, "pattern");
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   399
            return Global.createFilter(pattern, false);
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   400
        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   401
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   402
        /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   403
         * Implementation of ObjectInputFilter that performs the checks of
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   404
         * the process-wide serialization filter. If configured, it will be
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   405
         * used for all ObjectInputStreams that do not set their own filters.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   406
         *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   407
         */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   408
        final static class Global implements ObjectInputFilter {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   409
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   410
             * The pattern used to create the filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   411
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   412
            private final String pattern;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   413
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   414
             * The list of class filters.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   415
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   416
            private final List<Function<Class<?>, Status>> filters;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   417
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   418
             * Maximum allowed bytes in the stream.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   419
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   420
            private long maxStreamBytes;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   421
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   422
             * Maximum depth of the graph allowed.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   423
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   424
            private long maxDepth;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   425
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   426
             * Maximum number of references in a graph.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   427
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   428
            private long maxReferences;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   429
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   430
             * Maximum length of any array.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   431
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   432
            private long maxArrayLength;
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   433
            /**
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   434
             * True to check the component type for arrays.
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   435
             */
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   436
            private final boolean checkComponentType;
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   437
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   438
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   439
             * Returns an ObjectInputFilter from a string of patterns.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   440
             *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   441
             * @param pattern the pattern string to parse
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   442
             * @param checkComponentType true if the filter should check
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   443
             *                           the component type of arrays
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   444
             * @return a filter to check a class being deserialized;
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   445
             *          {@code null} if no patterns
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   446
             * @throws IllegalArgumentException if the parameter is malformed
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   447
             *                if the pattern is missing the name, the long value
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   448
             *                is not a number or is negative.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   449
             */
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   450
            static ObjectInputFilter createFilter(String pattern, boolean checkComponentType) {
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   451
                try {
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   452
                    return new Global(pattern, checkComponentType);
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   453
                } catch (UnsupportedOperationException uoe) {
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   454
                    // no non-empty patterns
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   455
                    return null;
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   456
                }
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   457
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   458
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   459
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   460
             * Construct a new filter from the pattern String.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   461
             *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   462
             * @param pattern a pattern string of filters
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   463
             * @param checkComponentType true if the filter should check
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   464
             *                           the component type of arrays
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   465
             * @throws IllegalArgumentException if the pattern is malformed
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   466
             * @throws UnsupportedOperationException if there are no non-empty patterns
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   467
             */
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   468
            private Global(String pattern, boolean checkComponentType) {
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   469
                boolean hasLimits = false;
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   470
                this.pattern = pattern;
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   471
                this.checkComponentType = checkComponentType;
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   472
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   473
                maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   474
                maxDepth = Long.MAX_VALUE;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   475
                maxReferences = Long.MAX_VALUE;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   476
                maxStreamBytes = Long.MAX_VALUE;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   477
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   478
                String[] patterns = pattern.split(";");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   479
                filters = new ArrayList<>(patterns.length);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   480
                for (int i = 0; i < patterns.length; i++) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   481
                    String p = patterns[i];
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   482
                    int nameLen = p.length();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   483
                    if (nameLen == 0) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   484
                        continue;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   485
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   486
                    if (parseLimit(p)) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   487
                        // If the pattern contained a limit setting, i.e. type=value
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   488
                        hasLimits = true;
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   489
                        continue;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   490
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   491
                    boolean negate = p.charAt(0) == '!';
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   492
                    int poffset = negate ? 1 : 0;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   493
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   494
                    // isolate module name, if any
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   495
                    int slash = p.indexOf('/', poffset);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   496
                    if (slash == poffset) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   497
                        throw new IllegalArgumentException("module name is missing in: \"" + pattern + "\"");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   498
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   499
                    final String moduleName = (slash >= 0) ? p.substring(poffset, slash) : null;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   500
                    poffset = (slash >= 0) ? slash + 1 : poffset;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   501
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   502
                    final Function<Class<?>, Status> patternFilter;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   503
                    if (p.endsWith("*")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   504
                        // Wildcard cases
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   505
                        if (p.endsWith(".*")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   506
                            // Pattern is a package name with a wildcard
47722
ce6ff74192fc 8190733: Use Class::getPackageName in java.base implementation
mchung
parents: 47216
diff changeset
   507
                            final String pkg = p.substring(poffset, nameLen - 2);
ce6ff74192fc 8190733: Use Class::getPackageName in java.base implementation
mchung
parents: 47216
diff changeset
   508
                            if (pkg.isEmpty()) {
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   509
                                throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   510
                            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   511
                            if (negate) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   512
                                // A Function that fails if the class starts with the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   513
                                patternFilter = c -> matchesPackage(c, pkg) ? Status.REJECTED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   514
                            } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   515
                                // A Function that succeeds if the class starts with the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   516
                                patternFilter = c -> matchesPackage(c, pkg) ? Status.ALLOWED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   517
                            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   518
                        } else if (p.endsWith(".**")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   519
                            // Pattern is a package prefix with a double wildcard
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   520
                            final String pkgs = p.substring(poffset, nameLen - 2);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   521
                            if (pkgs.length() < 2) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   522
                                throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   523
                            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   524
                            if (negate) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   525
                                // A Function that fails if the class starts with the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   526
                                patternFilter = c -> c.getName().startsWith(pkgs) ? Status.REJECTED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   527
                            } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   528
                                // A Function that succeeds if the class starts with the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   529
                                patternFilter = c -> c.getName().startsWith(pkgs) ? Status.ALLOWED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   530
                            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   531
                        } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   532
                            // Pattern is a classname (possibly empty) with a trailing wildcard
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   533
                            final String className = p.substring(poffset, nameLen - 1);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   534
                            if (negate) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   535
                                // A Function that fails if the class starts with the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   536
                                patternFilter = c -> c.getName().startsWith(className) ? Status.REJECTED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   537
                            } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   538
                                // A Function that succeeds if the class starts with the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   539
                                patternFilter = c -> c.getName().startsWith(className) ? Status.ALLOWED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   540
                            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   541
                        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   542
                    } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   543
                        final String name = p.substring(poffset);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   544
                        if (name.isEmpty()) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   545
                            throw new IllegalArgumentException("class or package missing in: \"" + pattern + "\"");
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   546
                        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   547
                        // Pattern is a class name
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   548
                        if (negate) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   549
                            // A Function that fails if the class equals the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   550
                            patternFilter = c -> c.getName().equals(name) ? Status.REJECTED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   551
                        } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   552
                            // A Function that succeeds if the class equals the pattern, otherwise don't care
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   553
                            patternFilter = c -> c.getName().equals(name) ? Status.ALLOWED : Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   554
                        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   555
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   556
                    // If there is a moduleName, combine the module name check with the package/class check
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   557
                    if (moduleName == null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   558
                        filters.add(patternFilter);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   559
                    } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   560
                        filters.add(c -> moduleName.equals(c.getModule().getName()) ? patternFilter.apply(c) : Status.UNDECIDED);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   561
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   562
                }
42446
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   563
                if (filters.isEmpty() && !hasLimits) {
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   564
                    throw new UnsupportedOperationException("no non-empty patterns");
397681315009 8170291: Unpredictable results of j.i.ObjectInputFilter::createFilter
rriggs
parents: 42223
diff changeset
   565
                }
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   566
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   567
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   568
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   569
             * Parse out a limit for one of maxarray, maxdepth, maxbytes, maxreferences.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   570
             *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   571
             * @param pattern a string with a type name, '=' and a value
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   572
             * @return {@code true} if a limit was parsed, else {@code false}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   573
             * @throws IllegalArgumentException if the pattern is missing
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   574
             *                the name, the Long value is not a number or is negative.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   575
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   576
            private boolean parseLimit(String pattern) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   577
                int eqNdx = pattern.indexOf('=');
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   578
                if (eqNdx < 0) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   579
                    // not a limit pattern
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   580
                    return false;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   581
                }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   582
                String valueString = pattern.substring(eqNdx + 1);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   583
                if (pattern.startsWith("maxdepth=")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   584
                    maxDepth = parseValue(valueString);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   585
                } else if (pattern.startsWith("maxarray=")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   586
                    maxArrayLength = parseValue(valueString);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   587
                } else if (pattern.startsWith("maxrefs=")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   588
                    maxReferences = parseValue(valueString);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   589
                } else if (pattern.startsWith("maxbytes=")) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   590
                    maxStreamBytes = parseValue(valueString);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   591
                } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   592
                    throw new IllegalArgumentException("unknown limit: " + pattern.substring(0, eqNdx));
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   593
                }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   594
                return true;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   595
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   596
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   597
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   598
             * Parse the value of a limit and check that it is non-negative.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   599
             * @param string inputstring
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   600
             * @return the parsed value
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   601
             * @throws IllegalArgumentException if parsing the value fails or the value is negative
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   602
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   603
            private static long parseValue(String string) throws IllegalArgumentException {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   604
                // Parse a Long from after the '=' to the end
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   605
                long value = Long.parseLong(string);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   606
                if (value < 0) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   607
                    throw new IllegalArgumentException("negative limit: " + string);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   608
                }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   609
                return value;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   610
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   611
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   612
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   613
             * {@inheritDoc}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   614
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   615
            @Override
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   616
            public Status checkInput(FilterInfo filterInfo) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   617
                if (filterInfo.references() < 0
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   618
                        || filterInfo.depth() < 0
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   619
                        || filterInfo.streamBytes() < 0
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   620
                        || filterInfo.references() > maxReferences
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   621
                        || filterInfo.depth() > maxDepth
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   622
                        || filterInfo.streamBytes() > maxStreamBytes) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   623
                    return Status.REJECTED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   624
                }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   625
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   626
                Class<?> clazz = filterInfo.serialClass();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   627
                if (clazz != null) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   628
                    if (clazz.isArray()) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   629
                        if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > maxArrayLength) {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   630
                            // array length is too big
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   631
                            return Status.REJECTED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   632
                        }
46160
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   633
                        if (!checkComponentType) {
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   634
                            // As revised; do not check the component type for arrays
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   635
                            return Status.UNDECIDED;
c647e44ea1b9 8185346: Relax RMI Registry Serial Filter to allow arrays of any type
rriggs
parents: 44545
diff changeset
   636
                        }
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   637
                        do {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   638
                            // Arrays are decided based on the component type
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   639
                            clazz = clazz.getComponentType();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   640
                        } while (clazz.isArray());
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   641
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   642
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   643
                    if (clazz.isPrimitive())  {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   644
                        // Primitive types are undecided; let someone else decide
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   645
                        return Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   646
                    } else {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   647
                        // Find any filter that allowed or rejected the class
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   648
                        final Class<?> cl = clazz;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   649
                        Optional<Status> status = filters.stream()
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   650
                                .map(f -> f.apply(cl))
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   651
                                .filter(p -> p != Status.UNDECIDED)
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   652
                                .findFirst();
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   653
                        return status.orElse(Status.UNDECIDED);
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   654
                    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   655
                }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   656
                return Status.UNDECIDED;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   657
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   658
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   659
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   660
             * Returns {@code true} if the class is in the package.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   661
             *
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   662
             * @param c   a class
47722
ce6ff74192fc 8190733: Use Class::getPackageName in java.base implementation
mchung
parents: 47216
diff changeset
   663
             * @param pkg a package name
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   664
             * @return {@code true} if the class is in the package,
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   665
             * otherwise {@code false}
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   666
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   667
            private static boolean matchesPackage(Class<?> c, String pkg) {
47722
ce6ff74192fc 8190733: Use Class::getPackageName in java.base implementation
mchung
parents: 47216
diff changeset
   668
                return pkg.equals(c.getPackageName());
41230
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   669
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   670
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   671
            /**
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   672
             * Returns the pattern used to create this filter.
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   673
             * @return the pattern used to create this filter
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   674
             */
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   675
            @Override
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   676
            public String toString() {
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   677
                return pattern;
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   678
            }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   679
        }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   680
    }
0a8c1ba2b6fb 8155760: Implement Serialization Filtering
rriggs
parents:
diff changeset
   681
}