Skip to content

Commit

Permalink
Allow list fields to be null when written (#13089)
Browse files Browse the repository at this point in the history
When access control cluster is decoding TLV to write entries, if
subjects or targets are explicitly null, treat them as empty lists.
  • Loading branch information
mlepage-google authored and pull[bot] committed Jun 23, 2023
1 parent 472d8de commit 1581595
Showing 1 changed file with 51 additions and 45 deletions.
96 changes: 51 additions & 45 deletions src/app/clusters/access-control-server/access-control-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,66 +243,72 @@ struct AccessControlEntryCodec
break;
}
case to_underlying(Fields::kSubjects): {
TLV::TLVType subjectsContainer;
VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(aReader.EnterContainer(subjectsContainer));
while ((err = aReader.Next()) == CHIP_NO_ERROR)
if (aReader.GetType() != TLV::kTLVType_Null)
{
NodeId subject = kUndefinedNodeId;
ReturnErrorOnFailure(DataModel::Decode(aReader, subject));
ReturnErrorOnFailure(entry.AddSubject(nullptr, subject));
TLV::TLVType subjectsContainer;
VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(aReader.EnterContainer(subjectsContainer));
while ((err = aReader.Next()) == CHIP_NO_ERROR)
{
NodeId subject = kUndefinedNodeId;
ReturnErrorOnFailure(DataModel::Decode(aReader, subject));
ReturnErrorOnFailure(entry.AddSubject(nullptr, subject));
}
VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
ReturnErrorOnFailure(aReader.ExitContainer(subjectsContainer));
}
VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
ReturnErrorOnFailure(aReader.ExitContainer(subjectsContainer));
break;
}
case to_underlying(Fields::kTargets): {
TLV::TLVType targetsContainer;
VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(aReader.EnterContainer(targetsContainer));
while ((err = aReader.Next()) == CHIP_NO_ERROR)
if (aReader.GetType() != TLV::kTLVType_Null)
{
AccessControl::Entry::Target target;
TLV::TLVType targetContainer;
VerifyOrReturnError(TLV::kTLVType_Structure == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(aReader.EnterContainer(targetContainer));
using TargetFields = AccessControlCluster::Structs::Target::Fields;
TLV::TLVType targetsContainer;
VerifyOrReturnError(TLV::kTLVType_Array == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(aReader.EnterContainer(targetsContainer));
while ((err = aReader.Next()) == CHIP_NO_ERROR)
{
VerifyOrReturnError(TLV::IsContextTag(aReader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
switch (TLV::TagNumFromTag(aReader.GetTag()))
AccessControl::Entry::Target target;
TLV::TLVType targetContainer;
VerifyOrReturnError(TLV::kTLVType_Structure == aReader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(aReader.EnterContainer(targetContainer));
using TargetFields = AccessControlCluster::Structs::Target::Fields;
while ((err = aReader.Next()) == CHIP_NO_ERROR)
{
case to_underlying(TargetFields::kCluster):
if (aReader.GetType() != TLV::kTLVType_Null)
{
ReturnErrorOnFailure(DataModel::Decode(aReader, target.cluster));
target.flags |= target.kCluster;
}
break;
case to_underlying(TargetFields::kEndpoint):
if (aReader.GetType() != TLV::kTLVType_Null)
{
ReturnErrorOnFailure(DataModel::Decode(aReader, target.endpoint));
target.flags |= target.kEndpoint;
}
break;
case to_underlying(TargetFields::kDeviceType):
if (aReader.GetType() != TLV::kTLVType_Null)
VerifyOrReturnError(TLV::IsContextTag(aReader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
switch (TLV::TagNumFromTag(aReader.GetTag()))
{
ReturnErrorOnFailure(DataModel::Decode(aReader, target.deviceType));
target.flags |= target.kDeviceType;
case to_underlying(TargetFields::kCluster):
if (aReader.GetType() != TLV::kTLVType_Null)
{
ReturnErrorOnFailure(DataModel::Decode(aReader, target.cluster));
target.flags |= target.kCluster;
}
break;
case to_underlying(TargetFields::kEndpoint):
if (aReader.GetType() != TLV::kTLVType_Null)
{
ReturnErrorOnFailure(DataModel::Decode(aReader, target.endpoint));
target.flags |= target.kEndpoint;
}
break;
case to_underlying(TargetFields::kDeviceType):
if (aReader.GetType() != TLV::kTLVType_Null)
{
ReturnErrorOnFailure(DataModel::Decode(aReader, target.deviceType));
target.flags |= target.kDeviceType;
}
break;
default:
break;
}
break;
default:
break;
}
VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
ReturnErrorOnFailure(aReader.ExitContainer(targetContainer));
ReturnErrorOnFailure(entry.AddTarget(nullptr, target));
}
VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
ReturnErrorOnFailure(aReader.ExitContainer(targetContainer));
ReturnErrorOnFailure(entry.AddTarget(nullptr, target));
ReturnErrorOnFailure(aReader.ExitContainer(targetsContainer));
}
VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
ReturnErrorOnFailure(aReader.ExitContainer(targetsContainer));
break;
}
default:
Expand Down

0 comments on commit 1581595

Please sign in to comment.