Skip to content

Commit e26b25e

Browse files
author
Antonio Sanchez
committed
Fixed bug with null values, since stacks should not allow null
1 parent 0976be9 commit e26b25e

File tree

4 files changed

+105
-7
lines changed

4 files changed

+105
-7
lines changed

src/main/java/org/json/simple/parser/ContainerContentHandler.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ private enum ContainerType {
1818
ARRAY
1919
}
2020

21+
private static Object NULL_VALUE = new Object();
22+
2123
ArrayDeque<Object> valueStack;
2224
ArrayDeque<ContainerType> containerStack;
2325
ContainerFactory factory;
@@ -27,10 +29,14 @@ public ContainerContentHandler(ContainerFactory factory) {
2729
}
2830

2931
public Object getContent() {
32+
Object val = null;
3033
if (valueStack.size() > 0) {
31-
return valueStack.pop();
34+
val = valueStack.pop();
35+
if (val == NULL_VALUE) {
36+
return null;
37+
}
3238
}
33-
return null;
39+
return val;
3440
}
3541

3642
public int getContentSize() {
@@ -132,6 +138,9 @@ public boolean endObjectEntry() throws ParseException, IOException {
132138
}
133139

134140
Object value = valueStack.pop();
141+
if (value == NULL_VALUE) {
142+
value = null;
143+
}
135144
String key = (String) valueStack.pop();
136145
@SuppressWarnings("rawtypes")
137146
// XXX raw types unavoidable do to the way ContainerFactory is currently written
@@ -186,6 +195,9 @@ public boolean primitive(Object value) throws ParseException, IOException {
186195
List array = (List) (valueStack.peek());
187196
array.add(value);
188197
} else {
198+
if (value == null) {
199+
value = NULL_VALUE;
200+
}
189201
valueStack.push(value);
190202
}
191203

src/main/java/org/json/simple/parser/DefaultContentHandler.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,25 @@ private enum ContainerType {
1717
ARRAY
1818
}
1919

20+
// special identifier for null value to allow it to be added to the stack
21+
static final Object NULL_VALUE = new Object();
22+
2023
ArrayDeque<Object> valueStack;
2124
ArrayDeque<ContainerType> containerStack;
2225

2326
public DefaultContentHandler() {
2427
}
2528

2629
public Object getContent() {
30+
Object val = null;
2731
if (valueStack.size() > 0) {
28-
return valueStack.pop();
32+
val = valueStack.pop();
33+
if (val == NULL_VALUE) {
34+
return null;
35+
}
36+
2937
}
30-
return null;
38+
return val;
3139
}
3240

3341
public int getContentSize() {
@@ -113,6 +121,9 @@ public boolean endObjectEntry() throws ParseException, IOException {
113121
}
114122

115123
Object value = valueStack.pop();
124+
if (value == NULL_VALUE) {
125+
value = null;
126+
}
116127
String key = (String) valueStack.pop();
117128
@SuppressWarnings("rawtypes")
118129
// XXX raw types unavoidable do to the way ContainerFactory is currently written
@@ -167,6 +178,9 @@ public boolean primitive(Object value) throws ParseException, IOException {
167178
List array = (List) (valueStack.peek());
168179
array.add(value);
169180
} else {
181+
if (value == null) {
182+
value = NULL_VALUE;
183+
}
170184
valueStack.push(value);
171185
}
172186

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.json.simple;
2+
3+
import org.json.simple.JSONArray;
4+
import org.json.simple.JSONObject;
5+
import org.json.simple.parser.JSONParser;
6+
import org.json.simple.parser.ParseException;
7+
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
import junit.framework.TestCase;
11+
12+
public class JSONEmptyAndNullTest extends TestCase {
13+
14+
public void testNullValue() throws ParseException {
15+
String str = "null";
16+
JSONParser parser = new JSONParser();
17+
Object obj = parser.parse(str);
18+
Object sol = null;
19+
Assert.assertEquals("null value", sol, obj);
20+
}
21+
22+
public void testNullValueInObject() throws ParseException {
23+
String str = "{\"exception\":null,\"status\":\"ERROR\"}";
24+
JSONParser parser = new JSONParser();
25+
Object obj = parser.parse(str);
26+
JSONObject sol = new JSONObject();
27+
sol.put("exception", null);
28+
sol.put("status", "ERROR");
29+
Assert.assertEquals("null value in JSON object", sol, obj);
30+
}
31+
32+
public void testNullValueInArray() throws ParseException {
33+
String str = "{\"list\": [null,\"hello\", null, \"world\"]}";
34+
JSONParser parser = new JSONParser();
35+
Object obj = parser.parse(str);
36+
37+
JSONArray array = new JSONArray();
38+
array.add(null);
39+
array.add("hello");
40+
array.add(null);
41+
array.add("world");
42+
JSONObject sol = new JSONObject();
43+
sol.put("list", array);
44+
45+
Assert.assertEquals("null value in JSON array", sol, obj);
46+
}
47+
48+
public void testEmptyArray() throws ParseException {
49+
JSONParser parser = new JSONParser();
50+
String arrayStr = "[]";
51+
JSONArray array = (JSONArray)(parser.parse(arrayStr));
52+
JSONArray sol = new JSONArray();
53+
Assert.assertEquals("Empty array", sol, array );
54+
}
55+
56+
public void testEmptyObject() throws ParseException {
57+
JSONParser parser = new JSONParser();
58+
String objStr = "{}";
59+
JSONObject obj = (JSONObject)(parser.parse(objStr));
60+
JSONObject sol = new JSONObject();
61+
Assert.assertEquals("Empty object", sol, obj );
62+
}
63+
64+
public void testEmptyString() throws ParseException {
65+
JSONParser parser = new JSONParser();
66+
String objStr = "";
67+
Object obj = parser.parse(objStr);
68+
JSONObject sol = null;
69+
Assert.assertEquals("Empty object", sol, obj );
70+
}
71+
72+
}

src/test/java/org/json/simple/Test.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
* @author FangYidong<[email protected]>
2626
*/
2727
@SuppressWarnings("deprecation")
28-
public class Test extends TestCase{
28+
public class Test extends TestCase {
2929

30-
public void testDecode() throws Exception{
30+
public void testDecode() throws Exception {
3131
System.out.println("=======decode=======");
3232

3333
String s="[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]";
@@ -192,7 +192,7 @@ public boolean startObjectEntry(String key) throws ParseException {
192192
pe.printStackTrace();
193193
}
194194

195-
class KeyFinder implements ContentHandler{
195+
class KeyFinder implements ContentHandler {
196196
private Object value;
197197
private boolean found = false;
198198
private boolean end = false;

0 commit comments

Comments
 (0)