Skip to content

Commit

Permalink
fix prefer FiledWriter.features to JSONWriter.context.features when F…
Browse files Browse the repository at this point in the history
…iledWriter.features is not among (0, JSONWriter.Feature.FieldBased.mask, FieldInfo.FIELD_MASK), for issue #2952
  • Loading branch information
yanxutao89 committed Sep 11, 2024
1 parent 30b4e64 commit 3bda413
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ private void gwObjectJSONB(
int REF_PATH = mwc.var("REF_PATH");
Label endDetect_ = new Label(), refSetPath_ = new Label();

mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, endDetect_);
mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, fieldWriter, i, endDetect_);

mw.visitVarInsn(Opcodes.ALOAD, OBJECT);
mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
Expand Down Expand Up @@ -1117,7 +1117,7 @@ private void gwListJSONB(
if (!disableReferenceDetect) {
Label endDetect_ = new Label(), refSetPath_ = new Label();

mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, endDetect_);
mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, fieldWriter, i, endDetect_);

mw.visitVarInsn(Opcodes.ALOAD, OBJECT);
mw.visitVarInsn(Opcodes.ALOAD, LIST);
Expand Down Expand Up @@ -1904,7 +1904,7 @@ private void gwFieldValueObject(
Label ignoreEmptyEnd_ = null;
if ((fieldWriter.features & IgnoreEmpty.mask) == 0) {
ignoreEmptyEnd_ = new Label();
mwc.genIsEnabled(IgnoreEmpty.mask, ignoreEmptyEnd_);
mwc.genIsEnabled(IgnoreEmpty.mask, fieldWriter, i, ignoreEmptyEnd_);
}

mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
Expand Down Expand Up @@ -1937,7 +1937,7 @@ private void gwFieldValueObject(
mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_JSON_WRITER, "isRefDetect", "(Ljava/lang/Object;)Z", false);
} else {
mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, null);
mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, fieldWriter, i, null);
}
mw.visitInsn(Opcodes.DUP);
mw.visitVarInsn(Opcodes.ISTORE, REF_DETECT);
Expand Down Expand Up @@ -1987,7 +1987,7 @@ private void gwFieldValueObject(

if (Object[].class.isAssignableFrom(fieldClass)) {
Label notWriteEmptyArrayEnd_ = new Label();
mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, notWriteEmptyArrayEnd_);
mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, fieldWriter, i, notWriteEmptyArrayEnd_);

mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
mw.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
Expand All @@ -2000,7 +2000,7 @@ private void gwFieldValueObject(
} else if (Collection.class.isAssignableFrom(fieldClass)) {
Label notWriteEmptyArrayEnd_ = new Label();
if ((features & NotWriteEmptyArray.mask) == 0) {
mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, notWriteEmptyArrayEnd_);
mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, fieldWriter, i, notWriteEmptyArrayEnd_);
}

mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
Expand Down Expand Up @@ -2133,7 +2133,7 @@ private void gwFieldValueObject(
nullFeatures |= WriteNullStringAsEmpty.mask;
nullFeatures |= NullAsDefaultValue.mask;
}
mwc.genIsEnabled(nullFeatures, notNull_);
mwc.genIsEnabled(nullFeatures, fieldWriter, i, notNull_);
// mw.visitVarInsn(Opcodes.ILOAD, mwc.var(WRITE_NULLS));
// mw.visitJumpInsn(Opcodes.IFEQ, notNull_);
}
Expand Down Expand Up @@ -2211,7 +2211,7 @@ private void gwFieldValueList(
Label ignoreEmptyEnd_ = null;
if ((fieldWriter.features & IgnoreEmpty.mask) == 0) {
ignoreEmptyEnd_ = new Label();
mwc.genIsEnabled(IgnoreEmpty.mask, ignoreEmptyEnd_);
mwc.genIsEnabled(IgnoreEmpty.mask, fieldWriter, i, ignoreEmptyEnd_);
}

mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
Expand All @@ -2225,7 +2225,7 @@ private void gwFieldValueList(
if (!disableReferenceDetect) {
Label endDetect_ = new Label(), refSetPath_ = new Label();

mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, endDetect_);
mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, fieldWriter, i, endDetect_);

mw.visitVarInsn(Opcodes.ALOAD, OBJECT);
mw.visitVarInsn(Opcodes.ALOAD, LIST);
Expand Down Expand Up @@ -2264,7 +2264,7 @@ private void gwFieldValueList(

{
Label notWriteEmptyArrayEnd_ = new Label();
mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, notWriteEmptyArrayEnd_);
mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, fieldWriter, i, notWriteEmptyArrayEnd_);

mw.visitVarInsn(Opcodes.ALOAD, LIST);
mw.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Collection", "isEmpty", "()Z", true);
Expand Down Expand Up @@ -2312,7 +2312,7 @@ private void gwFieldValueList(
mw.visitJumpInsn(Opcodes.GOTO, notNull_);

mw.visitLabel(null_);
mwc.genIsEnabled(WriteNulls.mask | NullAsDefaultValue.mask | WriteNullListAsEmpty.mask, notNull_);
mwc.genIsEnabled(WriteNulls.mask | NullAsDefaultValue.mask | WriteNullListAsEmpty.mask, fieldWriter, i, notNull_);

// writeFieldName(w);
gwFieldName(mwc, fieldWriter, i);
Expand Down Expand Up @@ -2405,6 +2405,8 @@ private void gwInt32(
if ((fieldWriter.features & (WriteNulls.mask | NullAsDefaultValue.mask | WriteNullNumberAsZero.mask)) == 0) {
mwc.genIsEnabled(
WriteNulls.mask | NullAsDefaultValue.mask | WriteNullNumberAsZero.mask,
fieldWriter,
i,
writeNullValue_,
endIfNull_
);
Expand Down Expand Up @@ -2480,6 +2482,8 @@ private void gwInt64(

mwc.genIsEnabled(
WriteNulls.mask | NullAsDefaultValue.mask | WriteNullNumberAsZero.mask,
fieldWriter,
i,
writeNullValue_,
endIfNull_
);
Expand Down Expand Up @@ -2541,6 +2545,8 @@ private void gwDouble(

mwc.genIsEnabled(
WriteNulls.mask | NullAsDefaultValue.mask | WriteNullNumberAsZero.mask,
fieldWriter,
i,
writeNullValue_,
endIfNull_
);
Expand Down Expand Up @@ -2602,6 +2608,8 @@ private void gwFloat(

mwc.genIsEnabled(
WriteNulls.mask | NullAsDefaultValue.mask | WriteNullNumberAsZero.mask,
fieldWriter,
i,
writeNullValue_,
endIfNull_
);
Expand Down Expand Up @@ -3461,7 +3469,7 @@ private void gwFieldValueString(
Label ignoreEmptyEnd_ = null;
if ((features & IgnoreEmpty.mask) == 0) {
ignoreEmptyEnd_ = new Label();
mwc.genIsEnabled(IgnoreEmpty.mask, ignoreEmptyEnd_);
mwc.genIsEnabled(IgnoreEmpty.mask, fieldWriter, i, ignoreEmptyEnd_);
}

mw.visitVarInsn(Opcodes.ALOAD, FIELD_VALUE);
Expand Down Expand Up @@ -3494,6 +3502,8 @@ private void gwFieldValueString(
if ((features & (JSONWriter.Feature.WriteNulls.mask | defaultValueMask)) == 0) {
mwc.genIsEnabled(
WriteNulls.mask | NullAsDefaultValue.mask | WriteNullStringAsEmpty.mask,
fieldWriter,
i,
writeNull_,
endIfNull_
);
Expand All @@ -3502,7 +3512,7 @@ private void gwFieldValueString(
mw.visitLabel(writeNull_);

if (fieldWriter.defaultValue == null) {
mwc.genIsDisabled(NotWriteDefaultValue.mask, endIfNull_);
mwc.genIsDisabled(NotWriteDefaultValue.mask, fieldWriter, i, endIfNull_);
}

// writeFieldName(w);
Expand Down Expand Up @@ -4024,8 +4034,31 @@ void genIsEnabled(long features, Label elseLabel) {
}
}

void genIsDisabled(long features, Label elseLabel) {
mw.visitVarInsn(Opcodes.LLOAD, var2(CONTEXT_FEATURES));
void genIsEnabled(long features, FieldWriter fieldWriter, int i, Label elseLabel) {
if (fieldWriter.features != 0 && fieldWriter.features != FieldBased.mask && fieldWriter.features != FieldInfo.FIELD_MASK) {
mw.visitVarInsn(Opcodes.ALOAD, THIS);
mw.visitFieldInsn(Opcodes.GETFIELD, classNameType, fieldWriter(i), DESC_FIELD_WRITER);
mw.visitFieldInsn(Opcodes.GETFIELD, TYPE_FIELD_WRITER, "features", "J");
} else {
mw.visitVarInsn(Opcodes.LLOAD, var2(CONTEXT_FEATURES));
}
mw.visitLdcInsn(features);
mw.visitInsn(Opcodes.LAND);
mw.visitInsn(Opcodes.LCONST_0);
mw.visitInsn(Opcodes.LCMP);
if (elseLabel != null) {
mw.visitJumpInsn(Opcodes.IFEQ, elseLabel);
}
}

void genIsDisabled(long features, FieldWriter fieldWriter, int i, Label elseLabel) {
if (fieldWriter.features != 0 && fieldWriter.features != FieldBased.mask && fieldWriter.features != FieldInfo.FIELD_MASK) {
mw.visitVarInsn(Opcodes.ALOAD, THIS);
mw.visitFieldInsn(Opcodes.GETFIELD, classNameType, fieldWriter(i), DESC_FIELD_WRITER);
mw.visitFieldInsn(Opcodes.GETFIELD, TYPE_FIELD_WRITER, "features", "J");
} else {
mw.visitVarInsn(Opcodes.LLOAD, var2(CONTEXT_FEATURES));
}
mw.visitLdcInsn(features);
mw.visitInsn(Opcodes.LAND);
mw.visitInsn(Opcodes.LCONST_0);
Expand All @@ -4043,6 +4076,22 @@ void genIsEnabled(long features, Label trueLabel, Label falseLabel) {
mw.visitJumpInsn(Opcodes.GOTO, trueLabel);
}

void genIsEnabled(long features, FieldWriter fieldWriter, int i, Label trueLabel, Label falseLabel) {
if (fieldWriter.features != 0 && fieldWriter.features != FieldBased.mask && fieldWriter.features != FieldInfo.FIELD_MASK) {
mw.visitVarInsn(Opcodes.ALOAD, THIS);
mw.visitFieldInsn(Opcodes.GETFIELD, classNameType, fieldWriter(i), DESC_FIELD_WRITER);
mw.visitFieldInsn(Opcodes.GETFIELD, TYPE_FIELD_WRITER, "features", "J");
} else {
mw.visitVarInsn(Opcodes.LLOAD, var2(CONTEXT_FEATURES));
}
mw.visitLdcInsn(features);
mw.visitInsn(Opcodes.LAND);
mw.visitInsn(Opcodes.LCONST_0);
mw.visitInsn(Opcodes.LCMP);
mw.visitJumpInsn(Opcodes.IFEQ, falseLabel);
mw.visitJumpInsn(Opcodes.GOTO, trueLabel);
}

void genIsEnabledAndAssign(long features, int var) {
mw.visitVarInsn(Opcodes.LLOAD, var2(CONTEXT_FEATURES));
mw.visitLdcInsn(features);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.alibaba.fastjson2.issues_2900;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import org.junit.jupiter.api.Test;

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

public class Issue2952 {
@Test
public void toJsonList() {
assertEquals("{\"d\":null,\"i\":null,\"l\":null,\"s\":null}", JSON.toJSONString(new C()));
}

@Data
public class C {
@JSONField(serializeFeatures = JSONWriter.Feature.WriteNulls)
private Long l;

@JSONField(serializeFeatures = JSONWriter.Feature.WriteNulls)
private Double d;

@JSONField(serializeFeatures = JSONWriter.Feature.WriteNulls)
private Integer i;

@JSONField(serializeFeatures = JSONWriter.Feature.WriteNulls)
private String s;
}
}

0 comments on commit 3bda413

Please sign in to comment.