Disallow trailing tokens in JSON files
Motivation:
We observed an unexpected deserialization outcome with malformed JSON. Jackson does not fail on that data but silently drops part of the data.
For example, we expected Jackson to fail to parse the data.
{
"a" : {},
"b" : {},
"c" : {
},
"c1" : true
} // a malformed tailing JSON token
"d" : {},
"e": {}
}
But Jackson just drops d and e fields and parses the JSON into:
{
"a":{},
"b":{},
"c":{},
"c1":true
}
The maintainer of Jackson said it is an expected behavior but not a bug. https://github.com/FasterXML/jackson-core/issues/808#issuecomment-1211057640
But this is intended behavior, not a bug: Jackson only reads as much content as it needs for a valid JSON Value. It does not try to consume everything there might be available, given that the white-space-separated content streams are commonly used.
He suggested enabling DeserializationFeature.FAIL_ON_TRAILING_TOKENS to fail on the malformed data added after the end of the top-level JSON.
Modifications:
- Enable
DeserializationFeature.FAIL_ON_TRAILING_TOKENSto the default JacksonObjectMapperin Central Dogma
Result:
Central Dogma now correctly rejects malformed JSON when parsing JSON data.
Walkthrough
The PR enables Jackson's FAIL_ON_TRAILING_TOKENS deserialization feature on both compact and pretty mappers to enforce stricter JSON parsing. Supporting test cases verify the new behavior for invalid JSON with trailing content, and existing test JSON patches are corrected to contain valid syntax.
Changes
| Cohort / File(s) | Summary |
|---|---|
Jackson Configurationcommon/src/main/java/com/linecorp/centraldogma/internal/Jackson.java |
Adds import of DeserializationFeature and enables FAIL_ON_TRAILING_TOKENS on both compactMapper and prettyMapper to enforce stricter JSON deserialization behavior. |
Test Coverage for Invalid JSONserver/src/test/java/com/linecorp/centraldogma/server/InvalidJsonParsingTest.javaserver/src/test/resources/invalid-content-after-trailing-comma.json |
New test class verifying that invalid JSON with trailing content triggers an IOError with MismatchedInputException cause when parsed via Jackson. Test resource file contains intentionally malformed JSON to exercise the stricter parser. |
Test Correctionsserver/src/test/java/com/linecorp/centraldogma/server/metadata/MetadataApiServiceTest.java |
Fixes JSON patch bodies in test methods addUpdateAndRemoveProjectMember and addUpdateAndRemoveProjectToken by removing extra closing braces from role assignment payloads. |
Estimated code review effort
๐ฏ 2 (Simple) | โฑ๏ธ ~10 minutes
- Review Jackson feature enablement for correctness and compatibility
- Verify test assertions align with new deserialization behavior
- Confirm JSON patch corrections are syntactically valid
Possibly related PRs
- line/centraldogma#1205: Modifies RevisionJsonDeserializer to stop using readValueAsTree(), a direct follow-up to handle implications of FAIL_ON_TRAILING_TOKENS strictness.
Suggested labels
breaking change
Suggested reviewers
- trustin
- jrhee17
Poem
๐ฐ JSON tokens trailing merrily no more! With stricter rules, we guard the parser's door, Extra braces trimmed, payloads cleaned, Now Jackson speaks as loudly as it's dreamed. โจ
Pre-merge checks and finishing touches
โ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | โ ๏ธ Warning | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
โ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | โ Passed | The title accurately summarizes the main change: enabling FAIL_ON_TRAILING_TOKENS to disallow trailing tokens in JSON deserialization. |
| Description check | โ Passed | The description clearly explains the motivation (silent data loss with malformed JSON), provides concrete examples, cites the Jackson maintainer's recommendation, and outlines the modification and expected result. |
โจ Finishing touches
- [ ] ๐ Generate docstrings
๐งช Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
๐ Recent review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
๐ฅ Commits
Reviewing files that changed from the base of the PR and between 4bb95145378b729164cae2287866006ff7f09dd5 and f20aa9762fc1ee7de6255a4ce8851dc530f56808.
๐ Files selected for processing (1)
server/src/test/java/com/linecorp/centraldogma/server/metadata/MetadataApiServiceTest.java(2 hunks)
๐งฐ Additional context used
๐งฌ Code graph analysis (1)
server/src/test/java/com/linecorp/centraldogma/server/metadata/MetadataApiServiceTest.java (1)
common/src/main/java/com/linecorp/centraldogma/internal/jsonpatch/JsonPatch.java (1)
JsonPatch(125-384)
โฐ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build-ubuntu-latest-jdk-25-snapshot
- GitHub Check: build-ubuntu-latest-jdk-17-min-java-11
- GitHub Check: build-ubuntu-latest-jdk-17-coverage
- GitHub Check: build-ubuntu-latest-jdk-21
- GitHub Check: build-macos-latest-jdk-25
- GitHub Check: build-windows-latest-jdk-25
- GitHub Check: build-ubuntu-latest-jdk-11
- GitHub Check: lint
- GitHub Check: flaky-tests
- GitHub Check: docker-build
๐ Additional comments (2)
server/src/test/java/com/linecorp/centraldogma/server/metadata/MetadataApiServiceTest.java (2)
129-130: LGTM! JSON corrected to remove trailing tokens.The JSON strings are now properly formed without extra closing braces. This fix is necessary since the PR enables
FAIL_ON_TRAILING_TOKENSin Jackson, which would reject the previously malformed JSON.
165-166: LGTM! Consistent fix applied.The JSON strings are correctly formed, matching the fix applied in
addUpdateAndRemoveProjectMember. Both test methods now use valid JSON without trailing tokens.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
I found that DeserializationFeature.FAIL_ON_TRAILING_TOKENS throws an exception on valid JSON if @JsonDeserialize is applied to an element of a list.
https://github.com/line/centraldogma/blob/3f7cac9e4543fd504b91da2d1734d3e4a49c98e3/server/src/main/java/com/linecorp/centraldogma/server/CentralDogmaConfig.java#L278-L280
Trailing token (of type END_ARRAY) found after value (bound as `com.fasterxml.jackson.databind.JsonNode`): not allowed as per `DeserializationFeature.FAIL_ON_TRAILING_TOKENS`
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 15, column: 3] (through reference chain: com.linecorp.centraldogma.server.CentralDogmaConfig["ports"]->java.util.ArrayList[0])
com.fasterxml.jackson.databind.exc.MismatchedInputException: Trailing token (of type END_ARRAY) found after value (bound as `com.fasterxml.jackson.databind.JsonNode`): not allowed as per `DeserializationFeature.FAIL_ON_TRAILING_TOKENS`
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 15, column: 3] (through reference chain: com.linecorp.centraldogma.server.CentralDogmaConfig["ports"]->java.util.ArrayList[0])
Although it could be worked around for that case, I wasn't sure if enabling DeserializationFeature.FAIL_ON_TRAILING_TOKENS was a good idea given its false-positive behavior.
If there is consensus that applying a workaround and changing the internal deserializers is preferable, I'm happy to follow the direction. Otherwise, I will close this PR.