Relax limit on max string size in CBOR, Smile, YAML (#103930)

Remove the rough limit on string length from Jackson 2.15. The limit was already relaxed for JSON in #96031, this extends that change to other XContent types.

Refs: #96031
Fixes: #104009
This commit is contained in:
Stuart Tettemer 2024-01-08 13:31:54 -06:00 committed by GitHub
parent 2279d75b9d
commit a359b1f648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 10 deletions

View File

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.xcontent.provider;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.core.TSFBuilder;
public class XContentImplUtils {
public static <F extends JsonFactory, B extends TSFBuilder<F, B>> F configure(TSFBuilder<F, B> builder) {
// jackson 2.15 introduced a max string length. We have other limits in place to constrain max doc size,
// so here we set to max value (2GiB) so as not to constrain further than those existing limits.
return builder.streamReadConstraints(StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build()).build();
}
}

View File

@ -21,6 +21,7 @@ import org.elasticsearch.xcontent.XContentParseException;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentParserConfiguration;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.provider.XContentImplUtils;
import java.io.IOException;
import java.io.InputStream;
@ -45,7 +46,7 @@ public final class CborXContentImpl implements XContent {
}
static {
cborFactory = new CBORFactory();
cborFactory = XContentImplUtils.configure(CBORFactory.builder());
cborFactory.configure(CBORFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW, false); // this trips on many mappings now...
// Do not automatically close unclosed objects/arrays in com.fasterxml.jackson.dataformat.cbor.CBORGenerator#close() method
cborFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT, false);

View File

@ -13,7 +13,6 @@ import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonFactoryBuilder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.StreamReadConstraints;
import org.elasticsearch.xcontent.XContent;
import org.elasticsearch.xcontent.XContentBuilder;
@ -21,6 +20,7 @@ import org.elasticsearch.xcontent.XContentGenerator;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentParserConfiguration;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.provider.XContentImplUtils;
import java.io.IOException;
import java.io.InputStream;
@ -46,12 +46,7 @@ public class JsonXContentImpl implements XContent {
}
static {
var builder = new JsonFactoryBuilder();
// jackson 2.15 introduced a max string length. We have other limits in place to constrain max doc size,
// so here we set to max value (2GiB) so as not to constrain further than those existing limits.
builder.streamReadConstraints(StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build());
jsonFactory = builder.build();
jsonFactory = XContentImplUtils.configure(new JsonFactoryBuilder());
jsonFactory.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true);
jsonFactory.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
jsonFactory.configure(JsonFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW, false); // this trips on many mappings now...

View File

@ -21,6 +21,7 @@ import org.elasticsearch.xcontent.XContentGenerator;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentParserConfiguration;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.provider.XContentImplUtils;
import java.io.IOException;
import java.io.InputStream;
@ -45,7 +46,7 @@ public final class SmileXContentImpl implements XContent {
}
static {
smileFactory = new SmileFactory();
smileFactory = XContentImplUtils.configure(SmileFactory.builder());
// for now, this is an overhead, might make sense for web sockets
smileFactory.configure(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT, false);
smileFactory.configure(SmileFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW, false); // this trips on many mappings now...

View File

@ -11,6 +11,7 @@ package org.elasticsearch.xcontent.provider.yaml;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import org.elasticsearch.xcontent.XContent;
import org.elasticsearch.xcontent.XContentBuilder;
@ -18,6 +19,7 @@ import org.elasticsearch.xcontent.XContentGenerator;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentParserConfiguration;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.provider.XContentImplUtils;
import java.io.IOException;
import java.io.InputStream;
@ -42,7 +44,10 @@ public final class YamlXContentImpl implements XContent {
}
static {
yamlFactory = new YAMLFactory();
yamlFactory = XContentImplUtils.configure(YAMLFactory.builder());
// YAMLFactory.builder() differs from new YAMLFactory() in that builder() does not set the default yaml parser feature flags.
// So set the only default feature flag, EMPTY_STRING_AS_NULL, here.
yamlFactory.configure(YAMLParser.Feature.EMPTY_STRING_AS_NULL, true);
yamlFactory.configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true);
yamlFactory.configure(JsonParser.Feature.USE_FAST_DOUBLE_PARSER, true);
yamlXContent = new YamlXContentImpl();