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