Skip to content

Commit c56c82c

Browse files
committed
Prevent modifications of JsonUtil's JSON_FACTORY
`JsonFactory` is mutable.
1 parent 9abdb19 commit c56c82c

File tree

5 files changed

+40
-7
lines changed

5 files changed

+40
-7
lines changed

core/trino-main/src/main/java/io/trino/operator/scalar/JsonToArrayCast.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
*/
1414
package io.trino.operator.scalar;
1515

16+
import com.fasterxml.jackson.core.JsonFactory;
1617
import com.fasterxml.jackson.core.JsonParser;
1718
import com.fasterxml.jackson.core.JsonToken;
19+
import com.fasterxml.jackson.databind.ObjectMapper;
1820
import com.google.common.collect.ImmutableList;
1921
import io.airlift.slice.Slice;
2022
import io.trino.annotation.UsedByGeneratedCode;
@@ -41,8 +43,8 @@
4143
import static io.trino.spi.type.TypeSignature.arrayType;
4244
import static io.trino.type.JsonType.JSON;
4345
import static io.trino.util.Failures.checkCondition;
44-
import static io.trino.util.JsonUtil.JSON_FACTORY;
4546
import static io.trino.util.JsonUtil.canCastFromJson;
47+
import static io.trino.util.JsonUtil.createJsonFactory;
4648
import static io.trino.util.JsonUtil.createJsonParser;
4749
import static io.trino.util.JsonUtil.truncateIfNecessaryForErrorMessage;
4850
import static io.trino.util.Reflection.methodHandle;
@@ -54,6 +56,13 @@ public class JsonToArrayCast
5456
public static final JsonToArrayCast JSON_TO_ARRAY = new JsonToArrayCast();
5557
private static final MethodHandle METHOD_HANDLE = methodHandle(JsonToArrayCast.class, "toArray", ArrayType.class, BlockBuilderAppender.class, ConnectorSession.class, Slice.class);
5658

59+
private static final JsonFactory JSON_FACTORY = createJsonFactory();
60+
61+
static {
62+
// Changes factory. Necessary for JsonParser.readValueAsTree to work.
63+
new ObjectMapper(JSON_FACTORY);
64+
}
65+
5766
private JsonToArrayCast()
5867
{
5968
super(FunctionMetadata.scalarBuilder()

core/trino-main/src/main/java/io/trino/operator/scalar/JsonToMapCast.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
*/
1414
package io.trino.operator.scalar;
1515

16+
import com.fasterxml.jackson.core.JsonFactory;
1617
import com.fasterxml.jackson.core.JsonParser;
1718
import com.fasterxml.jackson.core.JsonToken;
19+
import com.fasterxml.jackson.databind.ObjectMapper;
1820
import com.google.common.collect.ImmutableList;
1921
import io.airlift.slice.Slice;
2022
import io.trino.annotation.UsedByGeneratedCode;
@@ -43,8 +45,8 @@
4345
import static io.trino.type.JsonType.JSON;
4446
import static io.trino.util.Failures.checkCondition;
4547
import static io.trino.util.JsonUtil.BlockBuilderAppender.createBlockBuilderAppender;
46-
import static io.trino.util.JsonUtil.JSON_FACTORY;
4748
import static io.trino.util.JsonUtil.canCastFromJson;
49+
import static io.trino.util.JsonUtil.createJsonFactory;
4850
import static io.trino.util.JsonUtil.createJsonParser;
4951
import static io.trino.util.JsonUtil.truncateIfNecessaryForErrorMessage;
5052
import static io.trino.util.Reflection.methodHandle;
@@ -56,6 +58,13 @@ public class JsonToMapCast
5658
public static final JsonToMapCast JSON_TO_MAP = new JsonToMapCast();
5759
private static final MethodHandle METHOD_HANDLE = methodHandle(JsonToMapCast.class, "toMap", MapType.class, BlockBuilderAppender.class, ConnectorSession.class, Slice.class);
5860

61+
private static final JsonFactory JSON_FACTORY = createJsonFactory();
62+
63+
static {
64+
// Changes factory. Necessary for JsonParser.readValueAsTree to work.
65+
new ObjectMapper(JSON_FACTORY);
66+
}
67+
5968
private JsonToMapCast()
6069
{
6170
super(FunctionMetadata.scalarBuilder()

core/trino-main/src/main/java/io/trino/operator/scalar/JsonToRowCast.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
*/
1414
package io.trino.operator.scalar;
1515

16+
import com.fasterxml.jackson.core.JsonFactory;
1617
import com.fasterxml.jackson.core.JsonParser;
1718
import com.fasterxml.jackson.core.JsonToken;
19+
import com.fasterxml.jackson.databind.ObjectMapper;
1820
import com.google.common.collect.ImmutableList;
1921
import io.airlift.slice.Slice;
2022
import io.trino.annotation.UsedByGeneratedCode;
@@ -41,8 +43,8 @@
4143
import static io.trino.type.JsonType.JSON;
4244
import static io.trino.util.Failures.checkCondition;
4345
import static io.trino.util.JsonUtil.BlockBuilderAppender.createBlockBuilderAppender;
44-
import static io.trino.util.JsonUtil.JSON_FACTORY;
4546
import static io.trino.util.JsonUtil.canCastFromJson;
47+
import static io.trino.util.JsonUtil.createJsonFactory;
4648
import static io.trino.util.JsonUtil.createJsonParser;
4749
import static io.trino.util.JsonUtil.truncateIfNecessaryForErrorMessage;
4850
import static io.trino.util.Reflection.methodHandle;
@@ -54,6 +56,13 @@ public class JsonToRowCast
5456
public static final JsonToRowCast JSON_TO_ROW = new JsonToRowCast();
5557
private static final MethodHandle METHOD_HANDLE = methodHandle(JsonToRowCast.class, "toRow", RowType.class, BlockBuilderAppender.class, ConnectorSession.class, Slice.class);
5658

59+
private static final JsonFactory JSON_FACTORY = createJsonFactory();
60+
61+
static {
62+
// Changes factory. Necessary for JsonParser.readValueAsTree to work.
63+
new ObjectMapper(JSON_FACTORY);
64+
}
65+
5766
private JsonToRowCast()
5867
{
5968
super(FunctionMetadata.scalarBuilder()

core/trino-main/src/main/java/io/trino/operator/scalar/timestamp/TimestampToJsonCast.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414
package io.trino.operator.scalar.timestamp;
1515

16+
import com.fasterxml.jackson.core.JsonFactory;
1617
import com.fasterxml.jackson.core.JsonGenerator;
1718
import io.airlift.slice.DynamicSliceOutput;
1819
import io.airlift.slice.Slice;
@@ -32,7 +33,7 @@
3233
import static io.trino.spi.function.OperatorType.CAST;
3334
import static io.trino.spi.type.StandardTypes.JSON;
3435
import static io.trino.type.DateTimes.formatTimestamp;
35-
import static io.trino.util.JsonUtil.JSON_FACTORY;
36+
import static io.trino.util.JsonUtil.createJsonFactory;
3637
import static io.trino.util.JsonUtil.createJsonGenerator;
3738
import static java.lang.String.format;
3839
import static java.time.ZoneOffset.UTC;
@@ -41,6 +42,7 @@
4142
public final class TimestampToJsonCast
4243
{
4344
private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
45+
private static final JsonFactory JSON_FACTORY = createJsonFactory();
4446

4547
private TimestampToJsonCast() {}
4648

core/trino-main/src/main/java/io/trino/util/JsonUtil.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,19 @@ public final class JsonUtil
104104
{
105105
private JsonUtil() {}
106106

107-
public static final JsonFactory JSON_FACTORY = new JsonFactoryBuilder().disable(CANONICALIZE_FIELD_NAMES).build();
108-
109107
// This object mapper is constructed without .configure(ORDER_MAP_ENTRIES_BY_KEYS, true) because
110108
// `OBJECT_MAPPER.writeValueAsString(parser.readValueAsTree());` preserves input order.
111109
// Be aware. Using it arbitrarily can produce invalid json (ordered by key is required in Trino).
112-
private static final ObjectMapper OBJECT_MAPPED_UNORDERED = new ObjectMapper(JSON_FACTORY);
110+
private static final ObjectMapper OBJECT_MAPPED_UNORDERED = new ObjectMapper(createJsonFactory());
113111

114112
private static final int MAX_JSON_LENGTH_IN_ERROR_MESSAGE = 10_000;
115113

114+
// Note: JsonFactory is mutable, instances cannot be shared openly.
115+
public static JsonFactory createJsonFactory()
116+
{
117+
return new JsonFactoryBuilder().disable(CANONICALIZE_FIELD_NAMES).build();
118+
}
119+
116120
public static JsonParser createJsonParser(JsonFactory factory, Slice json)
117121
throws IOException
118122
{

0 commit comments

Comments
 (0)