Skip to content

Commit ea3bc5d

Browse files
authored
Fixed enum mismatch (#1581)
* fixed: enum mismatch for issue(#1578) Signed-off-by: Kraity <[email protected]>
1 parent 2534e1e commit ea3bc5d

File tree

3 files changed

+125
-25
lines changed

3 files changed

+125
-25
lines changed

core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplEnum.java

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName
214214
}
215215
}
216216

217-
Enum fieldValue = null;
217+
Enum<?> fieldValue = null;
218218
if (jsonReader.isInt()) {
219219
int intValue = jsonReader.readInt32Value();
220220
if (valueField == null) {
@@ -233,27 +233,35 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName
233233
throw new JSONException(jsonReader.info("parse enum error, class " + enumClass.getName() + ", " + valueField.getName() + " " + intValue));
234234
}
235235
}
236-
} else if (jsonReader.nextIfNullOrEmptyString()) {
237-
fieldValue = null;
238-
} else if (valueFieldType != null && valueFieldType == String.class && jsonReader.isString()) {
239-
String str = jsonReader.readString();
240-
for (int i = 0; i < stringValues.length; i++) {
241-
if (str.equals(stringValues[i])) {
242-
fieldValue = enums[i];
243-
break;
236+
} else if (!jsonReader.nextIfNullOrEmptyString()) {
237+
if (stringValues != null && jsonReader.isString()) {
238+
String str = jsonReader.readString();
239+
for (int i = 0; i < stringValues.length; i++) {
240+
if (str.equals(stringValues[i])) {
241+
fieldValue = enums[i];
242+
break;
243+
}
244+
}
245+
} else if (intValues != null && jsonReader.isString()) {
246+
int intValue = jsonReader.readInt32Value();
247+
for (int i = 0; i < intValues.length; i++) {
248+
if (intValues[i] == intValue) {
249+
fieldValue = enums[i];
250+
break;
251+
}
252+
}
253+
} else {
254+
long hashCode = jsonReader.readValueHashCode();
255+
if (hashCode == Fnv.MAGIC_HASH_CODE) {
256+
return null;
244257
}
245-
}
246-
} else {
247-
long hashCode = jsonReader.readValueHashCode();
248-
fieldValue = getEnumByHashCode(hashCode);
249-
if (hashCode == Fnv.MAGIC_HASH_CODE) {
250-
return null;
251-
}
252258

253-
if (fieldValue == null) {
254-
fieldValue = getEnumByHashCode(
255-
jsonReader.getNameHashCodeLCase()
256-
);
259+
fieldValue = getEnumByHashCode(hashCode);
260+
if (fieldValue == null) {
261+
fieldValue = getEnumByHashCode(
262+
jsonReader.getNameHashCodeLCase()
263+
);
264+
}
257265
}
258266

259267
if (fieldValue == null && jsonReader.isEnabled(JSONReader.Feature.ErrorOnEnumNotMatch)) {

core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplEnum2X4.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public final class ObjectReaderImplEnum2X4
2323
private long enumNameHashCode10;
2424
private long enumNameHashCode11;
2525

26+
static final long HASHCODE64_0 = Fnv.hashCode64("0");
27+
static final long HASHCODE64_1 = Fnv.hashCode64("1");
28+
2629
public ObjectReaderImplEnum2X4(Class enumClass, Enum[] enums, Enum[] ordinalEnums, long[] enumNameHashCodes) {
2730
this.enumClass = enumClass;
2831
this.typeNameHash = Fnv.hashCode64(TypeUtils.getTypeName(enumClass));
@@ -113,9 +116,9 @@ public Object readJSONBObject(JSONReader jsonReader, Type fieldType, Object fiel
113116
}
114117
} else {
115118
long hashCode = jsonReader.readValueHashCode();
116-
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode) {
119+
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode || HASHCODE64_0 == hashCode) {
117120
fieldValue = enum0;
118-
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode) {
121+
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode || HASHCODE64_1 == hashCode) {
119122
fieldValue = enum1;
120123
} else {
121124
long hashCodeLCase = jsonReader.getNameHashCodeLCase();
@@ -144,7 +147,7 @@ public Object readJSONBObject(JSONReader jsonReader, Type fieldType, Object fiel
144147
@Override
145148
public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
146149
int start = jsonReader.getOffset();
147-
Enum fieldValue;
150+
Enum<?> fieldValue;
148151
if (jsonReader.isInt()) {
149152
int ordinal = jsonReader.readInt32Value();
150153
if (ordinal == 0) {
@@ -158,9 +161,9 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName
158161
fieldValue = null;
159162
} else {
160163
long hashCode = jsonReader.readValueHashCode();
161-
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode) {
164+
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode || HASHCODE64_0 == hashCode) {
162165
fieldValue = enum0;
163-
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode) {
166+
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode || HASHCODE64_1 == hashCode) {
164167
fieldValue = enum1;
165168
} else {
166169
long hashCodeLCase = jsonReader.getNameHashCodeLCase();
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.alibaba.fastjson2.issues_1500;
2+
3+
import com.alibaba.fastjson2.JSON;
4+
import com.alibaba.fastjson2.annotation.JSONField;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Getter;
7+
import lombok.Setter;
8+
import lombok.ToString;
9+
import org.junit.jupiter.api.Test;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
/**
14+
* @author kraity
15+
*/
16+
public class Issue1578 {
17+
@Getter
18+
@AllArgsConstructor
19+
public enum GenderEnum {
20+
UNKNOWN(0, "未知"),
21+
MALE(1, "男"),
22+
FEMALE(2, "女");
23+
24+
@JSONField(value = true)
25+
private final Integer code;
26+
private final String name;
27+
}
28+
29+
@Getter
30+
@Setter
31+
@ToString
32+
public static class User {
33+
private String name;
34+
private GenderEnum gender;
35+
}
36+
37+
@Test
38+
public void test() {
39+
User user0 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":0}", User.class);
40+
assertNotNull(user0);
41+
assertEquals("张三丰", user0.getName());
42+
assertSame(GenderEnum.UNKNOWN, user0.getGender());
43+
44+
User user1 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":1}", User.class);
45+
assertNotNull(user1);
46+
assertEquals("张三丰", user1.getName());
47+
assertSame(GenderEnum.MALE, user1.getGender());
48+
49+
User user2 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":\"2\"}", User.class);
50+
assertNotNull(user2);
51+
assertEquals("张三丰", user2.getName());
52+
assertSame(GenderEnum.FEMALE, user2.getGender());
53+
54+
User user3 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":\"0\"}", User.class);
55+
assertNotNull(user3);
56+
assertEquals("张三丰", user3.getName());
57+
assertSame(GenderEnum.UNKNOWN, user3.getGender());
58+
}
59+
60+
@Getter
61+
@AllArgsConstructor
62+
public enum GenderEnum2 {
63+
MALE(-6, "男"),
64+
FEMALE(-7, "女");
65+
private final Integer code;
66+
private final String name;
67+
}
68+
69+
@Getter
70+
@Setter
71+
@ToString
72+
public static class User2 {
73+
private String name;
74+
private GenderEnum2 gender;
75+
}
76+
77+
@Test
78+
public void test_2x4() {
79+
User2 user2 = JSON.parseObject("{\"gender\":\"0\",\"name\":\"张三丰\"}", User2.class);
80+
assertNotNull(user2);
81+
assertEquals("张三丰", user2.getName());
82+
assertSame(GenderEnum2.MALE, user2.getGender());
83+
84+
User2 user3 = JSON.parseObject("{\"gender\":\"1\",\"name\":\"张三丰\"}", User2.class);
85+
assertNotNull(user3);
86+
assertEquals("张三丰", user3.getName());
87+
assertSame(GenderEnum2.FEMALE, user3.getGender());
88+
}
89+
}

0 commit comments

Comments
 (0)