Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

always validate object keys are unique

  • Loading branch information...
commit f5b9bef5fefbe9ace4ee17026c05cf0112ff18b6 1 parent 7324036
@ropalka ropalka authored
View
16 modules/impl/src/main/java/com/fossnova/json/stream/JsonGrammarAnalyzer.java
@@ -30,7 +30,9 @@
import static com.fossnova.json.stream.JsonGrammarToken.OBJECT_START;
import static com.fossnova.json.stream.JsonGrammarToken.STRING;
+import java.util.HashSet;
import java.util.LinkedList;
+import java.util.Set;
import org.fossnova.json.stream.JsonEvent;
import org.fossnova.json.stream.JsonException;
@@ -46,6 +48,8 @@
private boolean finished;
+ private final LinkedList< Set< String >> jsonKeys = new LinkedList< Set< String >>();
+
private final LinkedList< JsonGrammarToken > stack = new LinkedList< JsonGrammarToken >();
JsonGrammarAnalyzer() {
@@ -88,6 +92,15 @@ void push( final JsonGrammarToken event ) {
}
}
+ void pushString( final String jsonKey ) {
+ if ( isLastOnStack( STRING ) ) {
+ final boolean containsKey = !jsonKeys.getLast().add( jsonKey );
+ if ( containsKey ) {
+ throw newJsonException( "JSON keys have to be unique. The key '" + jsonKey + "' already exists" );
+ }
+ }
+ }
+
JsonEvent getCurrentEvent() {
return currentEvent;
}
@@ -132,6 +145,8 @@ private void putObjectEnd() {
} else if ( isLastOnStack( ARRAY_START ) ) {
canWriteComma = true;
}
+ jsonKeys.getLast().clear();
+ jsonKeys.removeLast();
if ( isEmpty() ) {
setCannotContinue();
}
@@ -193,6 +208,7 @@ private void putObjectStart() {
}
// implementation
stack.add( OBJECT_START );
+ jsonKeys.addLast( new HashSet< String >() );
}
private void putArrayStart() {
View
1  modules/impl/src/main/java/com/fossnova/json/stream/JsonReaderImpl.java
@@ -248,6 +248,7 @@ public JsonEvent next() throws IOException {
analyzer.push( JsonGrammarToken.STRING );
in.unread( currentChar );
readString();
+ analyzer.pushString( jsonString );
exitLoop = true;
}
break;
View
1  modules/impl/src/main/java/com/fossnova/json/stream/JsonWriterImpl.java
@@ -100,6 +100,7 @@ public JsonWriterImpl writeString( final String data ) throws IOException {
ensureOpen();
writeOptionalColonOrComma();
analyzer.push( JsonGrammarToken.STRING );
+ analyzer.pushString( data );
out.write( encode( data ) );
return this;
}
View
37 modules/tests/src/test/java/test/fossnova/json/InvalidJsonReaderTestCase.java
@@ -19,6 +19,8 @@
*/
package test.fossnova.json;
+import static org.junit.Assert.assertEquals;
+
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -385,6 +387,12 @@ public void notEmptyObjectStartState() throws IOException {
}
@Test
+ public void uniqueObjectKeys() throws IOException {
+ read_objectStart_string_null_string();
+ read_objectStart_string_objectStart_string_null_objectEnd_string();
+ }
+
+ @Test
public void unexpectedEOF() throws IOException {
read_arrayStart_string_EOF();
read_arrayStart_number_EOF();
@@ -3161,4 +3169,33 @@ private void read_arrayStart_wrongDouble() throws IOException {
assertDoubleState( reader, 0.0 );
} catch ( final NumberFormatException ignore ) {}
}
+
+ private void read_objectStart_string_null_string() throws IOException {
+ final String sameKey = "same key";
+ final JsonReader reader = getJsonReader( "{\"" + sameKey + "\":null,\"" + sameKey + "\"" );
+ assertObjectStartState( reader );
+ assertStringState( reader, sameKey );
+ assertNullState( reader );
+ try {
+ reader.next();
+ } catch ( final JsonException e ) {
+ assertEquals( "JSON keys have to be unique. The key '" + sameKey + "' already exists", e.getMessage() );
+ }
+ }
+
+ private void read_objectStart_string_objectStart_string_null_objectEnd_string() throws IOException {
+ final String sameKey = "same key";
+ final JsonReader reader = getJsonReader( "{\"" + sameKey + "\":{\"" + sameKey + "\":null},\"" + sameKey + "\"" );
+ assertObjectStartState( reader );
+ assertStringState( reader, sameKey );
+ assertObjectStartState( reader );
+ assertStringState( reader, sameKey );
+ assertNullState( reader );
+ assertObjectEndState( reader );
+ try {
+ reader.next();
+ } catch ( final JsonException e ) {
+ assertEquals( "JSON keys have to be unique. The key '" + sameKey + "' already exists", e.getMessage() );
+ }
+ }
}
View
133 modules/tests/src/test/java/test/fossnova/json/InvalidJsonWriterTestCase.java
@@ -172,6 +172,12 @@ public void notEmptyObjectStartState() throws IOException {
write_objectStart_string_null_string_arrayEnd();
}
+ @Test
+ public void uniqueObjectKeys() throws IOException {
+ write_objectStart_string_null_string();
+ write_objectStart_string_objectStart_string_null_objectEnd_string();
+ }
+
private void write_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
try {
@@ -1166,9 +1172,9 @@ private void write_objectStart_string_string_null() throws IOException {
private void write_objectStart_string_string_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
+ writer.writeString( "1" );
writer.writeString( "" );
- writer.writeString( "" );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1180,9 +1186,9 @@ private void write_objectStart_string_string_string_objectEnd() throws IOExcepti
private void write_objectStart_string_byte_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeByte( ( byte ) 0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1194,9 +1200,9 @@ private void write_objectStart_string_byte_string_objectEnd() throws IOException
private void write_objectStart_string_short_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeShort( ( short ) 0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1208,9 +1214,9 @@ private void write_objectStart_string_short_string_objectEnd() throws IOExceptio
private void write_objectStart_string_int_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeInt( 0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1222,9 +1228,9 @@ private void write_objectStart_string_int_string_objectEnd() throws IOException
private void write_objectStart_string_long_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeLong( 0L );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1236,9 +1242,9 @@ private void write_objectStart_string_long_string_objectEnd() throws IOException
private void write_objectStart_string_bigInteger_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBigInteger( BigInteger.ZERO );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1250,9 +1256,9 @@ private void write_objectStart_string_bigInteger_string_objectEnd() throws IOExc
private void write_objectStart_string_bigDecimal_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBigDecimal( BigDecimal.ZERO );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1264,9 +1270,9 @@ private void write_objectStart_string_bigDecimal_string_objectEnd() throws IOExc
private void write_objectStart_string_float_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeFloat( 0.0F );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1278,9 +1284,9 @@ private void write_objectStart_string_float_string_objectEnd() throws IOExceptio
private void write_objectStart_string_double_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeDouble( 0.0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1292,9 +1298,9 @@ private void write_objectStart_string_double_string_objectEnd() throws IOExcepti
private void write_objectStart_string_false_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBoolean( false );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1306,9 +1312,9 @@ private void write_objectStart_string_false_string_objectEnd() throws IOExceptio
private void write_objectStart_string_true_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBoolean( true );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1320,9 +1326,9 @@ private void write_objectStart_string_true_string_objectEnd() throws IOException
private void write_objectStart_string_null_string_objectEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeNull();
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeObjectEnd();
fail();
@@ -1334,9 +1340,9 @@ private void write_objectStart_string_null_string_objectEnd() throws IOException
private void write_objectStart_string_string_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
+ writer.writeString( "1" );
writer.writeString( "" );
- writer.writeString( "" );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1348,9 +1354,9 @@ private void write_objectStart_string_string_string_arrayEnd() throws IOExceptio
private void write_objectStart_string_byte_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeByte( ( byte ) 0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1362,9 +1368,9 @@ private void write_objectStart_string_byte_string_arrayEnd() throws IOException
private void write_objectStart_string_short_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeShort( ( short ) 0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1376,9 +1382,9 @@ private void write_objectStart_string_short_string_arrayEnd() throws IOException
private void write_objectStart_string_int_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeInt( 0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1390,9 +1396,9 @@ private void write_objectStart_string_int_string_arrayEnd() throws IOException {
private void write_objectStart_string_long_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeLong( 0L );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1404,9 +1410,9 @@ private void write_objectStart_string_long_string_arrayEnd() throws IOException
private void write_objectStart_string_bigInteger_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBigInteger( BigInteger.ZERO );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1418,9 +1424,9 @@ private void write_objectStart_string_bigInteger_string_arrayEnd() throws IOExce
private void write_objectStart_string_bigDecimal_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBigDecimal( BigDecimal.ZERO );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1432,9 +1438,9 @@ private void write_objectStart_string_bigDecimal_string_arrayEnd() throws IOExce
private void write_objectStart_string_float_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeFloat( 0.0F );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1446,9 +1452,9 @@ private void write_objectStart_string_float_string_arrayEnd() throws IOException
private void write_objectStart_string_double_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeDouble( 0.0 );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1460,9 +1466,9 @@ private void write_objectStart_string_double_string_arrayEnd() throws IOExceptio
private void write_objectStart_string_false_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBoolean( false );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1474,9 +1480,9 @@ private void write_objectStart_string_false_string_arrayEnd() throws IOException
private void write_objectStart_string_true_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeBoolean( true );
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1488,9 +1494,9 @@ private void write_objectStart_string_true_string_arrayEnd() throws IOException
private void write_objectStart_string_null_string_arrayEnd() throws IOException {
final JsonWriter writer = getJsonWriter();
writer.writeObjectStart();
- writer.writeString( "" );
+ writer.writeString( "1" );
writer.writeNull();
- writer.writeString( "" );
+ writer.writeString( "2" );
try {
writer.writeArrayEnd();
fail();
@@ -1498,4 +1504,35 @@ private void write_objectStart_string_null_string_arrayEnd() throws IOException
assertEquals( "Expecting :", e.getMessage() );
}
}
+
+ private void write_objectStart_string_null_string() throws IOException {
+ final String sameKey = "same key";
+ final JsonWriter writer = getJsonWriter();
+ writer.writeObjectStart();
+ writer.writeString( sameKey );
+ writer.writeNull();
+ try {
+ writer.writeString( sameKey );
+ fail();
+ } catch ( final JsonException e ) {
+ assertEquals( "JSON keys have to be unique. The key '" + sameKey + "' already exists", e.getMessage() );
+ }
+ }
+
+ private void write_objectStart_string_objectStart_string_null_objectEnd_string() throws IOException {
+ final String sameKey = "same key";
+ final JsonWriter writer = getJsonWriter();
+ writer.writeObjectStart();
+ writer.writeString( sameKey );
+ writer.writeObjectStart();
+ writer.writeString( "same key" );
+ writer.writeNull();
+ writer.writeObjectEnd();
+ try {
+ writer.writeString( sameKey );
+ fail();
+ } catch ( final JsonException e ) {
+ assertEquals( "JSON keys have to be unique. The key '" + sameKey + "' already exists", e.getMessage() );
+ }
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.