Skip to content

Commit

Permalink
json: enabled lenient UTF encoding (#1735)
Browse files Browse the repository at this point in the history
When using smile enable lenient UTF encoding. In some cases
log strings can have invalid UTF characters that work for
encoding as JSON, but fail surrogate checks with smile. The
lenient encoding allows these to go through, but replaces
the invalid characters with `\uFFFD`.
  • Loading branch information
brharrington authored Dec 9, 2024
1 parent 3d371fb commit 7bfee25
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
2 changes: 2 additions & 0 deletions atlas-json/src/main/scala/com/netflix/atlas/json/Json.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.fasterxml.jackson.core.json.JsonWriteFeature
import com.fasterxml.jackson.databind.*
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.dataformat.smile.SmileFactory
import com.fasterxml.jackson.dataformat.smile.SmileGenerator
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.scala.DefaultScalaModule
Expand Down Expand Up @@ -75,6 +76,7 @@ object Json {
.builder()
.enable(StreamReadFeature.AUTO_CLOSE_SOURCE)
.enable(StreamWriteFeature.AUTO_CLOSE_TARGET)
.enable(SmileGenerator.Feature.LENIENT_UTF_ENCODING)
.build()

private val jsonMapper = newMapper(jsonFactory)
Expand Down
10 changes: 10 additions & 0 deletions atlas-json/src/test/scala/com/netflix/atlas/json/JsonSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.fasterxml.jackson.core.JsonParseException
import com.fasterxml.jackson.core.JsonToken
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.node.ObjectNode
import munit.FunSuite

import java.time.Instant
Expand Down Expand Up @@ -448,6 +449,15 @@ class JsonSuite extends FunSuite {
assertEquals(json, """{"name":"name","values":[]}""")
}

test("unmatched surrogate pairs") {
val json = "{\"test\": 1, \"test\uD83D\": 2}"
val jsonNode = Json.decode[ObjectNode](json)
val smile = Json.smileEncode(jsonNode)
val smileNode = Json.smileDecode[ObjectNode](smile)
val expected = Json.decode[ObjectNode](json.replace('\uD83D', '\uFFFD'))
assertEquals(smileNode, expected)
}

test("decode from JsonData") {
def parse(json: String): List[JsonSuiteSimple] = {
val node = Json.decode[JsonNode](json)
Expand Down

0 comments on commit 7bfee25

Please sign in to comment.