Skip to content

Commit

Permalink
bug fixed for smartMatchField, #3246
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Jun 9, 2020
1 parent e7f92f0 commit 18a99f2
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1271,18 +1271,23 @@ public FieldDeserializer smartMatch(String key, int[] setFlags) {
FieldDeserializer fieldDeserializer = getFieldDeserializer(key, setFlags);

if (fieldDeserializer == null) {
long smartKeyHash = TypeUtils.fnv1a_64_lower(key);
if (this.smartMatchHashArray == null) {
long[] hashArray = new long[sortedFieldDeserializers.length];
for (int i = 0; i < sortedFieldDeserializers.length; i++) {
hashArray[i] = TypeUtils.fnv1a_64_lower(sortedFieldDeserializers[i].fieldInfo.name);
hashArray[i] = sortedFieldDeserializers[i].fieldInfo.nameHashCode;
}
Arrays.sort(hashArray);
this.smartMatchHashArray = hashArray;
}

// smartMatchHashArrayMapping
long smartKeyHash = TypeUtils.fnv1a_64_extract(key);
int pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash);
if (pos < 0) {
long smartKeyHash1 = TypeUtils.fnv1a_64_lower(key);
pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash1);
}

boolean is = false;
if (pos < 0 && (is = key.startsWith("is"))) {
smartKeyHash = TypeUtils.fnv1a_64_lower(key.substring(2));
Expand All @@ -1294,8 +1299,7 @@ public FieldDeserializer smartMatch(String key, int[] setFlags) {
short[] mapping = new short[smartMatchHashArray.length];
Arrays.fill(mapping, (short) -1);
for (int i = 0; i < sortedFieldDeserializers.length; i++) {
int p = Arrays.binarySearch(smartMatchHashArray
, TypeUtils.fnv1a_64_lower(sortedFieldDeserializers[i].fieldInfo.name));
int p = Arrays.binarySearch(smartMatchHashArray, sortedFieldDeserializers[i].fieldInfo.nameHashCode);
if (p >= 0) {
mapping[p] = (short) i;
}
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/com/alibaba/fastjson/util/FieldInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public class FieldInfo implements Comparable<FieldInfo> {
public final String format;

public final String[] alternateNames;

public final long nameHashCode;

public FieldInfo(String name, //
Class<?> declaringClass, //
Expand Down Expand Up @@ -94,6 +96,8 @@ public FieldInfo(String name, //
this.unwrapped = false;
this.format = null;
this.alternateNames = new String[0];

nameHashCode = nameHashCode64(name, fieldAnnotation);
}

public FieldInfo(String name, //
Expand Down Expand Up @@ -142,7 +146,7 @@ public FieldInfo(String name, //
this.parserFeatures = parserFeatures;
this.fieldAnnotation = fieldAnnotation;
this.methodAnnotation = methodAnnotation;

if (field != null) {
int modifiers = field.getModifiers();
fieldAccess = ((modifiers & Modifier.PUBLIC) != 0 || method == null);
Expand All @@ -162,6 +166,8 @@ public FieldInfo(String name, //
String format = null;
JSONField annotation = getAnnotation();

nameHashCode = nameHashCode64(name, annotation);

boolean jsonDirect = false;
if (annotation != null) {
format = annotation.format();
Expand Down Expand Up @@ -245,7 +251,15 @@ public FieldInfo(String name, //

isEnum = fieldClass.isEnum();
}


private long nameHashCode64(String name, JSONField annotation)
{
if (annotation != null && annotation.name().length() != 0) {
return TypeUtils.fnv1a_64_extract(name);
}
return TypeUtils.fnv1a_64_lower(name);
}

protected char[] genFieldNameChars() {
int nameLen = this.name.length();
char[] name_chars = new char[nameLen + 3];
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/alibaba/fastjson/util/TypeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2894,6 +2894,16 @@ public static long fnv1a_64_lower(String key){
return hashCode;
}

public static long fnv1a_64_extract(String key){
long hashCode = 0xcbf29ce484222325L;
for(int i = 0; i < key.length(); ++i){
char ch = key.charAt(i);
hashCode ^= ch;
hashCode *= 0x100000001b3L;
}
return hashCode;
}

public static long fnv1a_64(String key){
long hashCode = 0xcbf29ce484222325L;
for(int i = 0; i < key.length(); ++i){
Expand Down
61 changes: 61 additions & 0 deletions src/test/java/com/alibaba/json/bvt/issue_3200/Issue3246.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.alibaba.json.bvt.issue_3200;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import junit.framework.TestCase;
import lombok.Data;

public class Issue3246 extends TestCase {
public void test_for_issue() throws Exception {
String jsonStr = "{\"d_id\":\"bphyean01\",\"isOpenMergeCode\":0,\"offlineOrder\":false,\"offlineOrderType\":-1,\"og\":0,\"pushIdFromRemote\":false,\"qrisAmountPrice\":22000,\"s_req\":0,\"s_t\":1,\"skr_id\":0,\"type\":1,\"c_id\":471,\"o_$\":5500.0,\"am\":4,\"$_tp\":\"bp\",\"o_t\":1,\"a_m\":3}";
Order parseOrder = JSON.parseObject(jsonStr,Order.class);
assertEquals(Integer.valueOf(4), parseOrder.getAmount());
assertEquals("3", parseOrder.getAddMoney());

}

@Data
public static class Order {
@JSONField(name = "d_id", ordinal = 0)
private String deviceId;
@JSONField(name = "c_id", ordinal = 1)
private Integer commodityId;
@JSONField(name = "o_$", ordinal = 2)
private Double orderPrice;
@JSONField(name = "am", ordinal = 3)
private Integer amount;
@JSONField(name = "$_tp", ordinal = 4)
private String payType;
@JSONField(name = "wx_p_id", ordinal = 5)
private Long productId;
@JSONField(name = "ext_p_id", ordinal = 6)
private Long extraProductId;
@JSONField(name = "u_id", ordinal = 7)
private String userId;
@JSONField(name = "p_id", ordinal = 8)
private Long parentId;
@JSONField(name = "o_t", ordinal = 9)
private Integer orderType;
@JSONField(name = "ts", ordinal = 10)
private Integer tradeStatus;
@JSONField(name = "pn", ordinal = 11)
private String phoneNum;
@JSONField(name = "conf_id", ordinal = 12)
private Long configId;
@JSONField(name = "sku_id", ordinal = 13)
private Long skuCommodityId;
@JSONField(name = "c_ids", ordinal = 14)
private String commodityIds;
@JSONField(name = "a_m", ordinal = 15)
private String addMoney;
@JSONField(name = "skr_id", ordinal = 15)
private Long secKillRecordId;
@JSONField(name = "c_n", ordinal = 16)
private String clientOrderNum;
@JSONField(name = "s_t", ordinal = 16)
private Integer sceneType;
@JSONField(name = "t_t", ordinal = 16)
private Integer tradingType;

}
}

0 comments on commit 18a99f2

Please sign in to comment.