Implemented enhancement request from issue 42 by supporting a new GsonBuilder setting generateNonExecutableJson() that prefixes the generated JSON with some special text that makes the output non-executable javascript. Gson now recognizes this special text in the input while parsing the JSON in fromJson and filters it out, if present.
This commit is contained in:
parent
1c5785be57
commit
b2b2e5dc0a
|
@ -76,6 +76,8 @@ public final class Gson {
|
|||
|
||||
private static final String NULL_STRING = "null";
|
||||
|
||||
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
||||
|
||||
// Default instances of plug-ins
|
||||
static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
|
||||
new ModifierBasedExclusionStrategy(true, new int[] { Modifier.TRANSIENT, Modifier.STATIC });
|
||||
|
@ -83,6 +85,8 @@ public final class Gson {
|
|||
static final FieldNamingStrategy DEFAULT_NAMING_POLICY =
|
||||
new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
|
||||
|
||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n<data>";
|
||||
|
||||
private final ExclusionStrategy strategy;
|
||||
private final FieldNamingStrategy fieldNamingPolicy;
|
||||
private final MappedObjectConstructor objectConstructor;
|
||||
|
@ -96,6 +100,8 @@ public final class Gson {
|
|||
private final JsonFormatter formatter;
|
||||
private final boolean serializeNulls;
|
||||
|
||||
private final boolean generateNonExecutableJson;
|
||||
|
||||
/**
|
||||
* Constructs a Gson object with default configuration. The default configuration has the
|
||||
* following settings:
|
||||
|
@ -142,13 +148,14 @@ public final class Gson {
|
|||
this(strategy, fieldNamingPolicy,
|
||||
new MappedObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
|
||||
DEFAULT_JSON_FORMATTER, false, DefaultTypeAdapters.getDefaultSerializers(),
|
||||
DefaultTypeAdapters.getDefaultDeserializers());
|
||||
DefaultTypeAdapters.getDefaultDeserializers(), DEFAULT_JSON_NON_EXECUTABLE);
|
||||
}
|
||||
|
||||
Gson(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy,
|
||||
MappedObjectConstructor objectConstructor, JsonFormatter formatter, boolean serializeNulls,
|
||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
|
||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
||||
boolean generateNonExecutableGson) {
|
||||
this.strategy = strategy;
|
||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||
this.objectConstructor = objectConstructor;
|
||||
|
@ -156,6 +163,7 @@ public final class Gson {
|
|||
this.serializeNulls = serializeNulls;
|
||||
this.serializers = serializers;
|
||||
this.deserializers = deserializers;
|
||||
this.generateNonExecutableJson = generateNonExecutableGson;
|
||||
}
|
||||
|
||||
private ObjectNavigatorFactory createDefaultObjectNavigatorFactory() {
|
||||
|
@ -260,6 +268,9 @@ public final class Gson {
|
|||
createDefaultObjectNavigatorFactory(), serializeNulls, serializers);
|
||||
JsonElement jsonElement = context.serialize(src, typeOfSrc);
|
||||
|
||||
if (generateNonExecutableJson) {
|
||||
writer.append(JSON_NON_EXECUTABLE_PREFIX);
|
||||
}
|
||||
//TODO(Joel): instead of navigating the "JsonElement" inside the formatter, do it here.
|
||||
formatter.format(jsonElement, writer, serializeNulls);
|
||||
} else {
|
||||
|
|
|
@ -73,6 +73,7 @@ public final class GsonBuilder {
|
|||
private boolean serializeSpecialFloatingPointValues;
|
||||
private boolean escapeHtmlChars;
|
||||
private boolean prettyPrinting;
|
||||
private boolean generateNonExecutableJson;
|
||||
|
||||
/**
|
||||
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
|
||||
|
@ -97,6 +98,7 @@ public final class GsonBuilder {
|
|||
dateStyle = DateFormat.DEFAULT;
|
||||
timeStyle = DateFormat.DEFAULT;
|
||||
serializeSpecialFloatingPointValues = false;
|
||||
generateNonExecutableJson = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,6 +130,20 @@ public final class GsonBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the output JSON non-executable in Javascript by prefixing the generated JSON with some
|
||||
* special text. This prevents attacks from third-party sites through script sourcing. See
|
||||
* <a href="http://code.google.com/p/google-gson/issues/detail?id=42">Gson Issue 42</a>
|
||||
* for details.
|
||||
*
|
||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||
* @since 1.3
|
||||
*/
|
||||
public GsonBuilder generateNonExecutableJson() {
|
||||
this.generateNonExecutableJson = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Gson to exclude all fields from consideration for serialization or deserialization
|
||||
* that do not have the {@link com.google.gson.annotations.Expose} annotation.
|
||||
|
@ -430,7 +446,7 @@ public final class GsonBuilder {
|
|||
JsonFormatter formatter = prettyPrinting ?
|
||||
new JsonPrintFormatter(escapeHtmlChars) : new JsonCompactFormatter(escapeHtmlChars);
|
||||
Gson gson = new Gson(exclusionStrategy, fieldNamingPolicy, objConstructor,
|
||||
formatter, serializeNulls, customSerializers, customDeserializers);
|
||||
formatter, serializeNulls, customSerializers, customDeserializers, generateNonExecutableJson);
|
||||
return gson;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,17 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
JsonElement json = null;
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 26:
|
||||
jj_consume_token(26);
|
||||
break;
|
||||
default:
|
||||
jj_la1[0] = jj_gen;
|
||||
;
|
||||
}
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 27:
|
||||
json = JsonObject();
|
||||
break;
|
||||
case 30:
|
||||
case 31:
|
||||
json = JsonArray();
|
||||
break;
|
||||
case DIGITS:
|
||||
|
@ -19,14 +27,14 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
case BOOLEAN:
|
||||
case SINGLE_QUOTE_LITERAL:
|
||||
case DOUBLE_QUOTE_LITERAL:
|
||||
case 32:
|
||||
case 33:
|
||||
json = JsonPrimitive();
|
||||
break;
|
||||
case NULL:
|
||||
json = JsonNull();
|
||||
break;
|
||||
default:
|
||||
jj_la1[0] = jj_gen;
|
||||
jj_la1[1] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -36,7 +44,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
|
||||
final private JsonObject JsonObject() throws ParseException {
|
||||
JsonObject o = new JsonObject();
|
||||
jj_consume_token(26);
|
||||
jj_consume_token(27);
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case IDENTIFIER_SANS_EXPONENT:
|
||||
case IDENTIFIER_STARTS_WITH_EXPONENT:
|
||||
|
@ -45,10 +53,10 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
Members(o);
|
||||
break;
|
||||
default:
|
||||
jj_la1[1] = jj_gen;
|
||||
jj_la1[2] = jj_gen;
|
||||
;
|
||||
}
|
||||
jj_consume_token(27);
|
||||
jj_consume_token(28);
|
||||
{if (true) return o;}
|
||||
throw new Error("Missing return statement in function");
|
||||
}
|
||||
|
@ -63,12 +71,12 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
final private void Members(JsonObject o) throws ParseException {
|
||||
Pair(o);
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 28:
|
||||
jj_consume_token(28);
|
||||
case 29:
|
||||
jj_consume_token(29);
|
||||
Members(o);
|
||||
break;
|
||||
default:
|
||||
jj_la1[2] = jj_gen;
|
||||
jj_la1[3] = jj_gen;
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +85,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
JsonPrimitive property;
|
||||
JsonElement value;
|
||||
property = JsonMemberName();
|
||||
jj_consume_token(29);
|
||||
jj_consume_token(30);
|
||||
value = JsonValue();
|
||||
o.add(property.getAsString(), value);
|
||||
}
|
||||
|
@ -96,7 +104,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
{if (true) return value;}
|
||||
break;
|
||||
default:
|
||||
jj_la1[3] = jj_gen;
|
||||
jj_la1[4] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -105,7 +113,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
|
||||
final private JsonArray JsonArray() throws ParseException {
|
||||
JsonArray array = new JsonArray();
|
||||
jj_consume_token(30);
|
||||
jj_consume_token(31);
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case DIGITS:
|
||||
case NULL:
|
||||
|
@ -114,16 +122,16 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
case BOOLEAN:
|
||||
case SINGLE_QUOTE_LITERAL:
|
||||
case DOUBLE_QUOTE_LITERAL:
|
||||
case 26:
|
||||
case 30:
|
||||
case 32:
|
||||
case 27:
|
||||
case 31:
|
||||
case 33:
|
||||
Elements(array);
|
||||
break;
|
||||
default:
|
||||
jj_la1[4] = jj_gen;
|
||||
jj_la1[5] = jj_gen;
|
||||
;
|
||||
}
|
||||
jj_consume_token(31);
|
||||
jj_consume_token(32);
|
||||
array.reverse();
|
||||
{if (true) return array;}
|
||||
throw new Error("Missing return statement in function");
|
||||
|
@ -133,12 +141,12 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
JsonElement element;
|
||||
element = JsonValue();
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 28:
|
||||
jj_consume_token(28);
|
||||
case 29:
|
||||
jj_consume_token(29);
|
||||
Elements(array);
|
||||
break;
|
||||
default:
|
||||
jj_la1[5] = jj_gen;
|
||||
jj_la1[6] = jj_gen;
|
||||
;
|
||||
}
|
||||
array.add(element);
|
||||
|
@ -154,13 +162,13 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
case DIGITS:
|
||||
case NAN:
|
||||
case INFINITY:
|
||||
case 32:
|
||||
case 33:
|
||||
o = JsonNumber();
|
||||
break;
|
||||
case 26:
|
||||
case 27:
|
||||
o = JsonObject();
|
||||
break;
|
||||
case 30:
|
||||
case 31:
|
||||
o = JsonArray();
|
||||
break;
|
||||
case BOOLEAN:
|
||||
|
@ -170,7 +178,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
o = JsonNull();
|
||||
break;
|
||||
default:
|
||||
jj_la1[6] = jj_gen;
|
||||
jj_la1[7] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -197,7 +205,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
case DIGITS:
|
||||
case NAN:
|
||||
case INFINITY:
|
||||
case 32:
|
||||
case 33:
|
||||
value = JsonNumber();
|
||||
{if (true) return value;}
|
||||
break;
|
||||
|
@ -206,7 +214,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
{if (true) return value;}
|
||||
break;
|
||||
default:
|
||||
jj_la1[7] = jj_gen;
|
||||
jj_la1[8] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -224,14 +232,14 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
} else {
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case DIGITS:
|
||||
case 32:
|
||||
case 33:
|
||||
intpart = JsonInt();
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 33:
|
||||
case 34:
|
||||
fracpart = JsonFrac();
|
||||
break;
|
||||
default:
|
||||
jj_la1[8] = jj_gen;
|
||||
jj_la1[9] = jj_gen;
|
||||
;
|
||||
}
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
|
@ -239,7 +247,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
exppart = JsonExp();
|
||||
break;
|
||||
default:
|
||||
jj_la1[9] = jj_gen;
|
||||
jj_la1[10] = jj_gen;
|
||||
;
|
||||
}
|
||||
Number n;
|
||||
|
@ -253,7 +261,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
{if (true) return new JsonPrimitive(n);}
|
||||
break;
|
||||
default:
|
||||
jj_la1[10] = jj_gen;
|
||||
jj_la1[11] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -269,21 +277,21 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
{if (true) return new JsonPrimitive(Double.NaN);}
|
||||
break;
|
||||
case INFINITY:
|
||||
case 32:
|
||||
case 33:
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 32:
|
||||
jj_consume_token(32);
|
||||
case 33:
|
||||
jj_consume_token(33);
|
||||
negative = true;
|
||||
break;
|
||||
default:
|
||||
jj_la1[11] = jj_gen;
|
||||
jj_la1[12] = jj_gen;
|
||||
;
|
||||
}
|
||||
jj_consume_token(INFINITY);
|
||||
{if (true) return new JsonPrimitive(negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY);}
|
||||
break;
|
||||
default:
|
||||
jj_la1[12] = jj_gen;
|
||||
jj_la1[13] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -294,12 +302,12 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
String digits;
|
||||
boolean negative = false;
|
||||
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
|
||||
case 32:
|
||||
jj_consume_token(32);
|
||||
case 33:
|
||||
jj_consume_token(33);
|
||||
negative = true;
|
||||
break;
|
||||
default:
|
||||
jj_la1[13] = jj_gen;
|
||||
jj_la1[14] = jj_gen;
|
||||
;
|
||||
}
|
||||
digits = Digits();
|
||||
|
@ -311,7 +319,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
|
||||
final private String JsonFrac() throws ParseException {
|
||||
String digits;
|
||||
jj_consume_token(33);
|
||||
jj_consume_token(34);
|
||||
digits = Digits();
|
||||
{if (true) return "." + digits;}
|
||||
throw new Error("Missing return statement in function");
|
||||
|
@ -334,7 +342,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
t = jj_consume_token(IDENTIFIER_SANS_EXPONENT);
|
||||
break;
|
||||
default:
|
||||
jj_la1[14] = jj_gen;
|
||||
jj_la1[15] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -359,7 +367,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
t = jj_consume_token(DOUBLE_QUOTE_LITERAL);
|
||||
break;
|
||||
default:
|
||||
jj_la1[15] = jj_gen;
|
||||
jj_la1[16] = jj_gen;
|
||||
jj_consume_token(-1);
|
||||
throw new ParseException();
|
||||
}
|
||||
|
@ -376,7 +384,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
}
|
||||
|
||||
private boolean jj_3R_4() {
|
||||
if (jj_scan_token(32)) return true;
|
||||
if (jj_scan_token(33)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -419,7 +427,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
private Token jj_scanpos, jj_lastpos;
|
||||
private int jj_la;
|
||||
private int jj_gen;
|
||||
final private int[] jj_la1 = new int[16];
|
||||
final private int[] jj_la1 = new int[17];
|
||||
static private int[] jj_la1_0;
|
||||
static private int[] jj_la1_1;
|
||||
static {
|
||||
|
@ -427,10 +435,10 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
jj_la1_init_1();
|
||||
}
|
||||
private static void jj_la1_init_0() {
|
||||
jj_la1_0 = new int[] {0x440307c0,0x31800,0x10000000,0x31800,0x440307c0,0x10000000,0x440307c0,0x30740,0x0,0x20,0x40,0x0,0x300,0x0,0x1800,0x30000,};
|
||||
jj_la1_0 = new int[] {0x4000000,0x880307c0,0x31800,0x20000000,0x31800,0x880307c0,0x20000000,0x880307c0,0x30740,0x0,0x20,0x40,0x0,0x300,0x0,0x1800,0x30000,};
|
||||
}
|
||||
private static void jj_la1_init_1() {
|
||||
jj_la1_1 = new int[] {0x1,0x0,0x0,0x0,0x1,0x0,0x1,0x1,0x2,0x0,0x1,0x1,0x1,0x1,0x0,0x0,};
|
||||
jj_la1_1 = new int[] {0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x2,0x2,0x4,0x0,0x2,0x2,0x2,0x2,0x0,0x0,};
|
||||
}
|
||||
final private JJCalls[] jj_2_rtns = new JJCalls[1];
|
||||
private boolean jj_rescan = false;
|
||||
|
@ -447,7 +455,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 16; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 17; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
|
||||
}
|
||||
|
||||
|
@ -462,7 +470,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 16; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 17; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
|
||||
}
|
||||
|
||||
|
@ -473,7 +481,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 16; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 17; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
|
||||
}
|
||||
|
||||
|
@ -484,7 +492,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 16; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 17; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
|
||||
}
|
||||
|
||||
|
@ -494,7 +502,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 16; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 17; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
|
||||
}
|
||||
|
||||
|
@ -504,7 +512,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
token = new Token();
|
||||
jj_ntk = -1;
|
||||
jj_gen = 0;
|
||||
for (int i = 0; i < 16; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < 17; i++) jj_la1[i] = -1;
|
||||
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
|
||||
}
|
||||
|
||||
|
@ -616,12 +624,12 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
/** Generate ParseException. */
|
||||
public ParseException generateParseException() {
|
||||
jj_expentries.clear();
|
||||
boolean[] la1tokens = new boolean[34];
|
||||
boolean[] la1tokens = new boolean[35];
|
||||
if (jj_kind >= 0) {
|
||||
la1tokens[jj_kind] = true;
|
||||
jj_kind = -1;
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int i = 0; i < 17; i++) {
|
||||
if (jj_la1[i] == jj_gen) {
|
||||
for (int j = 0; j < 32; j++) {
|
||||
if ((jj_la1_0[i] & (1<<j)) != 0) {
|
||||
|
@ -633,7 +641,7 @@ final class JsonParserImpl implements JsonParserImplConstants {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 34; i++) {
|
||||
for (int i = 0; i < 35; i++) {
|
||||
if (la1tokens[i]) {
|
||||
jj_expentry = new int[1];
|
||||
jj_expentry[0] = i;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Generated By:JavaCC: Do not edit this line. JsonParserImplConstants.java */
|
||||
package com.google.gson;
|
||||
|
||||
|
||||
/**
|
||||
* Token literal values and constants.
|
||||
* Generated by org.javacc.parser.OtherFilesGen#start()
|
||||
|
@ -87,6 +86,7 @@ interface JsonParserImplConstants {
|
|||
"\"u\"",
|
||||
"<HEX>",
|
||||
"<HEX_ESC>",
|
||||
"\")]}\\\'\\n<data>\"",
|
||||
"\"{\"",
|
||||
"\"}\"",
|
||||
"\",\"",
|
||||
|
|
|
@ -172,6 +172,10 @@ private final int jjStopStringLiteralDfa_0(int pos, long active0)
|
|||
return 10;
|
||||
}
|
||||
return -1;
|
||||
case 7:
|
||||
if ((active0 & 0x200L) != 0L)
|
||||
return 10;
|
||||
return -1;
|
||||
default :
|
||||
return -1;
|
||||
}
|
||||
|
@ -192,28 +196,30 @@ private int jjMoveStringLiteralDfa0_0()
|
|||
{
|
||||
case 34:
|
||||
return jjStartNfaWithStates_0(0, 18, 43);
|
||||
case 41:
|
||||
return jjMoveStringLiteralDfa1_0(0x4000000L);
|
||||
case 44:
|
||||
return jjStopAtPos(0, 28);
|
||||
case 45:
|
||||
return jjStopAtPos(0, 32);
|
||||
case 46:
|
||||
return jjStopAtPos(0, 33);
|
||||
case 58:
|
||||
return jjStopAtPos(0, 29);
|
||||
case 45:
|
||||
return jjStopAtPos(0, 33);
|
||||
case 46:
|
||||
return jjStopAtPos(0, 34);
|
||||
case 58:
|
||||
return jjStopAtPos(0, 30);
|
||||
case 73:
|
||||
return jjMoveStringLiteralDfa1_0(0x200L);
|
||||
case 78:
|
||||
return jjMoveStringLiteralDfa1_0(0x100L);
|
||||
case 91:
|
||||
return jjStopAtPos(0, 30);
|
||||
case 93:
|
||||
return jjStopAtPos(0, 31);
|
||||
case 93:
|
||||
return jjStopAtPos(0, 32);
|
||||
case 110:
|
||||
return jjMoveStringLiteralDfa1_0(0x80L);
|
||||
case 123:
|
||||
return jjStopAtPos(0, 26);
|
||||
case 125:
|
||||
return jjStopAtPos(0, 27);
|
||||
case 125:
|
||||
return jjStopAtPos(0, 28);
|
||||
default :
|
||||
return jjMoveNfa_0(4, 0);
|
||||
}
|
||||
|
@ -227,6 +233,8 @@ private int jjMoveStringLiteralDfa1_0(long active0)
|
|||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 93:
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x4000000L);
|
||||
case 97:
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x100L);
|
||||
case 110:
|
||||
|
@ -257,6 +265,8 @@ private int jjMoveStringLiteralDfa2_0(long old0, long active0)
|
|||
return jjMoveStringLiteralDfa3_0(active0, 0x200L);
|
||||
case 108:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0x80L);
|
||||
case 125:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0x4000000L);
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
@ -273,6 +283,8 @@ private int jjMoveStringLiteralDfa3_0(long old0, long active0)
|
|||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 39:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x4000000L);
|
||||
case 105:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x200L);
|
||||
case 108:
|
||||
|
@ -295,6 +307,8 @@ private int jjMoveStringLiteralDfa4_0(long old0, long active0)
|
|||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 10:
|
||||
return jjMoveStringLiteralDfa5_0(active0, 0x4000000L);
|
||||
case 110:
|
||||
return jjMoveStringLiteralDfa5_0(active0, 0x200L);
|
||||
default :
|
||||
|
@ -313,6 +327,8 @@ private int jjMoveStringLiteralDfa5_0(long old0, long active0)
|
|||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 60:
|
||||
return jjMoveStringLiteralDfa6_0(active0, 0x4000000L);
|
||||
case 105:
|
||||
return jjMoveStringLiteralDfa6_0(active0, 0x200L);
|
||||
default :
|
||||
|
@ -331,6 +347,8 @@ private int jjMoveStringLiteralDfa6_0(long old0, long active0)
|
|||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 100:
|
||||
return jjMoveStringLiteralDfa7_0(active0, 0x4000000L);
|
||||
case 116:
|
||||
return jjMoveStringLiteralDfa7_0(active0, 0x200L);
|
||||
default :
|
||||
|
@ -349,6 +367,8 @@ private int jjMoveStringLiteralDfa7_0(long old0, long active0)
|
|||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 97:
|
||||
return jjMoveStringLiteralDfa8_0(active0, 0x4000000L);
|
||||
case 121:
|
||||
if ((active0 & 0x200L) != 0L)
|
||||
return jjStartNfaWithStates_0(7, 9, 10);
|
||||
|
@ -358,6 +378,62 @@ private int jjMoveStringLiteralDfa7_0(long old0, long active0)
|
|||
}
|
||||
return jjStartNfa_0(6, active0);
|
||||
}
|
||||
private int jjMoveStringLiteralDfa8_0(long old0, long active0)
|
||||
{
|
||||
if (((active0 &= old0)) == 0L)
|
||||
return jjStartNfa_0(6, old0);
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) {
|
||||
jjStopStringLiteralDfa_0(7, active0);
|
||||
return 8;
|
||||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 116:
|
||||
return jjMoveStringLiteralDfa9_0(active0, 0x4000000L);
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return jjStartNfa_0(7, active0);
|
||||
}
|
||||
private int jjMoveStringLiteralDfa9_0(long old0, long active0)
|
||||
{
|
||||
if (((active0 &= old0)) == 0L)
|
||||
return jjStartNfa_0(7, old0);
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) {
|
||||
jjStopStringLiteralDfa_0(8, active0);
|
||||
return 9;
|
||||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 97:
|
||||
return jjMoveStringLiteralDfa10_0(active0, 0x4000000L);
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return jjStartNfa_0(8, active0);
|
||||
}
|
||||
private int jjMoveStringLiteralDfa10_0(long old0, long active0)
|
||||
{
|
||||
if (((active0 &= old0)) == 0L)
|
||||
return jjStartNfa_0(8, old0);
|
||||
try { curChar = input_stream.readChar(); }
|
||||
catch(java.io.IOException e) {
|
||||
jjStopStringLiteralDfa_0(9, active0);
|
||||
return 10;
|
||||
}
|
||||
switch(curChar)
|
||||
{
|
||||
case 62:
|
||||
if ((active0 & 0x4000000L) != 0L)
|
||||
return jjStopAtPos(10, 26);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return jjStartNfa_0(9, active0);
|
||||
}
|
||||
private int jjStartNfaWithStates_0(int pos, int kind, int state)
|
||||
{
|
||||
jjmatchedKind = kind;
|
||||
|
@ -976,7 +1052,8 @@ private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, lo
|
|||
public static final String[] jjstrLiteralImages = {
|
||||
"", null, null, null, null, null, null, "\156\165\154\154", "\116\141\116",
|
||||
"\111\156\146\151\156\151\164\171", null, null, null, null, null, null, null, null, "\42", null, null, null, null,
|
||||
null, null, null, "\173", "\175", "\54", "\72", "\133", "\135", "\55", "\56", };
|
||||
null, null, null, "\51\135\175\47\12\74\144\141\164\141\76", "\173", "\175", "\54",
|
||||
"\72", "\133", "\135", "\55", "\56", };
|
||||
|
||||
/** Lexer state names. */
|
||||
public static final String[] lexStateNames = {
|
||||
|
@ -989,10 +1066,10 @@ public static final String[] lexStateNames = {
|
|||
/** Lex State array. */
|
||||
public static final int[] jjnewLexState = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 0, -1, 1, 3, -1,
|
||||
1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
};
|
||||
static final long[] jjtoToken = {
|
||||
0x3fe775fe1L,
|
||||
0x7fe775fe1L,
|
||||
};
|
||||
static final long[] jjtoSkip = {
|
||||
0x1eL,
|
||||
|
|
|
@ -60,7 +60,7 @@ public JsonElement parse() :
|
|||
JsonElement json = null;
|
||||
}
|
||||
{
|
||||
( json=JsonObject() |
|
||||
[")]}'\n<data>"]( json=JsonObject() |
|
||||
json=JsonArray() |
|
||||
json=JsonPrimitive() |
|
||||
json=JsonNull())
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.functional;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.common.TestTypes.BagOfPrimitives;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for security-related aspects of Gson
|
||||
*
|
||||
* @author Inderjeet Singh
|
||||
*/
|
||||
public class SecurityTest extends TestCase {
|
||||
/**
|
||||
* Keep this in sync with Gson.JSON_NON_EXECUTABLE_PREFIX
|
||||
*/
|
||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n<data>";
|
||||
|
||||
private GsonBuilder gsonBuilder;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
gsonBuilder = new GsonBuilder();
|
||||
}
|
||||
|
||||
public void testNonExecutableJsonSerialization() {
|
||||
Gson gson = gsonBuilder.generateNonExecutableJson().create();
|
||||
String json = gson.toJson(new BagOfPrimitives());
|
||||
assertTrue(json.startsWith(JSON_NON_EXECUTABLE_PREFIX));
|
||||
}
|
||||
|
||||
public void testNonExecutableJsonDeserialization() {
|
||||
String json = JSON_NON_EXECUTABLE_PREFIX + "{longValue:1}";
|
||||
Gson gson = gsonBuilder.create();
|
||||
BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class);
|
||||
assertEquals(1, target.longValue);
|
||||
}
|
||||
|
||||
public void testJsonWithNonExectuableTokenSerialization() {
|
||||
Gson gson = gsonBuilder.generateNonExecutableJson().create();
|
||||
String json = gson.toJson(JSON_NON_EXECUTABLE_PREFIX);
|
||||
assertTrue(json.contains(")]}'\n\u003cdata\u003e"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gson should be able to deserialize a stream with non-exectuable token even if it is created
|
||||
* without {@link GsonBuilder#generateNonExecutableJson()}.
|
||||
*/
|
||||
public void testJsonWithNonExectuableTokenWithRegularGsonDeserialization() {
|
||||
Gson gson = gsonBuilder.create();
|
||||
String json = JSON_NON_EXECUTABLE_PREFIX + "{stringValue:')]}\\u0027\\n<data>'}";
|
||||
BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class);
|
||||
assertEquals(")]}'\n<data>", target.stringValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gson should be able to deserialize a stream with non-exectuable token if it is created
|
||||
* with {@link GsonBuilder#generateNonExecutableJson()}.
|
||||
*/
|
||||
public void testJsonWithNonExectuableTokenWithConfiguredGsonDeserialization() {
|
||||
// Gson should be able to deserialize a stream with non-exectuable token even if it is created
|
||||
Gson gson = gsonBuilder.generateNonExecutableJson().create();
|
||||
String json = JSON_NON_EXECUTABLE_PREFIX + "{intValue:2,stringValue:')]}\\u0027\\n<data>'}";
|
||||
BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class);
|
||||
assertEquals(")]}'\n<data>", target.stringValue);
|
||||
assertEquals(2, target.intValue);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user