Skip to content

Commit 77a30fe

Browse files
authored
Fix JSON parsing stack overflow vulnerabilities (#1939)
1 parent b24ea69 commit 77a30fe

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

chunjun-core/src/main/java/com/dtstack/chunjun/util/GsonUtil.java

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -77,51 +77,62 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
7777
return new TypeAdapter() {
7878
@Override
7979
public Object read(JsonReader in) throws IOException {
80-
JsonToken token = in.peek();
81-
// 判断字符串的实际类型
82-
switch (token) {
83-
case BEGIN_ARRAY:
84-
List<Object> list = new ArrayList<>();
85-
in.beginArray();
86-
while (in.hasNext()) {
87-
list.add(read(in));
80+
// Either List or Map
81+
Object current;
82+
JsonToken peeked = in.peek();
83+
84+
current = tryBeginNesting(in, peeked);
85+
if (current == null) {
86+
return readTerminal(in, peeked);
87+
}
88+
89+
Deque<Object> stack = new ArrayDeque<>();
90+
91+
while (true) {
92+
while (in.hasNext()) {
93+
String name = null;
94+
// Name is only used for JSON object members
95+
if (current instanceof Map) {
96+
name = in.nextName();
8897
}
89-
in.endArray();
90-
return list;
9198

92-
case BEGIN_OBJECT:
93-
Map<String, Object> map =
94-
new LinkedTreeMap<>();
95-
in.beginObject();
96-
while (in.hasNext()) {
97-
map.put(in.nextName(), read(in));
99+
peeked = in.peek();
100+
Object value = tryBeginNesting(in, peeked);
101+
boolean isNesting = value != null;
102+
103+
if (value == null) {
104+
value = readTerminal(in, peeked);
98105
}
99-
in.endObject();
100-
return map;
101-
case STRING:
102-
return in.nextString();
103-
case NUMBER:
104-
String s = in.nextString();
105-
if (s.contains(".")) {
106-
return Double.valueOf(s);
106+
107+
if (current instanceof List) {
108+
@SuppressWarnings("unchecked")
109+
List<Object> list = (List<Object>) current;
110+
list.add(value);
107111
} else {
108-
try {
109-
return Integer.valueOf(s);
110-
} catch (Exception e) {
111-
try {
112-
return Long.valueOf(s);
113-
} catch (Exception e1) {
114-
return new BigInteger(s);
115-
}
116-
}
112+
@SuppressWarnings("unchecked")
113+
Map<String, Object> map = (Map<String, Object>) current;
114+
map.put(name, value);
117115
}
118-
case BOOLEAN:
119-
return in.nextBoolean();
120-
case NULL:
121-
in.nextNull();
122-
return null;
123-
default:
124-
throw new IllegalStateException();
116+
117+
if (isNesting) {
118+
stack.addLast(current);
119+
current = value;
120+
}
121+
}
122+
123+
// End current element
124+
if (current instanceof List) {
125+
in.endArray();
126+
} else {
127+
in.endObject();
128+
}
129+
130+
if (stack.isEmpty()) {
131+
return current;
132+
} else {
133+
// Continue with enclosing element
134+
current = stack.removeLast();
135+
}
125136
}
126137
}
127138

0 commit comments

Comments
 (0)