diff --git a/src/main/java/com/fasterxml/jackson/core/StreamReadConstraints.java b/src/main/java/com/fasterxml/jackson/core/StreamReadConstraints.java
index 6da6770ad9..6a67decf51 100644
--- a/src/main/java/com/fasterxml/jackson/core/StreamReadConstraints.java
+++ b/src/main/java/com/fasterxml/jackson/core/StreamReadConstraints.java
@@ -16,6 +16,8 @@
*
*
Maximum String value length: default 20_000_000 (see {@link #DEFAULT_MAX_STRING_LEN})
*
+ * Maximum Property name length: default 50_000 (see {@link #DEFAULT_MAX_NAME_LEN})
+ *
* Maximum Nesting depth: default 1000 (see {@link #DEFAULT_MAX_DEPTH})
*
*
@@ -45,6 +47,14 @@ public class StreamReadConstraints
*/
public static final int DEFAULT_MAX_STRING_LEN = 20_000_000;
+ /**
+ * Default setting for maximum name length: see {@link Builder#maxNameLength(int)}
+ * for details.
+ *
+ * @since 2.16
+ */
+ public static final int DEFAULT_MAX_NAME_LEN = 50_000;
+
/**
* Limit for the maximum magnitude of Scale of {@link java.math.BigDecimal} that can be
* converted to {@link java.math.BigInteger}.
@@ -56,9 +66,11 @@ public class StreamReadConstraints
protected final int _maxNestingDepth;
protected final int _maxNumLen;
protected final int _maxStringLen;
+ protected final int _maxNameLen;
private static StreamReadConstraints DEFAULT =
- new StreamReadConstraints(DEFAULT_MAX_DEPTH, DEFAULT_MAX_NUM_LEN, DEFAULT_MAX_STRING_LEN);
+ new StreamReadConstraints(DEFAULT_MAX_DEPTH, DEFAULT_MAX_NUM_LEN,
+ DEFAULT_MAX_STRING_LEN, DEFAULT_MAX_NAME_LEN);
/**
* Override the default StreamReadConstraints. These defaults are only used when {@link JsonFactory}
@@ -89,6 +101,7 @@ public static final class Builder {
private int maxNestingDepth;
private int maxNumLen;
private int maxStringLen;
+ private int maxNameLen;
/**
* Sets the maximum nesting depth. The depth is a count of objects and arrays that have not
@@ -149,24 +162,47 @@ public Builder maxStringLength(final int maxStringLen) {
return this;
}
+ /**
+ * Sets the maximum name length (in chars or bytes, depending on input context).
+ * The default is 50,000. This limit is not exact, the limit is applied when we increase
+ * internal buffer sizes and an exception will happen at sizes greater than this limit. Some
+ * text values that are a little bigger than the limit may be treated as valid but no text
+ * values with sizes less than or equal to this limit will be treated as invalid.
+ *
+ * @param maxNameLen the maximum string length (in chars or bytes, depending on input context)
+ *
+ * @return this builder
+ * @throws IllegalArgumentException if the maxStringLen is set to a negative value
+ * @since 2.16.0
+ */
+ public Builder maxNameLength(final int maxNameLen) {
+ if (maxNameLen < 0) {
+ throw new IllegalArgumentException("Cannot set maxNameLen to a negative value");
+ }
+ this.maxNameLen = maxNameLen;
+ return this;
+ }
+
Builder() {
- this(DEFAULT_MAX_DEPTH, DEFAULT_MAX_NUM_LEN, DEFAULT_MAX_STRING_LEN);
+ this(DEFAULT_MAX_DEPTH, DEFAULT_MAX_NUM_LEN, DEFAULT_MAX_STRING_LEN, DEFAULT_MAX_NAME_LEN);
}
- Builder(final int maxNestingDepth, final int maxNumLen, final int maxStringLen) {
+ Builder(final int maxNestingDepth, final int maxNumLen, final int maxStringLen, final int maxNameLen) {
this.maxNestingDepth = maxNestingDepth;
this.maxNumLen = maxNumLen;
this.maxStringLen = maxStringLen;
+ this.maxNameLen = maxNameLen;
}
Builder(StreamReadConstraints src) {
maxNestingDepth = src._maxNestingDepth;
maxNumLen = src._maxNumLen;
maxStringLen = src._maxStringLen;
+ maxNameLen = src._maxNameLen;
}
public StreamReadConstraints build() {
- return new StreamReadConstraints(maxNestingDepth, maxNumLen, maxStringLen);
+ return new StreamReadConstraints(maxNestingDepth, maxNumLen, maxStringLen, maxNameLen);
}
}
@@ -176,10 +212,17 @@ public StreamReadConstraints build() {
/**********************************************************************
*/
+ @Deprecated // since 2.16
protected StreamReadConstraints(final int maxNestingDepth, final int maxNumLen, final int maxStringLen) {
+ this(maxNestingDepth, maxNumLen, maxStringLen, DEFAULT_MAX_NAME_LEN);
+ }
+
+ protected StreamReadConstraints(final int maxNestingDepth, final int maxNumLen,
+ final int maxStringLen, final int maxNameLen) {
_maxNestingDepth = maxNestingDepth;
_maxNumLen = maxNumLen;
_maxStringLen = maxStringLen;
+ _maxNameLen = maxNameLen;
}
public static Builder builder() {
@@ -238,6 +281,16 @@ public int getMaxStringLength() {
return _maxStringLen;
}
+ /**
+ * Accessor for maximum length of names to decode.
+ * see {@link Builder#maxNameLength(int)} for details.
+ *
+ * @return Maximum allowed name length
+ */
+ public int getMaxNameLength() {
+ return _maxNameLen;
+ }
+
/*
/**********************************************************************
/* Convenience methods for validation, document limits
@@ -334,6 +387,27 @@ public void validateStringLength(int length) throws StreamConstraintsException
}
}
+ /**
+ * Convenience method that can be used to verify that a name
+ * of specified length does not exceed maximum specific by this
+ * constraints object: if it does, a
+ * {@link StreamConstraintsException}
+ * is thrown.
+ *
+ * @param length Length of name in input units
+ *
+ * @throws StreamConstraintsException If length exceeds maximum
+ */
+ public void validateNameLength(int length) throws StreamConstraintsException
+ {
+ if (length > _maxNameLen) {
+ throw _constructException(
+ "Name value length (%d) exceeds the maximum allowed (%d, from %s)",
+ length, _maxNameLen,
+ _constrainRef("getMaxNameLength"));
+ }
+ }
+
/*
/**********************************************************************
/* Convenience methods for validation, other