From 970d3579bf2df2cd363fd0235c5d070519831f59 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Wed, 7 Dec 2022 17:08:44 +0100 Subject: [PATCH] [jsontlv] TlvToJson returns null for empty array instead of an empty array (#23885) --- src/lib/support/jsontlv/BUILD.gn | 1 - src/lib/support/jsontlv/TlvJson.cpp | 62 ++++++++++++------------- src/lib/support/tests/TestTlvToJson.cpp | 12 +++++ 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/lib/support/jsontlv/BUILD.gn b/src/lib/support/jsontlv/BUILD.gn index 4bcea650508b75..eda4d7fa19bcf2 100644 --- a/src/lib/support/jsontlv/BUILD.gn +++ b/src/lib/support/jsontlv/BUILD.gn @@ -16,7 +16,6 @@ import("//build_overrides/chip.gni") import("//build_overrides/jsoncpp.gni") config("jsontlv_config") { - cflags = [ "-Wno-implicit-fallthrough" ] } static_library("jsontlv") { diff --git a/src/lib/support/jsontlv/TlvJson.cpp b/src/lib/support/jsontlv/TlvJson.cpp index 9b9bc3c25cdb55..35bf8686d43bfc 100644 --- a/src/lib/support/jsontlv/TlvJson.cpp +++ b/src/lib/support/jsontlv/TlvJson.cpp @@ -116,8 +116,6 @@ std::string JsonToString(Json::Value & json) CHIP_ERROR TlvToJson(TLV::TLVReader & reader, KeyContext context, Json::Value & parent) { - bool isStruct = false; - switch (reader.GetType()) { case TLV::kTLVType_UnsignedInteger: { @@ -186,46 +184,46 @@ CHIP_ERROR TlvToJson(TLV::TLVReader & reader, KeyContext context, Json::Value & break; } - case TLV::kTLVType_Structure: - isStruct = true; + case TLV::kTLVType_Structure: { + TLV::TLVType containerType; + ReturnErrorOnFailure(reader.EnterContainer(containerType)); + + CHIP_ERROR err; + Json::Value value; + + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + VerifyOrReturnError(TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); + KeyContext context2(static_cast(TLV::TagNumFromTag(reader.GetTag()))); - // - // Fall-through to the case below since - // arrays and structs are handled similarly with - // just a small difference in terms of handling of field IDs vs. - // list indices of the elements in the respective collections. - // + // + // Recursively convert to JSON the encompassing item within the struct. + // + ReturnErrorOnFailure(TlvToJson(reader, context2, value)); + } + + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(reader.ExitContainer(containerType)); + InsertKeyValue(parent, context, value); + break; + } case TLV::kTLVType_Array: { TLV::TLVType containerType; - ReturnErrorOnFailure(reader.EnterContainer(containerType)); CHIP_ERROR err; - Json::Value value; - size_t listIndex = 0; + Json::Value value = Json::Value(Json::arrayValue); + size_t listIndex = 0; while ((err = reader.Next()) == CHIP_NO_ERROR) { - if (isStruct) - { - VerifyOrReturnError(TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); - KeyContext context2(static_cast(TLV::TagNumFromTag(reader.GetTag()))); - - // - // Recursively convert to JSON the encompassing item within the struct. - // - ReturnErrorOnFailure(TlvToJson(reader, context2, value)); - } - else - { - KeyContext context2(static_cast(listIndex++)); - - // - // Recursively convert to JSON the encompassing item within the array. - // - ReturnErrorOnFailure(TlvToJson(reader, context2, value)); - } + KeyContext context2(static_cast(listIndex++)); + + // + // Recursively convert to JSON the encompassing item within the array. + // + ReturnErrorOnFailure(TlvToJson(reader, context2, value)); } VerifyOrReturnError(err == CHIP_END_OF_TLV, err); diff --git a/src/lib/support/tests/TestTlvToJson.cpp b/src/lib/support/tests/TestTlvToJson.cpp index f2a777a7258716..95a8967820317e 100644 --- a/src/lib/support/tests/TestTlvToJson.cpp +++ b/src/lib/support/tests/TestTlvToJson.cpp @@ -188,6 +188,18 @@ void TestConverter(nlTestSuite * inSuite, void * inContext) " \"value\" : [ 1, 2, 3, 4 ]\n" "}\n"); + int8uList = {}; + EncodeAndValidate(int8uList, + "{\n" + " \"value\" : []\n" + "}\n"); + + DataModel::Nullable> nullValueList; + EncodeAndValidate(nullValueList, + "{\n" + " \"value\" : null\n" + "}\n"); + Clusters::UnitTesting::Structs::SimpleStruct::Type structListData[2] = { structVal, structVal }; DataModel::List structList;