< prev index next >

src/share/classes/sun/misc/ObjectInputFilter.java

Print this page




 362          * the filter returns {@link Status#REJECTED Status.REJECTED}.
 363          * If the class is an array type, the class to be matched is the element type.
 364          * Arrays of any number of dimensions are treated the same as the element type.
 365          * For example, a pattern of "{@code !example.Foo}",
 366          * rejects creation of any instance or array of {@code example.Foo}.
 367          * The first pattern that matches, working from left to right, determines
 368          * the {@link Status#ALLOWED Status.ALLOWED}
 369          * or {@link Status#REJECTED Status.REJECTED} result.
 370          * If nothing matches, the result is {@link Status#UNDECIDED Status.UNDECIDED}.
 371          *
 372          * @param pattern the pattern string to parse; not null
 373          * @return a filter to check a class being deserialized; may be null;
 374          *          {@code null} if no patterns
 375          * @throws IllegalArgumentException
 376          *                if a limit is missing the name, or the long value
 377          *                is not a number or is negative,
 378          *                or if the package is missing for ".*" and ".**"
 379          */
 380         public static ObjectInputFilter createFilter(String pattern) {
 381             Objects.requireNonNull(pattern, "pattern");
 382             return Global.createFilter(pattern);













 383         }
 384 
 385         /**
 386          * Implementation of ObjectInputFilter that performs the checks of
 387          * the process-wide serialization filter. If configured, it will be
 388          * used for all ObjectInputStreams that do not set their own filters.
 389          *
 390          */
 391         final static class Global implements ObjectInputFilter {
 392             /**
 393              * The pattern used to create the filter.
 394              */
 395             private final String pattern;
 396             /**
 397              * The list of class filters.
 398              */
 399             private final List<Function<Class<?>, Status>> filters;
 400             /**
 401              * Maximum allowed bytes in the stream.
 402              */
 403             private long maxStreamBytes;
 404             /**
 405              * Maximum depth of the graph allowed.
 406              */
 407             private long maxDepth;
 408             /**
 409              * Maximum number of references in a graph.
 410              */
 411             private long maxReferences;
 412             /**
 413              * Maximum length of any array.
 414              */
 415             private long maxArrayLength;




 416 
 417             /**
 418              * Returns an ObjectInputFilter from a string of patterns.
 419              *
 420              * @param pattern the pattern string to parse


 421              * @return a filter to check a class being deserialized; not null
 422              * @throws IllegalArgumentException if the parameter is malformed
 423              *                if the pattern is missing the name, the long value
 424              *                is not a number or is negative.
 425              */
 426             static ObjectInputFilter createFilter(String pattern) {
 427                 Global filter = new Global(pattern);
 428                 return filter.isEmpty() ? null : filter;
 429             }
 430 
 431             /**
 432              * Construct a new filter from the pattern String.
 433              *
 434              * @param pattern a pattern string of filters


 435              * @throws IllegalArgumentException if the pattern is malformed
 436              */
 437             private Global(String pattern) {
 438                 this.pattern = pattern;

 439 
 440                 maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
 441                 maxDepth = Long.MAX_VALUE;
 442                 maxReferences = Long.MAX_VALUE;
 443                 maxStreamBytes = Long.MAX_VALUE;
 444 
 445                 String[] patterns = pattern.split(";");
 446                 filters = new ArrayList<>(patterns.length);
 447                 for (int i = 0; i < patterns.length; i++) {
 448                     String p = patterns[i];
 449                     int nameLen = p.length();
 450                     if (nameLen == 0) {
 451                         continue;
 452                     }
 453                     if (parseLimit(p)) {
 454                         // If the pattern contained a limit setting, i.e. type=value
 455                         continue;
 456                     }
 457                     boolean negate = p.charAt(0) == '!';
 458 


 576             /**
 577              * {@inheritDoc}
 578              */
 579             @Override
 580             public Status checkInput(FilterInfo filterInfo) {
 581                 if (filterInfo.references() < 0
 582                         || filterInfo.depth() < 0
 583                         || filterInfo.streamBytes() < 0
 584                         || filterInfo.references() > maxReferences
 585                         || filterInfo.depth() > maxDepth
 586                         || filterInfo.streamBytes() > maxStreamBytes) {
 587                     return Status.REJECTED;
 588                 }
 589 
 590                 Class<?> clazz = filterInfo.serialClass();
 591                 if (clazz != null) {
 592                     if (clazz.isArray()) {
 593                         if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > maxArrayLength) {
 594                             // array length is too big
 595                             return Status.REJECTED;




 596                         }
 597                         do {
 598                             // Arrays are decided based on the component type
 599                             clazz = clazz.getComponentType();
 600                         } while (clazz.isArray());
 601                     }
 602 
 603                     if (clazz.isPrimitive())  {
 604                         // Primitive types are undecided; let someone else decide
 605                         return Status.UNDECIDED;
 606                     } else {
 607                         // Find any filter that allowed or rejected the class
 608                         final Class<?> cl = clazz;
 609                         Optional<Status> status = filters.stream()
 610                                 .map(f -> f.apply(cl))
 611                                 .filter(p -> p != Status.UNDECIDED)
 612                                 .findFirst();
 613                         return status.orElse(Status.UNDECIDED);
 614                     }
 615                 }




 362          * the filter returns {@link Status#REJECTED Status.REJECTED}.
 363          * If the class is an array type, the class to be matched is the element type.
 364          * Arrays of any number of dimensions are treated the same as the element type.
 365          * For example, a pattern of "{@code !example.Foo}",
 366          * rejects creation of any instance or array of {@code example.Foo}.
 367          * The first pattern that matches, working from left to right, determines
 368          * the {@link Status#ALLOWED Status.ALLOWED}
 369          * or {@link Status#REJECTED Status.REJECTED} result.
 370          * If nothing matches, the result is {@link Status#UNDECIDED Status.UNDECIDED}.
 371          *
 372          * @param pattern the pattern string to parse; not null
 373          * @return a filter to check a class being deserialized; may be null;
 374          *          {@code null} if no patterns
 375          * @throws IllegalArgumentException
 376          *                if a limit is missing the name, or the long value
 377          *                is not a number or is negative,
 378          *                or if the package is missing for ".*" and ".**"
 379          */
 380         public static ObjectInputFilter createFilter(String pattern) {
 381             Objects.requireNonNull(pattern, "pattern");
 382             return Global.createFilter(pattern, true);
 383         }
 384 
 385         /**
 386          * Returns an ObjectInputFilter from a string of patterns that
 387          * checks only the length for arrays, not the component type.
 388          *
 389          * @param pattern the pattern string to parse; not null
 390          * @return a filter to check a class being deserialized;
 391          *          {@code null} if no patterns
 392          */
 393         public static ObjectInputFilter createFilter2(String pattern) {
 394             Objects.requireNonNull(pattern, "pattern");
 395             return Global.createFilter(pattern, false);
 396         }
 397 
 398         /**
 399          * Implementation of ObjectInputFilter that performs the checks of
 400          * the process-wide serialization filter. If configured, it will be
 401          * used for all ObjectInputStreams that do not set their own filters.
 402          *
 403          */
 404         final static class Global implements ObjectInputFilter {
 405             /**
 406              * The pattern used to create the filter.
 407              */
 408             private final String pattern;
 409             /**
 410              * The list of class filters.
 411              */
 412             private final List<Function<Class<?>, Status>> filters;
 413             /**
 414              * Maximum allowed bytes in the stream.
 415              */
 416             private long maxStreamBytes;
 417             /**
 418              * Maximum depth of the graph allowed.
 419              */
 420             private long maxDepth;
 421             /**
 422              * Maximum number of references in a graph.
 423              */
 424             private long maxReferences;
 425             /**
 426              * Maximum length of any array.
 427              */
 428             private long maxArrayLength;
 429             /**
 430              * True to check the component type for arrays.
 431              */
 432             private final boolean checkComponentType;
 433 
 434             /**
 435              * Returns an ObjectInputFilter from a string of patterns.
 436              *
 437              * @param pattern the pattern string to parse
 438              * @param checkComponentType true if the filter should check
 439              *                           the component type of arrays
 440              * @return a filter to check a class being deserialized; not null
 441              * @throws IllegalArgumentException if the parameter is malformed
 442              *                if the pattern is missing the name, the long value
 443              *                is not a number or is negative.
 444              */
 445             static ObjectInputFilter createFilter(String pattern, boolean checkComponentType) {
 446                 Global filter = new Global(pattern, checkComponentType);
 447                 return filter.isEmpty() ? null : filter;
 448             }
 449 
 450             /**
 451              * Construct a new filter from the pattern String.
 452              *
 453              * @param pattern a pattern string of filters
 454              * @param checkComponentType true if the filter should check
 455              *                           the component type of arrays
 456              * @throws IllegalArgumentException if the pattern is malformed
 457              */
 458             private Global(String pattern, boolean checkComponentType) {
 459                 this.pattern = pattern;
 460                 this.checkComponentType = checkComponentType;
 461 
 462                 maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
 463                 maxDepth = Long.MAX_VALUE;
 464                 maxReferences = Long.MAX_VALUE;
 465                 maxStreamBytes = Long.MAX_VALUE;
 466 
 467                 String[] patterns = pattern.split(";");
 468                 filters = new ArrayList<>(patterns.length);
 469                 for (int i = 0; i < patterns.length; i++) {
 470                     String p = patterns[i];
 471                     int nameLen = p.length();
 472                     if (nameLen == 0) {
 473                         continue;
 474                     }
 475                     if (parseLimit(p)) {
 476                         // If the pattern contained a limit setting, i.e. type=value
 477                         continue;
 478                     }
 479                     boolean negate = p.charAt(0) == '!';
 480 


 598             /**
 599              * {@inheritDoc}
 600              */
 601             @Override
 602             public Status checkInput(FilterInfo filterInfo) {
 603                 if (filterInfo.references() < 0
 604                         || filterInfo.depth() < 0
 605                         || filterInfo.streamBytes() < 0
 606                         || filterInfo.references() > maxReferences
 607                         || filterInfo.depth() > maxDepth
 608                         || filterInfo.streamBytes() > maxStreamBytes) {
 609                     return Status.REJECTED;
 610                 }
 611 
 612                 Class<?> clazz = filterInfo.serialClass();
 613                 if (clazz != null) {
 614                     if (clazz.isArray()) {
 615                         if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > maxArrayLength) {
 616                             // array length is too big
 617                             return Status.REJECTED;
 618                         }
 619                         if (!checkComponentType) {
 620                             // As revised; do not check the component type for arrays
 621                             return Status.UNDECIDED;
 622                         }
 623                         do {
 624                             // Arrays are decided based on the component type
 625                             clazz = clazz.getComponentType();
 626                         } while (clazz.isArray());
 627                     }
 628 
 629                     if (clazz.isPrimitive())  {
 630                         // Primitive types are undecided; let someone else decide
 631                         return Status.UNDECIDED;
 632                     } else {
 633                         // Find any filter that allowed or rejected the class
 634                         final Class<?> cl = clazz;
 635                         Optional<Status> status = filters.stream()
 636                                 .map(f -> f.apply(cl))
 637                                 .filter(p -> p != Status.UNDECIDED)
 638                                 .findFirst();
 639                         return status.orElse(Status.UNDECIDED);
 640                     }
 641                 }


< prev index next >