Skip to content

Commit

Permalink
Backport #1597 in 2.8 branch too
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 22, 2017
1 parent b55b04f commit 513ab6e
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 16 deletions.
6 changes: 5 additions & 1 deletion release-notes/CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,11 @@ Joshua Jones
Ivo Studens ([email protected])
* Contributed #1585: Invoke ServiceLoader.load() inside of a privileged block
when loading modules using `ObjectMapper.findModules()`
(2.8.9)
(2.8.9)

Marco Catania ([email protected])
* Contributed #1597: Escape JSONP breaking characters
(2.8.9)

Connor Kuhn (ckuhn@github)
* Contributed #1341: FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY
Expand Down
5 changes: 5 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Project: jackson-databind
=== Releases ===
------------------------------------------------------------------------

2.8.9 (not yet released)

#1597: Escape JSONP breaking characters
(contributed by Marco C)

2.8.8.1 (19-Apr-2017)

#1585: Invoke ServiceLoader.load() inside of a privileged block when loading
Expand Down
44 changes: 29 additions & 15 deletions src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
* <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> wrapping.
*
* @see com.fasterxml.jackson.databind.util.JSONWrappedObject
*
* @author tatu
*/
public class JSONPObject
implements JsonSerializable
Expand Down Expand Up @@ -55,29 +53,45 @@ public JSONPObject(String function, Object value, JavaType asType)
*/

@Override
public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer)
throws IOException, JsonProcessingException
public void serializeWithType(JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer)
throws IOException
{
// No type for JSONP wrapping: value serializer will handle typing for value:
serialize(jgen, provider);
serialize(gen, provider);
}

@Override
public void serialize(JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException
public void serialize(JsonGenerator gen, SerializerProvider provider)
throws IOException
{
// First, wrapping:
jgen.writeRaw(_function);
jgen.writeRaw('(');
gen.writeRaw(_function);
gen.writeRaw('(');

if (_value == null) {
provider.defaultSerializeNull(jgen);
} else if (_serializationType != null) {
provider.findTypedValueSerializer(_serializationType, true, null).serialize(_value, jgen, provider);
provider.defaultSerializeNull(gen);
} else {
Class<?> cls = _value.getClass();
provider.findTypedValueSerializer(cls, true, null).serialize(_value, jgen, provider);
// 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).
boolean override = (gen.getCharacterEscapes() == null);
if (override) {
gen.setCharacterEscapes(JsonpCharacterEscapes.instance());
}

try {
if (_serializationType != null) {
provider.findTypedValueSerializer(_serializationType, true, null).serialize(_value, gen, provider);
} else {
provider.findTypedValueSerializer(_value.getClass(), true, null).serialize(_value, gen, provider);
}
} finally {
if (override) {
gen.setCharacterEscapes(null);
}
}
}
jgen.writeRaw(')');
gen.writeRaw(')');
}

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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();

/**
* 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);
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"));
}
}

1 comment on commit 513ab6e

@catanm
Copy link
Contributor

@catanm catanm commented on 513ab6e Apr 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cowtowncoder many thanks!

Please sign in to comment.