[nexus] fix intermittent failure by initializing MeshCoP::Timestamp (#12581)

The MeshCoP::Timestamp class does not have a default constructor that
clears its members. When a Timestamp object is declared on the stack,
its members (seconds, ticks, and authoritative bit) contain garbage.

The SetSeconds() and SetTicks() methods only update their respective
fields and do not touch the authoritative bit. If the authoritative
bit happens to be set from stack garbage, the timestamp may be
incorrectly considered greater than another valid timestamp.

This caused intermittent failures in Nexus test 1.1.9.2.4 and others,
where a MGMT_ACTIVE_SET.req with an old timestamp was incorrectly
accepted by the Leader instead of being rejected.

This commit adds explicit Clear() calls to all MeshCoP::Timestamp
declarations in the affected Nexus tests to ensure they are properly
initialized.
This commit is contained in:
Jonathan Hui
2026-02-28 21:14:36 -06:00
committed by GitHub
parent d0237f5e91
commit c9a153bdd8
9 changed files with 33 additions and 27 deletions
+3 -3
View File
@@ -200,8 +200,8 @@ void Test9_2_10(void)
datasetInfo.Set<MeshCoP::Dataset::kPanId>(kPrimaryPanId);
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kLeaderActiveTimestamp);
timestamp.SetTicks(0);
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
}
leader.Get<MeshCoP::ActiveDatasetManager>().SaveLocal(datasetInfo);
@@ -262,14 +262,14 @@ void Test9_2_10(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep2);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestampStep2);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::PendingTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::Append<MeshCoP::DelayTimerTlv>(*message, kDelayTimerStep2));
+2 -2
View File
@@ -144,14 +144,14 @@ void SendPendingSet(Node &aCommissioner,
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, aSessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(aActiveTimestamp);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(aPendingTimestamp);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::PendingTimestampTlv>(*message, timestamp));
}
{
+5 -5
View File
@@ -262,14 +262,14 @@ void Test9_2_16(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep3);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestampStep3);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::PendingTimestampTlv>(*message, timestamp));
}
{
@@ -415,14 +415,14 @@ void Test9_2_16(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep11);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestampStep11);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::PendingTimestampTlv>(*message, timestamp));
}
{
@@ -478,8 +478,8 @@ void Test9_2_16(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep13);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::Append<MeshCoP::NetworkNameTlv>(*message, kNetworkNameStep13));
+2 -2
View File
@@ -180,8 +180,8 @@ void Test9_2_17(void)
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kLeader1Timestamp);
timestamp.SetTicks(0);
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
}
datasetInfo.Set<MeshCoP::Dataset::kChannelMask>((1 << kPrimaryChannel) | (1 << kSecondaryChannel));
@@ -204,8 +204,8 @@ void Test9_2_17(void)
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kLeader2Timestamp);
timestamp.SetTicks(0);
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
}
+4
View File
@@ -170,6 +170,7 @@ void Test9_2_18(void)
SuccessOrQuit(datasetInfo.GenerateRandom(leader.GetInstance()));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(1);
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
}
@@ -238,6 +239,7 @@ void Test9_2_18(void)
activeDatasetInfo.Clear();
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestamp20000);
activeDatasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
}
@@ -291,6 +293,7 @@ void Test9_2_18(void)
pendingDatasetInfo1.Clear();
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestamp20);
pendingDatasetInfo1.Set<MeshCoP::Dataset::kPendingTimestamp>(timestamp);
timestamp.SetSeconds(kActiveTimestamp20);
@@ -349,6 +352,7 @@ void Test9_2_18(void)
pendingDatasetInfo2.Clear();
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestamp20);
pendingDatasetInfo2.Set<MeshCoP::Dataset::kPendingTimestamp>(timestamp);
timestamp.SetSeconds(kActiveTimestamp20);
+9 -9
View File
@@ -344,8 +344,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep2);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
@@ -446,8 +446,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep6);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::Append<MeshCoP::ChannelTlv>(*message, MeshCoP::ChannelTlvValue(0, kSecondaryChannel)));
@@ -510,8 +510,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep8);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(
@@ -579,8 +579,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep10);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
@@ -645,8 +645,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep12);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
@@ -707,8 +707,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, kInvalidSessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep14);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
@@ -768,8 +768,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep2);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
@@ -830,8 +830,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep18);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
@@ -894,8 +894,8 @@ void RunTest9_2_4(Topology aTopology, const char *aJsonFile)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep20);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::AppendTlv(*message, MeshCoP::Tlv::kChannelMask, kChannelMask, sizeof(kChannelMask)));
+1 -1
View File
@@ -165,8 +165,8 @@ void Test9_2_5(void)
SuccessOrQuit(router1.Get<MeshCoP::ActiveDatasetManager>().Read(datasetInfo));
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampStep2);
timestamp.SetTicks(0);
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
datasetInfo.Set<MeshCoP::Dataset::kChannelMask>(kChannelMaskStep2);
datasetInfo.Set<MeshCoP::Dataset::kExtendedPanId>(
+3
View File
@@ -300,6 +300,7 @@ void Test9_2_6(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampNew);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
@@ -501,11 +502,13 @@ void Test9_2_6(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampFinal);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestamp);
SuccessOrQuit(Tlv::Append<MeshCoP::PendingTimestampTlv>(*message, timestamp));
}
+4 -5
View File
@@ -280,9 +280,9 @@ void Test9_2_7(void)
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
// Deviation from spec: Step 5 uses 15 instead of 20 to ensure it is older than the timestamp in Step 11.
timestamp.SetSeconds(kActiveTimestampStep5);
timestamp.SetTicks(0);
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
}
@@ -397,6 +397,7 @@ void Test9_2_7(void)
Coap::Message *message;
MeshCoP::Dataset dataset;
MeshCoP::Timestamp timestamp;
timestamp.Clear();
message = agent.NewPriorityConfirmablePostMessage(ot::kUriPendingSet);
VerifyOrQuit(message != nullptr);
@@ -404,11 +405,9 @@ void Test9_2_7(void)
SuccessOrQuit(router.Get<MeshCoP::ActiveDatasetManager>().Read(dataset));
timestamp.SetSeconds(kActiveTimestampRouter);
timestamp.SetTicks(0);
SuccessOrQuit(dataset.Write<MeshCoP::ActiveTimestampTlv>(timestamp));
timestamp.SetSeconds(kPendingTimestampRouter);
timestamp.SetTicks(0);
SuccessOrQuit(dataset.Write<MeshCoP::PendingTimestampTlv>(timestamp));
SuccessOrQuit(dataset.Write<MeshCoP::DelayTimerTlv>(kDelayTimerStep11 * 1000));
@@ -532,14 +531,14 @@ void Test9_2_7(void)
SuccessOrQuit(Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, sessionId));
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kPendingTimestampCommissioner);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::PendingTimestampTlv>(*message, timestamp));
}
{
MeshCoP::Timestamp timestamp;
timestamp.Clear();
timestamp.SetSeconds(kActiveTimestampCommissioner);
timestamp.SetTicks(0);
SuccessOrQuit(Tlv::Append<MeshCoP::ActiveTimestampTlv>(*message, timestamp));
}
SuccessOrQuit(Tlv::Append<MeshCoP::DelayTimerTlv>(*message, kDelayTimerStep17 * 1000));