Skip to content

Commit f3d729a

Browse files
authored
Merge pull request #1597 from catanm/escape-JSONP-breaking-characters
Escape JSONP breaking characters
2 parents a699637 + c091dc8 commit f3d729a

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

src/main/java/com/fasterxml/jackson/databind/util/JSONPObject.java

+25-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.fasterxml.jackson.core.*;
66

7+
import com.fasterxml.jackson.core.io.CharacterEscapes;
78
import com.fasterxml.jackson.databind.*;
89
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
910

@@ -66,18 +67,31 @@ public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, T
6667
public void serialize(JsonGenerator jgen, SerializerProvider provider)
6768
throws IOException, JsonProcessingException
6869
{
69-
// First, wrapping:
70-
jgen.writeRaw(_function);
71-
jgen.writeRaw('(');
72-
if (_value == null) {
73-
provider.defaultSerializeNull(jgen);
74-
} else if (_serializationType != null) {
75-
provider.findTypedValueSerializer(_serializationType, true, null).serialize(_value, jgen, provider);
76-
} else {
77-
Class<?> cls = _value.getClass();
78-
provider.findTypedValueSerializer(cls, true, null).serialize(_value, jgen, provider);
70+
CharacterEscapes currentCharacterEscapes = jgen.getCharacterEscapes();
71+
72+
// NOTE: Escape line-separator characters that break JSONP only if no custom character escapes are set.
73+
// If custom escapes are in place JSONP-breaking characters will not be escaped and it is recommended to
74+
// add escaping for those (see JsonpCharacterEscapes class).
75+
if (currentCharacterEscapes == null) {
76+
jgen.setCharacterEscapes(JsonpCharacterEscapes.instance());
77+
}
78+
79+
try {
80+
// First, wrapping:
81+
jgen.writeRaw(_function);
82+
jgen.writeRaw('(');
83+
if (_value == null) {
84+
provider.defaultSerializeNull(jgen);
85+
} else if (_serializationType != null) {
86+
provider.findTypedValueSerializer(_serializationType, true, null).serialize(_value, jgen, provider);
87+
} else {
88+
Class<?> cls = _value.getClass();
89+
provider.findTypedValueSerializer(cls, true, null).serialize(_value, jgen, provider);
90+
}
91+
jgen.writeRaw(')');
92+
} finally {
93+
jgen.setCharacterEscapes(currentCharacterEscapes);
7994
}
80-
jgen.writeRaw(')');
8195
}
8296

8397
/*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.fasterxml.jackson.databind.util;
2+
3+
import java.io.IOException;
4+
5+
import com.fasterxml.jackson.databind.BaseMapTest;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
8+
public class JSONPObjectTest extends BaseMapTest {
9+
10+
private final String CALLBACK = "callback";
11+
private final ObjectMapper MAPPER = new ObjectMapper();
12+
13+
/**
14+
* Unit tests for checking that JSONP breaking characters U+2028 and U+2029 are escaped when creating a {@link JSONPObject}.
15+
*/
16+
17+
public void testU2028Escaped() throws IOException {
18+
String containsU2028 = String.format("This string contains %c char", '\u2028');
19+
JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2028);
20+
String valueAsString = MAPPER.writeValueAsString(jsonpObject);
21+
assertFalse(valueAsString.contains("\u2028"));
22+
}
23+
24+
public void testU2029Escaped() throws IOException {
25+
String containsU2029 = String.format("This string contains %c char", '\u2029');
26+
JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2029);
27+
String valueAsString = MAPPER.writeValueAsString(jsonpObject);
28+
assertFalse(valueAsString.contains("\u2029"));
29+
}
30+
31+
public void testU2030NotEscaped() throws IOException {
32+
String containsU2030 = String.format("This string contains %c char", '\u2030');
33+
JSONPObject jsonpObject = new JSONPObject(CALLBACK, containsU2030);
34+
String valueAsString = MAPPER.writeValueAsString(jsonpObject);
35+
assertTrue(valueAsString.contains("\u2030"));
36+
}
37+
}

0 commit comments

Comments
 (0)