Permalink
Browse files

always validate object keys are unique

  • Loading branch information...
1 parent 7324036 commit f5b9bef5fefbe9ace4ee17026c05cf0112ff18b6 @ropalka ropalka committed Sep 20, 2012
@@ -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() {
@@ -248,6 +248,7 @@ public JsonEvent next() throws IOException {
analyzer.push( JsonGrammarToken.STRING );
in.unread( currentChar );
readString();
+ analyzer.pushString( jsonString );
exitLoop = true;
}
break;
@@ -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;
}
@@ -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() );
+ }
+ }
}
Oops, something went wrong.

0 comments on commit f5b9bef

Please sign in to comment.