VYPR
High severityNVD Advisory· Published Aug 8, 2023· Updated Sep 27, 2024

DOS in jackson-dataformats-text

CVE-2023-3894

Description

Jackson-dataformats-text TOML parser is vulnerable to denial of service via stack overflow due to uncontrolled recursion in deeply nested tables.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Jackson-dataformats-text TOML parser is vulnerable to denial of service via stack overflow due to uncontrolled recursion in deeply nested tables.

Vulnerability

CVE-2023-3894 describes a denial-of-service (DoS) vulnerability in the TOML parser of jackson-dataformats-text. The root cause is the absence of nesting depth validation, allowing deeply nested tables or arrays to cause a stack overflow and crash the JVM [1]. The issue was introduced in versions prior to the fix.

Exploitation

An attacker can exploit this by supplying a specially crafted TOML document with extremely deep nesting of tables (e.g., multiple [a.b.c...] or [[array]] structures) to any application that parses untrusted TOML input using the vulnerable parser. No authentication or special privileges are required beyond network access to the parser [1].

Impact

Successful exploitation leads to a denial-of-service condition: the parser crashes with a stack overflow, disrupting service availability [1].

Mitigation

The vulnerability is fixed in jackson-dataformats-text versions 2.16.0 and later. The fix adds nesting depth tracking via StreamReadConstraints.validateNestingDepth(), which limits recursion depth [2]. Users should upgrade to a patched version or apply input validation to limit nesting depth [4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
com.fasterxml.jackson.dataformat:jackson-dataformat-tomlMaven
< 2.15.02.15.0

Affected products

2

Patches

1
5dd5f740aedc

TOML: check nesting depth (#398)

16 files changed · +148 69
  • properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsFactory.java+3 1 modified
    @@ -28,7 +28,9 @@ public class JavaPropsFactory extends JsonFactory
         /**********************************************************
          */
         
    -    public JavaPropsFactory() { }
    +    public JavaPropsFactory() {
    +        super();
    +    }
     
         public JavaPropsFactory(ObjectCodec codec) {
             super(codec);
    
  • toml/src/main/java/com/fasterxml/jackson/dataformat/toml/Parser.java+11 3 modified
    @@ -56,7 +56,9 @@ public static ObjectNode parse(
             Parser parser = new Parser(new TomlFactory(), ioContext,
                     new TomlStreamReadException.ErrorContext(ioContext.contentReference(), null), options, reader);
             try {
    -            return parser.parse();
    +            final ObjectNode node = parser.parse();
    +            assert parser.getNestingDepth() == 0;
    +            return node;
             } finally {
                 parser.lexer.releaseBuffers();
             }
    @@ -80,12 +82,18 @@ public static ObjectNode parse(
                     new TomlStreamReadException.ErrorContext(ioContext.contentReference(), null),
                     factory.getFormatParserFeatures(), reader);
             try {
    -            return parser.parse();
    +            final ObjectNode node = parser.parse();
    +            assert parser.getNestingDepth() == 0;
    +            return node;
             } finally {
                 parser.lexer.releaseBuffers();
             }
         }
     
    +    int getNestingDepth() {
    +        return lexer.getNestingDepth();
    +    }
    +
         private TomlToken peek() throws TomlStreamReadException {
             TomlToken here = this.next;
             if (here == null) throw errorContext.atPosition(lexer).generic("Premature end of file");
    @@ -376,7 +384,7 @@ private ValueNode parseIntFromBuffer(char[] buffer, int start, int length) throw
         }
     
         private JsonNode parseFloat(int nextState) throws IOException {
    -        String text = lexer.yytext().replace("_", "");
    +        final String text = lexer.yytext().replace("_", "");
             pollExpected(TomlToken.FLOAT, nextState);
             if (text.endsWith("nan")) {
                 return factory.numberNode(Double.NaN);
    
  • toml/src/main/java/com/fasterxml/jackson/dataformat/toml/TomlFactory.java+1 0 modified
    @@ -56,6 +56,7 @@ public final class TomlFactory extends JsonFactory
          */
     
         public TomlFactory() {
    +        super();
             _tomlParserFeatures = DEFAULT_TOML_PARSER_FEATURE_FLAGS;
             _tomlGeneratorFeatures = DEFAULT_TOML_GENERATOR_FEATURE_FLAGS;
         }
    
  • toml/src/main/jflex/com/fasterxml/jackson/dataformat/toml/toml.jflex+47 10 modified
    @@ -15,6 +15,7 @@ package com.fasterxml.jackson.dataformat.toml;
     
     %init{
     this.ioContext = ioContext;
    +this.streamReadConstraints = ioContext.streamReadConstraints();
     this.errorContext = errorContext;
     yybegin(EXPECT_EXPRESSION);
     this.zzBuffer = ioContext.allocTokenBuffer();
    @@ -30,6 +31,8 @@ this.textBuffer = ioContext.constructReadConstrainedTextBuffer();
     
       private boolean trimmedNewline;
       final com.fasterxml.jackson.core.util.TextBuffer textBuffer;
    +  private final com.fasterxml.jackson.core.StreamReadConstraints streamReadConstraints;
    +  private int nestingDepth;
     
       private void requestLargerBuffer() throws TomlStreamReadException {
           if (prohibitInternalBufferAllocate) {
    @@ -54,6 +57,10 @@ this.textBuffer = ioContext.constructReadConstrainedTextBuffer();
           textBuffer.releaseBuffers();
       }
     
    +  public int getNestingDepth() {
    +      return nestingDepth;
    +  }
    +
       private void startString() {
           // resetWithEmpty does not set _currentSegment, so we need this variant to be able to append further data
           textBuffer.emptyAndGetCurrentSegment();
    @@ -257,8 +264,14 @@ HexDig = [0-9A-Fa-f]
               yybegin(LITERAL_STRING);
               startString();
           }
    -    {StdTableOpen} {return TomlToken.STD_TABLE_OPEN;}
    -    {ArrayTableOpen} {return TomlToken.ARRAY_TABLE_OPEN;}
    +    {StdTableOpen} {
    +          streamReadConstraints.validateNestingDepth(++nestingDepth);
    +          return TomlToken.STD_TABLE_OPEN;
    +      }
    +    {ArrayTableOpen} {
    +          streamReadConstraints.validateNestingDepth(++nestingDepth);
    +          return TomlToken.ARRAY_TABLE_OPEN;
    +      }
         {KeyValSep} {return TomlToken.KEY_VAL_SEP;}
         {NewLine} {}
         {Comment} {}
    @@ -284,9 +297,18 @@ HexDig = [0-9A-Fa-f]
               startString();
           }
         {KeyValSep} {return TomlToken.KEY_VAL_SEP;}
    -    {InlineTableClose} {return TomlToken.INLINE_TABLE_CLOSE;}
    -    {StdTableClose} {return TomlToken.STD_TABLE_CLOSE;}
    -    {ArrayTableClose} {return TomlToken.ARRAY_TABLE_CLOSE;}
    +    {InlineTableClose} {
    +          nestingDepth--;
    +          return TomlToken.INLINE_TABLE_CLOSE;
    +      }
    +    {StdTableClose} {
    +          nestingDepth--;
    +          return TomlToken.STD_TABLE_CLOSE;
    +      }
    +    {ArrayTableClose} {
    +          nestingDepth--;
    +          return TomlToken.ARRAY_TABLE_CLOSE;
    +      }
     }
     
     <EXPECT_EOL> {
    @@ -340,18 +362,30 @@ HexDig = [0-9A-Fa-f]
           }
     
         // inline array / table
    -    {ArrayOpen} {WsCommentNewlineNonEmpty}* {return TomlToken.ARRAY_OPEN;}
    -    {InlineTableOpen} {return TomlToken.INLINE_TABLE_OPEN;}
    +    {ArrayOpen} {WsCommentNewlineNonEmpty}* {
    +          streamReadConstraints.validateNestingDepth(++nestingDepth);
    +          return TomlToken.ARRAY_OPEN;
    +      }
    +    {InlineTableOpen} {
    +          streamReadConstraints.validateNestingDepth(++nestingDepth);
    +          return TomlToken.INLINE_TABLE_OPEN;
    +      }
     
         // array end just after comma
    -    {WsCommentNewlineNonEmpty}* {ArrayClose} {return TomlToken.ARRAY_CLOSE;}
    +    {WsCommentNewlineNonEmpty}* {ArrayClose} {
    +          nestingDepth--;
    +          return TomlToken.ARRAY_CLOSE;
    +      }
     }
     
     <EXPECT_ARRAY_SEP> {
         // array-values =  ws-comment-newline val ws-comment-newline array-sep array-values
         // array-values =/ ws-comment-newline val ws-comment-newline [ array-sep ]
         {Comma} {WsCommentNewlineNonEmpty}* {return TomlToken.COMMA;}
    -    {ArrayClose} {return TomlToken.ARRAY_CLOSE;}
    +    {ArrayClose} {
    +          nestingDepth--;
    +          return TomlToken.ARRAY_CLOSE;
    +      }
         {WsCommentNewlineNonEmpty} {} // always allowed here
     }
     
    @@ -360,7 +394,10 @@ HexDig = [0-9A-Fa-f]
         // inline-table-keyvals = keyval [ inline-table-sep inline-table-keyvals ]
     
         {Ws} {Comma} {Ws} {return TomlToken.COMMA;}
    -    {InlineTableClose} {return TomlToken.INLINE_TABLE_CLOSE;}
    +    {InlineTableClose} {
    +          nestingDepth--;
    +          return TomlToken.INLINE_TABLE_CLOSE;
    +      }
     }
     
     <BASIC_STRING> {
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/BigStringsTest.java+2 2 modified
    @@ -9,7 +9,7 @@
     import static org.junit.Assert.assertTrue;
     import static org.junit.Assert.fail;
     
    -public class BigStringsTest
    +public class BigStringsTest extends TomlMapperTestBase
     {
     
         final static class StringWrapper
    @@ -25,7 +25,7 @@ void setString(String string) {
             }
         }
     
    -    private final TomlMapper MAPPER = new TomlMapper();
    +    private final TomlMapper MAPPER = newTomlMapper();
     
         private TomlMapper newMapperWithUnlimitedStringSizeSupport() {
             TomlFactory tomlFactory = TomlFactory.builder()
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/ComplexPojoReadWriteTest.java+2 2 modified
    @@ -11,7 +11,7 @@
     import com.fasterxml.jackson.databind.ObjectMapper;
     
     // Copied from YAML modules "DatabindAdvancedTest"
    -public class ComplexPojoReadWriteTest
    +public class ComplexPojoReadWriteTest extends TomlMapperTestBase
     {
         enum Size { SMALL, LARGE; }
     
    @@ -145,7 +145,7 @@ public Image(String uri, String title, int w, int h, Size s)
         @Test
         public void testReadWriteComplexPojo() throws Exception
         {
    -        ObjectMapper mapper = new TomlMapper();
    +        ObjectMapper mapper = newTomlMapper();
     
             MediaItem input = new MediaItem();
             MediaContent content = new MediaContent();
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/ComplianceInvalidTest.java+2 2 modified
    @@ -15,7 +15,7 @@
     import java.util.stream.Collectors;
     
     @RunWith(Parameterized.class)
    -public class ComplianceInvalidTest {
    +public class ComplianceInvalidTest extends TomlMapperTestBase {
         @Parameterized.Parameters
         public static Collection<Object[]> data() throws IOException {
             Path folder = Paths.get("compliance", "invalid");
    @@ -28,7 +28,7 @@ public static Collection<Object[]> data() throws IOException {
                     .collect(Collectors.toList());
         }
     
    -    private final ObjectMapper MAPPER = new TomlMapper();
    +    private final ObjectMapper MAPPER = newTomlMapper();
     
         private final Path path;
     
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/ComplianceValidTest.java+1 1 modified
    @@ -27,7 +27,7 @@
     import java.util.stream.Collectors;
     
     @RunWith(Parameterized.class)
    -public class ComplianceValidTest {
    +public class ComplianceValidTest extends TomlMapperTestBase {
         @Parameterized.Parameters
         public static Collection<Object[]> data() throws IOException {
             Path folder = Paths.get("compliance", "valid");
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/FuzzTomlReadTest.java+18 2 modified
    @@ -3,6 +3,7 @@
     import java.io.IOException;
     import java.util.Arrays;
     
    +import com.fasterxml.jackson.core.exc.StreamConstraintsException;
     import org.junit.Assert;
     import org.junit.Test;
     
    @@ -13,9 +14,9 @@
     /**
      * Collection of OSS-Fuzz found issues for TOML format module.
      */
    -public class FuzzTomlReadTest
    +public class FuzzTomlReadTest extends TomlMapperTestBase
     {
    -    private final ObjectMapper TOML_MAPPER = new TomlMapper();
    +    private final ObjectMapper TOML_MAPPER = newTomlMapper();
     
         // https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50036
         @Test
    @@ -76,6 +77,21 @@ public void testNumberParsingFail50395() throws Exception
                 verifyException(e, "Premature end of file");
             }
         }
    +
    +    @Test
    +    public void testStackOverflow50083() throws Exception
    +    {
    +        StringBuilder input = new StringBuilder();
    +        for (int i = 0; i < 9999; i++) {
    +            input.append("a={");
    +        }
    +        try {
    +            TOML_MAPPER.readTree(input.toString());
    +            Assert.fail("Should not pass");
    +        } catch (StreamConstraintsException e) {
    +            verifyException(e, "Depth (1001) exceeds the maximum allowed nesting depth (1000)");
    +        }
    +    }
             
         protected void verifyException(Throwable e, String... matches)
         {
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/LongTokenTest.java+3 4 modified
    @@ -1,7 +1,6 @@
     package com.fasterxml.jackson.dataformat.toml;
     
     import com.fasterxml.jackson.core.StreamReadConstraints;
    -import com.fasterxml.jackson.core.exc.StreamConstraintsException;
     import com.fasterxml.jackson.core.io.ContentReference;
     import com.fasterxml.jackson.core.io.IOContext;
     import com.fasterxml.jackson.core.util.BufferRecyclers;
    @@ -15,14 +14,14 @@
     import java.math.BigDecimal;
     import java.math.BigInteger;
     
    -public class LongTokenTest {
    +public class LongTokenTest extends TomlMapperTestBase {
         private static final int SCALE = 10000; // must be bigger than the default buffer size
     
         // Need to ensure max-number-limit not hit
         private final TomlFactory FACTORY = TomlFactory.builder()
                 .streamReadConstraints(StreamReadConstraints.builder().maxNumberLength(Integer.MAX_VALUE).build())
                 .build();
    -    private final ObjectMapper NO_LIMITS_MAPPER = new TomlMapper(FACTORY);
    +    private final ObjectMapper NO_LIMITS_MAPPER = newTomlMapper(FACTORY);
     
         @Test
         public void decimal() throws IOException {
    @@ -42,7 +41,7 @@ public void decimal() throws IOException {
         @Test
         public void decimalTooLong() throws IOException {
             // default TomlFactory has max num length of 1000
    -        final ObjectMapper mapper = new TomlMapper();
    +        final ObjectMapper mapper = newTomlMapper();
             StringBuilder toml = new StringBuilder("foo = 0.");
             for (int i = 0; i < SCALE; i++) {
                 toml.append('0');
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/ParserTest.java+10 9 modified
    @@ -27,8 +27,8 @@
     import java.util.Arrays;
     
     @SuppressWarnings("OctalInteger")
    -public class ParserTest {
    -    private static final ObjectMapper TOML_MAPPER = new TomlMapper();
    +public class ParserTest extends TomlMapperTestBase {
    +    private static final ObjectMapper TOML_MAPPER = newTomlMapper();
         private static final ObjectMapper jsonMapper = JsonMapper.builder()
                 .enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
                 .enable(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS)
    @@ -42,11 +42,11 @@ static ObjectNode toml(@Language("toml") String toml) throws IOException {
             return (ObjectNode) TOML_MAPPER.readTree(toml);
         }
     
    -    static ObjectNode toml(int opts, @Language("toml") String toml) throws IOException {
    +    static ObjectNode toml(TomlFactory factory, @Language("toml") String toml) throws IOException {
             return Parser.parse(
    +                factory,
                     new IOContext(BufferRecyclers.getBufferRecycler(),
                             ContentReference.rawReference(toml), false),
    -                opts,
                     new StringReader(toml)
             );
         }
    @@ -950,15 +950,16 @@ public void bigintBase() throws IOException {
         @Test
         public void javaTimeDeser() throws IOException {
             // this is the same test as above, except with explicit java.time deserialization
    -        int options = TomlReadFeature.PARSE_JAVA_TIME.getMask();
    +        final TomlFactory tomlFactory = newTomlFactory();
    +        tomlFactory.enable(TomlReadFeature.PARSE_JAVA_TIME);
     
             Assert.assertEquals(
                     JsonNodeFactory.instance.objectNode()
                             .<ObjectNode>set("odt1", JsonNodeFactory.instance.pojoNode(OffsetDateTime.parse("1979-05-27T07:32:00Z")))
                             .<ObjectNode>set("odt2", JsonNodeFactory.instance.pojoNode(OffsetDateTime.parse("1979-05-27T00:32:00-07:00")))
                             .<ObjectNode>set("odt3", JsonNodeFactory.instance.pojoNode(OffsetDateTime.parse("1979-05-27T00:32:00.999999-07:00")))
                             .<ObjectNode>set("odt4", JsonNodeFactory.instance.pojoNode(OffsetDateTime.parse("1979-05-27T07:32:00Z"))),
    -                toml(options,
    +                toml(tomlFactory,
                             "odt1 = 1979-05-27T07:32:00Z\n" +
                                     "odt2 = 1979-05-27T00:32:00-07:00\n" +
                                     "odt3 = 1979-05-27T00:32:00.999999-07:00\n" +
    @@ -968,20 +969,20 @@ public void javaTimeDeser() throws IOException {
                     JsonNodeFactory.instance.objectNode()
                             .<ObjectNode>set("ldt1", JsonNodeFactory.instance.pojoNode(LocalDateTime.parse("1979-05-27T07:32:00")))
                             .<ObjectNode>set("ldt2", JsonNodeFactory.instance.pojoNode(LocalDateTime.parse("1979-05-27T00:32:00.999999"))),
    -                toml(options,
    +                toml(tomlFactory,
                             "ldt1 = 1979-05-27T07:32:00\n" +
                                     "ldt2 = 1979-05-27T00:32:00.999999")
             );
             Assert.assertEquals(
                     JsonNodeFactory.instance.objectNode()
                             .set("ld1", JsonNodeFactory.instance.pojoNode(LocalDate.parse("1979-05-27"))),
    -                toml(options, "ld1 = 1979-05-27")
    +                toml(tomlFactory, "ld1 = 1979-05-27")
             );
             Assert.assertEquals(
                     JsonNodeFactory.instance.objectNode()
                             .<ObjectNode>set("lt1", JsonNodeFactory.instance.pojoNode(LocalTime.parse("07:32:00")))
                             .<ObjectNode>set("lt2", JsonNodeFactory.instance.pojoNode(LocalTime.parse("00:32:00.999999"))),
    -                toml(options,
    +                toml(tomlFactory,
                             "lt1 = 07:32:00\n" +
                                     "lt2 = 00:32:00.999999")
             );
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/POJOReadWriteTest.java+2 2 modified
    @@ -18,7 +18,7 @@
     import com.fasterxml.jackson.databind.json.JsonMapper;
     
     // Composed of pieces from other format modules' tests
    -public class POJOReadWriteTest
    +public class POJOReadWriteTest extends TomlMapperTestBase
     {
         @JsonPropertyOrder({ "topLeft", "bottomRight" })
         protected static class Rectangle {
    @@ -150,7 +150,7 @@ public int hashCode() {
             }
         }
     
    -    private final ObjectMapper MAPPER = new TomlMapper();
    +    private final ObjectMapper MAPPER = newTomlMapper();
         private final ObjectMapper JSON_MAPPER = new JsonMapper();
     
         @Test
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/StringOutputUtilTest.java+1 1 modified
    @@ -9,7 +9,7 @@
     import java.io.IOException;
     import java.io.StringReader;
     
    -public class StringOutputUtilTest {
    +public class StringOutputUtilTest extends TomlMapperTestBase {
         @Test
         public void exhaustiveWriteReadTest() throws IOException {
             // this test attempts single-character writes for *all* code points, and sees whether they're read back
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/TomlGeneratorTest.java+21 21 modified
    @@ -11,11 +11,11 @@
     import java.io.StringWriter;
     import java.time.*;
     
    -public class TomlGeneratorTest {
    +public class TomlGeneratorTest extends TomlMapperTestBase {
         @Test
         public void number() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeNumber(123);
    @@ -27,7 +27,7 @@ public void number() throws IOException {
         @Test
         public void bool() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeBoolean(true);
    @@ -39,7 +39,7 @@ public void bool() throws IOException {
         @Test
         public void floats() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeNumber(1.23);
    @@ -51,7 +51,7 @@ public void floats() throws IOException {
         @Test
         public void stringNormal() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeString("foo");
    @@ -63,7 +63,7 @@ public void stringNormal() throws IOException {
         @Test
         public void stringApostrophe() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeString("foo'");
    @@ -75,7 +75,7 @@ public void stringApostrophe() throws IOException {
         @Test
         public void stringQuote() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeString("foo\"");
    @@ -87,7 +87,7 @@ public void stringQuote() throws IOException {
         @Test
         public void stringQuoteApostrophe() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeString("foo\"'");
    @@ -99,7 +99,7 @@ public void stringQuoteApostrophe() throws IOException {
         @Test
         public void stringControlCharUnicode() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeString("foo\u0001");
    @@ -111,7 +111,7 @@ public void stringControlCharUnicode() throws IOException {
         @Test
         public void stringControlCharSpecial() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeString("foo\b");
    @@ -123,7 +123,7 @@ public void stringControlCharSpecial() throws IOException {
         @Test
         public void binary() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeBinary(new byte[] {1,2,3});
    @@ -135,7 +135,7 @@ public void binary() throws IOException {
         @Test
         public void emptyObject() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeStartObject();
    @@ -148,7 +148,7 @@ public void emptyObject() throws IOException {
         @Test
         public void objectWithValues() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeStartObject();
    @@ -165,7 +165,7 @@ public void objectWithValues() throws IOException {
         @Test
         public void emptyArray() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeStartArray();
    @@ -178,7 +178,7 @@ public void emptyArray() throws IOException {
         @Test
         public void arrayWithScalars() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeStartArray();
    @@ -194,7 +194,7 @@ public void arrayWithScalars() throws IOException {
         @Test
         public void arrayMixed() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeStartArray();
    @@ -214,7 +214,7 @@ public void arrayMixed() throws IOException {
         @Test
         public void temporal() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("abc");
                 generator.writeStartArray();
    @@ -231,7 +231,7 @@ public void temporal() throws IOException {
         @Test
         public void complexKey() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("foo bar");
                 generator.writeNumber(123);
    @@ -243,7 +243,7 @@ public void complexKey() throws IOException {
         // [dataformats-text#258]: byte-backed output not flushing?
         @Test
         public void nestedObjectValues() throws IOException {
    -        final ObjectMapper mapper = new TomlMapper();
    +        final ObjectMapper mapper = newTomlMapper();
             final String EXP_TOML = "point.x = 19\n"
                     +"point.y = 72\n";
     
    @@ -277,7 +277,7 @@ private void _writeNested(JsonGenerator g) throws IOException {
         @Test
         public void nullEnabledDefault() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("foo");
                 generator.writeNull();
    @@ -289,7 +289,7 @@ public void nullEnabledDefault() throws IOException {
         @Test(expected = TomlStreamWriteException.class)
         public void nullDisable() throws IOException {
             StringWriter w = new StringWriter();
    -        try (JsonGenerator generator = new TomlMapper().enable(TomlWriteFeature.FAIL_ON_NULL_WRITE).createGenerator(w)) {
    +        try (JsonGenerator generator = newTomlMapper().enable(TomlWriteFeature.FAIL_ON_NULL_WRITE).createGenerator(w)) {
                 generator.writeStartObject();
                 generator.writeFieldName("foo");
                 generator.writeNull();
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/TomlMapperTestBase.java+15 0 added
    @@ -0,0 +1,15 @@
    +package com.fasterxml.jackson.dataformat.toml;
    +
    +abstract class TomlMapperTestBase {
    +    protected static TomlFactory newTomlFactory() {
    +        return TomlFactory.builder().build();
    +    }
    +    
    +    protected static TomlMapper newTomlMapper() {
    +        return new TomlMapper(newTomlFactory());
    +    }
    +
    +    protected static TomlMapper newTomlMapper(TomlFactory tomlFactory) {
    +        return new TomlMapper(tomlFactory);
    +    }
    +}
    
  • toml/src/test/java/com/fasterxml/jackson/dataformat/toml/TomlMapperTest.java+9 9 modified
    @@ -19,7 +19,7 @@
     import org.junit.Test;
     import org.junit.rules.ExpectedException;
     
    -public class TomlMapperTest {
    +public class TomlMapperTest extends TomlMapperTestBase {
         @SuppressWarnings("deprecation")
         @Rule
         public final ExpectedException expectedException = ExpectedException.none();
    @@ -37,22 +37,22 @@ public class TomlMapperTest {
     
         @Test
         public void string() throws JsonProcessingException {
    -        Assert.assertEquals(TEST_OBJECT, new TomlMapper().readValue(TEST_STRING, TestClass.class));
    +        Assert.assertEquals(TEST_OBJECT, newTomlMapper().readValue(TEST_STRING, TestClass.class));
         }
     
         @Test
         public void bytes() throws IOException {
    -        Assert.assertEquals(TEST_OBJECT, new TomlMapper().readValue(TEST_STRING.getBytes(StandardCharsets.UTF_8), TestClass.class));
    +        Assert.assertEquals(TEST_OBJECT, newTomlMapper().readValue(TEST_STRING.getBytes(StandardCharsets.UTF_8), TestClass.class));
         }
     
         @Test
         public void stream() throws IOException {
    -        Assert.assertEquals(TEST_OBJECT, new TomlMapper().readValue(new ByteArrayInputStream(TEST_STRING.getBytes(StandardCharsets.UTF_8)), TestClass.class));
    +        Assert.assertEquals(TEST_OBJECT, newTomlMapper().readValue(new ByteArrayInputStream(TEST_STRING.getBytes(StandardCharsets.UTF_8)), TestClass.class));
         }
     
         @Test
         public void reader() throws IOException {
    -        Assert.assertEquals(TEST_OBJECT, new TomlMapper().readValue(new StringReader(TEST_STRING), TestClass.class));
    +        Assert.assertEquals(TEST_OBJECT, newTomlMapper().readValue(new StringReader(TEST_STRING), TestClass.class));
         }
     
         public static class TestClass {
    @@ -108,7 +108,7 @@ public void bigDecimal() throws JsonProcessingException {
             Assert.assertEquals(
                     JsonNodeFactory.instance.objectNode()
                             .put("abc", testValue),
    -                new TomlMapper().readTree("abc = " + testValue.toString())
    +                newTomlMapper().readTree("abc = " + testValue.toString())
             );
         }
     
    @@ -121,7 +121,7 @@ public void veryBigDecimal() throws JsonProcessingException {
             }
             final String value = sb.toString();
             try {
    -            new TomlMapper().readTree("abc = " + value);
    +            newTomlMapper().readTree("abc = " + value);
                 Assert.fail("expected TomlStreamReadException");
             } catch (TomlStreamReadException e) {
                 Assert.assertTrue("unexpected message: " + e.getMessage(),
    @@ -141,7 +141,7 @@ public void veryBigDecimalWithNumLenUnlimited() throws JsonProcessingException {
             TomlFactory factory = TomlFactory.builder()
                     .streamReadConstraints(StreamReadConstraints.builder().maxNumberLength(Integer.MAX_VALUE).build())
                     .build();
    -        TomlMapper mapper = new TomlMapper(factory);
    +        TomlMapper mapper = newTomlMapper(factory);
             Assert.assertEquals(
                     testValue,
                     mapper.readTree("abc = " + value).get("abc").decimalValue()
    @@ -159,7 +159,7 @@ public void temporalFieldFlag() throws JsonProcessingException {
             );
             Assert.assertEquals(
                     "2021-03-26",
    -                new TomlMapper().readValue("foo = 2021-03-26", ObjectField.class).foo
    +                newTomlMapper().readValue("foo = 2021-03-26", ObjectField.class).foo
             );
         }
     
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.