Jackson Annotations Source Code

Jackson is "the Java JSON library" or "the best JSON parser for Java". Or simply as "JSON for Java".

Jackson Annotations Source Code files are provided in the source packge (jackson-annotations-2.12.4-sources.jar). You can download it at Jackson Maven Website.

You can also browse Jackson Annotations Source Code below:

✍: FYIcenter.com

com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.java

package com.fasterxml.jackson.databind.jsontype;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.MapperConfig;

/**
 * Interface for classes that handle validation of class-name - based subtypes used
 * with Polymorphic Deserialization: both via "default typing" and explicit
 * {@code @JsonTypeInfo} when using Java Class name as Type Identifier.
 * The main purpose, initially, is to allow pluggable allow lists to avoid
 * security problems that occur with unlimited class names
 * (See <a href="https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062">
 * this article</a> for full explanation).
 *<p>
 * Calls to methods are done as follows:
 * <ol>
 *  <li>When a deserializer is needed for a polymorphic property (including root values) -- either
 *     for explicitly annotated polymorphic type, or "default typing" -- {@link #validateBaseType}
 *     is called to see if validity can be determined for all possible types: if 
 *     {@link Validity#ALLOWED} is returned no futher checks are made for any subtypes; of
 *     {@link Validity#DENIED} is returned, an exception will be thrown to indicate invalid polymorphic
 *     property
 *   </li>
 *  <li>If neither deny nor allowed was returned for property with specific base type, first time
 *     specific Type Id (Class Name) is encountered, method {@link #validateSubClassName} is called
 *     with resolved class name: it may indicate allowed/denied, resulting in either allowed use or
 *     denial with exception
 *   </li>
 *  <li>If no denial/allowance indicated, class name is resolved to actual {@link Class}, and
 *  {@link #validateSubType(MapperConfig, JavaType, JavaType)} is called: if
 *  {@link Validity#ALLOWED} is returned, usage is accepted; otherwise (denied or indeterminate)
 *  usage is not allowed and exception is thrown
 *   </li>
 * </ol>
 *<p>
 * Notes on implementations: implementations must be thread-safe and shareable (usually meaning they
 * are stateless). Determinations for validity are usually effectively cached on per-property
 * basis (by virtue of subtype deserializers being cached by polymorphic deserializers) so
 * caching at validator level is usually not needed. If caching is used, however, it must be done
 * in thread-safe manner as validators are shared within {@link ObjectMapper} as well as possible
 * across mappers (in case of default/standard validator).
 *<p>
 * Also note that it is strongly recommended that all implementations are based on provided
 * abstract base class, {@link PolymorphicTypeValidator.Base} which contains helper methods
 * and default implementations for returning {@link Validity#INDETERMINATE} for validation
 * methods (to allow only overriding relevant methods implementation cares about)
 *
 * @since 2.10
 */
public abstract class PolymorphicTypeValidator
    implements java.io.Serializable
{
    private static final long serialVersionUID = 1L;

    /**
     * Definition of return values to indicate determination regarding validity.
     */
    public enum Validity {
        /**
         * Value that indicates that Class name or Class is allowed for use without further checking
         */
        ALLOWED,
        /**
         * Value that indicates that Class name or Class is NOT allowed and no further checks are
         * needed or allowed
         */
        DENIED,

        /**
         * Value that indicates that Class name or Class validity can not be confirmed by validator
         * and further checks are needed.
         *<p>
         * Typically if validator can not establish validity from Type Id or Class (name), eventual
         * determination will be {@code DENIED}, for safety reasons.
         */
        INDETERMINATE
        ;
    }

    /**
     * Method called when a property with polymorphic value is encountered, and a
     * {@code TypeResolverBuilder} is needed. Intent is to allow early determination
     * of cases where subtyping is completely denied (for example for security reasons),
     * or, conversely, allowed for allow subtypes (when base type guarantees that all subtypes
     * are known to be safe). Check can be thought of as both optimization (for latter case)
     * and eager-fail (for former case) to give better feedback.
     * 
     * @param config Configuration for resolution: typically will be {@code DeserializationConfig}
     * @param baseType Nominal base type used for polymorphic handling: subtypes MUST be instances
     *   of this type and assignment compatibility is verified by Jackson core
     *
     * @return Determination of general validity of all subtypes of given base type; if
     *    {@link Validity#ALLOWED} returned, all subtypes will automatically be accepted without
     *    further checks; is {@link Validity#DENIED} returned no subtyping allowed at all
     *    (caller will usually throw an exception); otherwise (return {@link Validity#INDETERMINATE})
     *    per sub-type validation calls are made for each new subclass encountered.
     */
    public abstract Validity validateBaseType(MapperConfig<?> config, JavaType baseType);

    /**
     * Method called after intended class name for subtype has been read (and in case of minimal
     * class name, expanded to fully-qualified class name) but before attempt is made to
     * look up actual {@link java.lang.Class} or {@link JavaType}.
     * Validator may be able to
     * determine validity of eventual type (and return {@link Validity#ALLOWED} or
     * {@link Validity#DENIED}) or, if not able to, can defer validation to actual
     * resolved type by returning {@link Validity#INDETERMINATE}.
     *<p>
     * Validator may also choose to indicate denial by throwing a {@link JsonMappingException}
     * (such as {@link com.fasterxml.jackson.databind.exc.InvalidTypeIdException})
     *
     * @param config Configuration for resolution: typically will be {@code DeserializationConfig}
     * @param baseType Nominal base type used for polymorphic handling: subtypes MUST be instances
     *   of this type and assignment compatibility is verified by Jackson core
     * @param subClassName Name of class that will be resolved to {@link java.lang.Class} if
     *   (and only if) validity check is not denied.
     *
     * @return Determination of validity of given class name, as a subtype of given base type:
     *   should NOT return {@code null}
     */
    public abstract Validity validateSubClassName(MapperConfig<?> config, JavaType baseType,
            String subClassName) throws JsonMappingException;

    /**
     * Method called after class name has been resolved to actual type, in cases where previous
     * call to {@link #validateSubClassName} returned {@link Validity#INDETERMINATE}.
     * Validator should be able to determine validity and return appropriate {@link Validity}
     * value, although it may also
     *<p>
     * Validator may also choose to indicate denial by throwing a {@link JsonMappingException}
     * (such as {@link com.fasterxml.jackson.databind.exc.InvalidTypeIdException})
     *
     * @param config Configuration for resolution: typically will be {@code DeserializationConfig}
     * @param baseType Nominal base type used for polymorphic handling: subtypes MUST be instances
     *   of this type and assignment compatibility has been verified by Jackson core
     * @param subType Resolved subtype to validate
     *
     * @return Determination of validity of given class name, as a subtype of given base type:
     *   should NOT return {@code null}
     */
    public abstract Validity validateSubType(MapperConfig<?> config, JavaType baseType,
            JavaType subType) throws JsonMappingException;

    /**
     * Shared base class with partial implementation (with all validation calls returning
     * {@link Validity#INDETERMINATE}) and convenience methods for indicating failure reasons.
     * Use of this base class is strongly recommended over directly implement
     */
    public abstract static class Base
        extends PolymorphicTypeValidator
        implements java.io.Serializable
    {
        private static final long serialVersionUID = 1L;

        @Override
        public Validity validateBaseType(MapperConfig<?> config, JavaType baseType) {
            return Validity.INDETERMINATE;
        }
    
        @Override
        public Validity validateSubClassName(MapperConfig<?> config, JavaType baseType, String subClassName)
                throws JsonMappingException {
            return Validity.INDETERMINATE;
        }
    
        @Override
        public Validity validateSubType(MapperConfig<?> config, JavaType baseType, JavaType subType)
                throws JsonMappingException {
            return Validity.INDETERMINATE;
        }
    }
}

com/fasterxml/jackson/databind/jsontype/PolymorphicTypeValidator.java

 

⇒ Jackson Dataformat Extensions

⇐ Jackson Data Binding Source Code

⇑ Downloading and Reviewing jackson-*.jar

⇑⇑ Jackson - Java JSON library

2022-02-19, 36265👍, 0💬