Skip to content

Commit

Permalink
Fixed enum mismatch (#1581)
Browse files Browse the repository at this point in the history
* fixed: enum mismatch for issue(#1578)

Signed-off-by: Kraity <kraty@krait.cn>
  • Loading branch information
kraity authored Jun 17, 2023
1 parent 2534e1e commit ea3bc5d
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName
}
}

Enum fieldValue = null;
Enum<?> fieldValue = null;
if (jsonReader.isInt()) {
int intValue = jsonReader.readInt32Value();
if (valueField == null) {
Expand All @@ -233,27 +233,35 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName
throw new JSONException(jsonReader.info("parse enum error, class " + enumClass.getName() + ", " + valueField.getName() + " " + intValue));
}
}
} else if (jsonReader.nextIfNullOrEmptyString()) {
fieldValue = null;
} else if (valueFieldType != null && valueFieldType == String.class && jsonReader.isString()) {
String str = jsonReader.readString();
for (int i = 0; i < stringValues.length; i++) {
if (str.equals(stringValues[i])) {
fieldValue = enums[i];
break;
} else if (!jsonReader.nextIfNullOrEmptyString()) {
if (stringValues != null && jsonReader.isString()) {
String str = jsonReader.readString();
for (int i = 0; i < stringValues.length; i++) {
if (str.equals(stringValues[i])) {
fieldValue = enums[i];
break;
}
}
} else if (intValues != null && jsonReader.isString()) {
int intValue = jsonReader.readInt32Value();
for (int i = 0; i < intValues.length; i++) {
if (intValues[i] == intValue) {
fieldValue = enums[i];
break;
}
}
} else {
long hashCode = jsonReader.readValueHashCode();
if (hashCode == Fnv.MAGIC_HASH_CODE) {
return null;
}
}
} else {
long hashCode = jsonReader.readValueHashCode();
fieldValue = getEnumByHashCode(hashCode);
if (hashCode == Fnv.MAGIC_HASH_CODE) {
return null;
}

if (fieldValue == null) {
fieldValue = getEnumByHashCode(
jsonReader.getNameHashCodeLCase()
);
fieldValue = getEnumByHashCode(hashCode);
if (fieldValue == null) {
fieldValue = getEnumByHashCode(
jsonReader.getNameHashCodeLCase()
);
}
}

if (fieldValue == null && jsonReader.isEnabled(JSONReader.Feature.ErrorOnEnumNotMatch)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public final class ObjectReaderImplEnum2X4
private long enumNameHashCode10;
private long enumNameHashCode11;

static final long HASHCODE64_0 = Fnv.hashCode64("0");
static final long HASHCODE64_1 = Fnv.hashCode64("1");

public ObjectReaderImplEnum2X4(Class enumClass, Enum[] enums, Enum[] ordinalEnums, long[] enumNameHashCodes) {
this.enumClass = enumClass;
this.typeNameHash = Fnv.hashCode64(TypeUtils.getTypeName(enumClass));
Expand Down Expand Up @@ -113,9 +116,9 @@ public Object readJSONBObject(JSONReader jsonReader, Type fieldType, Object fiel
}
} else {
long hashCode = jsonReader.readValueHashCode();
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode) {
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode || HASHCODE64_0 == hashCode) {
fieldValue = enum0;
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode) {
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode || HASHCODE64_1 == hashCode) {
fieldValue = enum1;
} else {
long hashCodeLCase = jsonReader.getNameHashCodeLCase();
Expand Down Expand Up @@ -144,7 +147,7 @@ public Object readJSONBObject(JSONReader jsonReader, Type fieldType, Object fiel
@Override
public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
int start = jsonReader.getOffset();
Enum fieldValue;
Enum<?> fieldValue;
if (jsonReader.isInt()) {
int ordinal = jsonReader.readInt32Value();
if (ordinal == 0) {
Expand All @@ -158,9 +161,9 @@ public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName
fieldValue = null;
} else {
long hashCode = jsonReader.readValueHashCode();
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode) {
if (enumNameHashCode00 == hashCode || enumNameHashCode01 == hashCode || HASHCODE64_0 == hashCode) {
fieldValue = enum0;
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode) {
} else if (enumNameHashCode10 == hashCode || enumNameHashCode11 == hashCode || HASHCODE64_1 == hashCode) {
fieldValue = enum1;
} else {
long hashCodeLCase = jsonReader.getNameHashCodeLCase();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.alibaba.fastjson2.issues_1500;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
* @author kraity
*/
public class Issue1578 {
@Getter
@AllArgsConstructor
public enum GenderEnum {
UNKNOWN(0, "未知"),
MALE(1, "男"),
FEMALE(2, "女");

@JSONField(value = true)
private final Integer code;
private final String name;
}

@Getter
@Setter
@ToString
public static class User {
private String name;
private GenderEnum gender;
}

@Test
public void test() {
User user0 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":0}", User.class);
assertNotNull(user0);
assertEquals("张三丰", user0.getName());
assertSame(GenderEnum.UNKNOWN, user0.getGender());

User user1 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":1}", User.class);
assertNotNull(user1);
assertEquals("张三丰", user1.getName());
assertSame(GenderEnum.MALE, user1.getGender());

User user2 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":\"2\"}", User.class);
assertNotNull(user2);
assertEquals("张三丰", user2.getName());
assertSame(GenderEnum.FEMALE, user2.getGender());

User user3 = JSON.parseObject("{\"name\":\"张三丰\",\"gender\":\"0\"}", User.class);
assertNotNull(user3);
assertEquals("张三丰", user3.getName());
assertSame(GenderEnum.UNKNOWN, user3.getGender());
}

@Getter
@AllArgsConstructor
public enum GenderEnum2 {
MALE(-6, "男"),
FEMALE(-7, "女");
private final Integer code;
private final String name;
}

@Getter
@Setter
@ToString
public static class User2 {
private String name;
private GenderEnum2 gender;
}

@Test
public void test_2x4() {
User2 user2 = JSON.parseObject("{\"gender\":\"0\",\"name\":\"张三丰\"}", User2.class);
assertNotNull(user2);
assertEquals("张三丰", user2.getName());
assertSame(GenderEnum2.MALE, user2.getGender());

User2 user3 = JSON.parseObject("{\"gender\":\"1\",\"name\":\"张三丰\"}", User2.class);
assertNotNull(user3);
assertEquals("张三丰", user3.getName());
assertSame(GenderEnum2.FEMALE, user3.getGender());
}
}

0 comments on commit ea3bc5d

Please sign in to comment.