From caccce406ca94119fab60539ac3fec34151ba724 Mon Sep 17 00:00:00 2001 From: Marco Catania Date: Fri, 7 Apr 2017 15:24:34 +0100 Subject: [PATCH 1/5] escape jSONP breaking chars in JSONPObject serialize methods --- .../java/com/fasterxml/jackson/databind/util/JSONPObject.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java b/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java index 3379d401b9..4ea82fe46f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java @@ -66,6 +66,8 @@ public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, T public void serialize(JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + // Escape line-separator characters that break JSONP + jgen.setCharacterEscapes(JsonpCharacterEscapes.instance()); // First, wrapping: jgen.writeRaw(_function); jgen.writeRaw('('); From 5cea9f3e3d66c90d06e941f8e56d754b0a3a32a7 Mon Sep 17 00:00:00 2001 From: Marco Catania Date: Fri, 7 Apr 2017 15:25:03 +0100 Subject: [PATCH 2/5] add JSONPObject tests --- .../databind/util/JSONPObjectTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java diff --git a/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java b/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java new file mode 100644 index 0000000000..d5d1f69ad4 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java @@ -0,0 +1,33 @@ +package com.fasterxml.jackson.databind.util; + +import java.io.IOException; + +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JSONPObjectTest extends BaseMapTest { + + private final String CALLBACK = "callback"; + private final ObjectMapper MAPPER = new ObjectMapper(); + + public void testU2028Escaped() throws IOException { + String containsU2028 = String.format("This string contains %c char", '\u2028'); + JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2028); + String valueAsString = MAPPER.writeValueAsString(jsonpObject); + assertFalse(valueAsString.contains("\u2028")); + } + + public void testU2029Escaped() throws IOException { + String containsU2029 = String.format("This string contains %c char", '\u2029'); + JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2029); + String valueAsString = MAPPER.writeValueAsString(jsonpObject); + assertFalse(valueAsString.contains("\u2029")); + } + + public void testU2030NotEscaped() throws IOException { + String containsU2030 = String.format("This string contains %c char", '\u2030'); + JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2030); + String valueAsString = MAPPER.writeValueAsString(jsonpObject); + assertTrue(valueAsString.contains("\u2030")); + } +} From 80f3fc0684095493b7de3f286eae27854ac3c92a Mon Sep 17 00:00:00 2001 From: Marco Catania Date: Fri, 7 Apr 2017 15:28:13 +0100 Subject: [PATCH 3/5] add comment to tests --- .../com/fasterxml/jackson/databind/util/JSONPObjectTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java b/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java index d5d1f69ad4..032f40bc7e 100644 --- a/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/util/JSONPObjectTest.java @@ -10,6 +10,10 @@ public class JSONPObjectTest extends BaseMapTest { private final String CALLBACK = "callback"; private final ObjectMapper MAPPER = new ObjectMapper(); + /** + * Unit tests for checking that JSONP breaking characters U+2028 and U+2029 are escaped when creating a {@link JSONPObject}. + */ + public void testU2028Escaped() throws IOException { String containsU2028 = String.format("This string contains %c char", '\u2028'); JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2028); From 22bad46a36a09d0fddf84fcd2442916b636bb466 Mon Sep 17 00:00:00 2001 From: Marco Catania Date: Mon, 10 Apr 2017 13:50:04 +0100 Subject: [PATCH 4/5] apply JsonpCharacterEscapes if no custom escapes are already set. Reset escapes before method returns --- .../jackson/databind/util/JSONPObject.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java b/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java index 4ea82fe46f..c0a1aae32f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.core.io.CharacterEscapes; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; @@ -66,8 +67,15 @@ public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, T public void serialize(JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - // Escape line-separator characters that break JSONP - jgen.setCharacterEscapes(JsonpCharacterEscapes.instance()); + CharacterEscapes currentCharacterEscapes = jgen.getCharacterEscapes(); + + // NOTE: Escape line-separator characters that break JSONP only if no custom character escapes are set. + // If custom escapes are in place JSONP-breaking characters will not be escaped and it is recommended to + // add escaping for those (see JsonpCharacterEscapes class). + if (currentCharacterEscapes == null) { + jgen.setCharacterEscapes(JsonpCharacterEscapes.instance()); + } + // First, wrapping: jgen.writeRaw(_function); jgen.writeRaw('('); @@ -80,6 +88,7 @@ public void serialize(JsonGenerator jgen, SerializerProvider provider) provider.findTypedValueSerializer(cls, true, null).serialize(_value, jgen, provider); } jgen.writeRaw(')'); + jgen.setCharacterEscapes(currentCharacterEscapes); } /* From c091dc8d7cbe6873c8a5cbd83f44fa09ef09b29c Mon Sep 17 00:00:00 2001 From: Marco Catania Date: Fri, 21 Apr 2017 20:20:16 +0200 Subject: [PATCH 5/5] wrap in try and finally blocks --- .../jackson/databind/util/JSONPObject.java | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java b/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java index c0a1aae32f..b82884e88a 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java @@ -76,19 +76,22 @@ public void serialize(JsonGenerator jgen, SerializerProvider provider) jgen.setCharacterEscapes(JsonpCharacterEscapes.instance()); } - // First, wrapping: - jgen.writeRaw(_function); - jgen.writeRaw('('); - if (_value == null) { - provider.defaultSerializeNull(jgen); - } else if (_serializationType != null) { - provider.findTypedValueSerializer(_serializationType, true, null).serialize(_value, jgen, provider); - } else { - Class cls = _value.getClass(); - provider.findTypedValueSerializer(cls, true, null).serialize(_value, jgen, provider); + try { + // First, wrapping: + jgen.writeRaw(_function); + jgen.writeRaw('('); + if (_value == null) { + provider.defaultSerializeNull(jgen); + } else if (_serializationType != null) { + provider.findTypedValueSerializer(_serializationType, true, null).serialize(_value, jgen, provider); + } else { + Class cls = _value.getClass(); + provider.findTypedValueSerializer(cls, true, null).serialize(_value, jgen, provider); + } + jgen.writeRaw(')'); + } finally { + jgen.setCharacterEscapes(currentCharacterEscapes); } - jgen.writeRaw(')'); - jgen.setCharacterEscapes(currentCharacterEscapes); } /*