Skip to content

Commit 25b4968

Browse files
Remove restriction on LWT payload being zero (#221)
* Update the changelog * Remove payload non-zero restriction Ref: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718031 * Update changelog * Fix 10.4 violation * FRemove unused files * Update memory table * Add assert to check invalid conditions * Update the assertion to be correct * Fix last CBMC proof by making sure all pointers are allocated properly
1 parent afc726a commit 25b4968

File tree

5 files changed

+126
-16
lines changed

5 files changed

+126
-16
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog for coreMQTT Client Library
22

33
## v2.0.0 (September 2022)
4+
5+
### Changes
6+
- [#221](https://github.com/FreeRTOS/coreMQTT/pull/221) Remove LWT payload non-zero restriction.
47
- [#219](https://github.com/FreeRTOS/coreMQTT/pull/219) Fix MISRA deviations in the source.
58
- [#218](https://github.com/FreeRTOS/coreMQTT/pull/218) Fix bugs in receiveSingleIteration and optimize sendMessageVector.
69
- [#213](https://github.com/FreeRTOS/coreMQTT/pull/213) Fix MISRA deviations in the source.

docs/doxygen/include/size_table.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</tr>
1010
<tr>
1111
<td>core_mqtt.c</td>
12-
<td><center>3.9K</center></td>
12+
<td><center>4.0K</center></td>
1313
<td><center>3.4K</center></td>
1414
</tr>
1515
<tr>
@@ -24,7 +24,7 @@
2424
</tr>
2525
<tr>
2626
<td><b>Total estimates</b></td>
27-
<td><b><center>8.4K</center></b></td>
27+
<td><b><center>8.5K</center></b></td>
2828
<td><b><center>6.9K</center></b></td>
2929
</tr>
3030
</table>

source/core_mqtt.c

+17-12
Original file line numberDiff line numberDiff line change
@@ -1814,20 +1814,30 @@ static size_t addEncodedStringToVector( uint8_t serailizedLength[ 2 ],
18141814
const size_t seralizedLengthFieldSize = 2U;
18151815
TransportOutVector_t * pLocalIterator = iterator;
18161816
/* This function always adds 2 vectors. */
1817-
const size_t vectorsAdded = 2U;
1817+
size_t vectorsAdded = 0U;
1818+
1819+
/* When length is non-zero, the string must be non-NULL. */
1820+
assert( ( length != 0U ) == ( string != NULL ) );
18181821

18191822
serailizedLength[ 0 ] = ( ( uint8_t ) ( ( length ) >> 8 ) );
18201823
serailizedLength[ 1 ] = ( ( uint8_t ) ( ( length ) & 0x00ffU ) );
18211824

18221825
/* Add the serialized length of the string first. */
18231826
pLocalIterator[ 0 ].iov_base = serailizedLength;
18241827
pLocalIterator[ 0 ].iov_len = seralizedLengthFieldSize;
1828+
vectorsAdded++;
1829+
packetLength = seralizedLengthFieldSize;
18251830

1826-
/* Then add the pointer to the string itself. */
1827-
pLocalIterator[ 1 ].iov_base = string;
1828-
pLocalIterator[ 1 ].iov_len = length;
1829-
1830-
packetLength = length + seralizedLengthFieldSize;
1831+
/* Sometimes the string can be NULL that is, of 0 length. In that case,
1832+
* only the length field should be encoded in the vector. */
1833+
if( ( string != NULL ) && ( length != 0U ) )
1834+
{
1835+
/* Then add the pointer to the string itself. */
1836+
pLocalIterator[ 1 ].iov_base = string;
1837+
pLocalIterator[ 1 ].iov_len = length;
1838+
vectorsAdded++;
1839+
packetLength += length;
1840+
}
18311841

18321842
( *updatedLength ) = ( *updatedLength ) + packetLength;
18331843

@@ -2099,11 +2109,6 @@ static MQTTStatus_t sendConnectWithoutCopy( MQTTContext_t * pContext,
20992109
LogError( ( "pWillInfo->pTopicName cannot be NULL if Will is present." ) );
21002110
status = MQTTBadParameter;
21012111
}
2102-
else if( ( pWillInfo != NULL ) && ( pWillInfo->pPayload == NULL ) )
2103-
{
2104-
LogError( ( "pWillInfo->pPayload cannot be NULL if Will is present." ) );
2105-
status = MQTTBadParameter;
2106-
}
21072112
else
21082113
{
21092114
pIndex = MQTT_SerializeConnectFixedHeader( pIndex,
@@ -2149,7 +2154,7 @@ static MQTTStatus_t sendConnectWithoutCopy( MQTTContext_t * pContext,
21492154
ioVectorLength += vectorsAdded;
21502155

21512156

2152-
/* Serialize the payload. */
2157+
/* Serialize the payload. Payload of last will and testament can be NULL. */
21532158
vectorsAdded = addEncodedStringToVector( serializedPayloadLength,
21542159
pWillInfo->pPayload,
21552160
( uint16_t ) pWillInfo->payloadLength,

test/cbmc/proofs/MQTT_Connect/MQTT_Connect_harness.c

+45
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,33 @@ void harness()
5454
totalMessageLength += pConnectInfo->passwordLength;
5555
totalMessageLength += pConnectInfo->userNameLength;
5656
totalMessageLength += pConnectInfo->clientIdentifierLength;
57+
58+
if( pConnectInfo->passwordLength == 0 )
59+
{
60+
pConnectInfo->pPassword = NULL;
61+
}
62+
else
63+
{
64+
__CPROVER_assume( pConnectInfo->pPassword != NULL );
65+
}
66+
67+
if( pConnectInfo->userNameLength == 0 )
68+
{
69+
pConnectInfo->pUserName = NULL;
70+
}
71+
else
72+
{
73+
__CPROVER_assume( pConnectInfo->pUserName != NULL );
74+
}
75+
76+
if( pConnectInfo->clientIdentifierLength == 0 )
77+
{
78+
pConnectInfo->pClientIdentifier = NULL;
79+
}
80+
else
81+
{
82+
__CPROVER_assume( pConnectInfo->pClientIdentifier != NULL );
83+
}
5784
}
5885

5986
pWillInfo = allocateMqttPublishInfo( NULL );
@@ -65,6 +92,24 @@ void harness()
6592
__CPROVER_assume( pWillInfo->topicNameLength < 268435456 );
6693
__CPROVER_assume( pWillInfo->payloadLength < 268435456 );
6794

95+
if( pWillInfo->topicNameLength == 0 )
96+
{
97+
pWillInfo->pTopicName = NULL;
98+
}
99+
else
100+
{
101+
__CPROVER_assume( pWillInfo->pTopicName != NULL );
102+
}
103+
104+
if( pWillInfo->payloadLength == 0 )
105+
{
106+
pWillInfo->pPayload = NULL;
107+
}
108+
else
109+
{
110+
__CPROVER_assume( pWillInfo->pPayload != NULL );
111+
}
112+
68113
totalMessageLength += pWillInfo->topicNameLength;
69114
totalMessageLength += pWillInfo->payloadLength;
70115
}

test/unit-test/core_mqtt_utest.c

+59-2
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ void test_MQTT_Connect_ProperWIllInfo( void )
10591059
/**
10601060
* @brief Test MQTT_Connect, with no payload in will message.
10611061
*/
1062-
void test_MQTT_Connect_ImproperWIllInfo( void )
1062+
void test_MQTT_Connect_ProperWIllInfoWithNoPayload( void )
10631063
{
10641064
MQTTContext_t mqttContext = { 0 };
10651065
MQTTConnectInfo_t connectInfo = { 0 };
@@ -1107,7 +1107,64 @@ void test_MQTT_Connect_ImproperWIllInfo( void )
11071107

11081108
status = MQTT_Connect( &mqttContext, &connectInfo, &willInfo, timeout, &sessionPresent );
11091109

1110-
TEST_ASSERT_EQUAL_INT( MQTTBadParameter, status );
1110+
TEST_ASSERT_EQUAL_INT( MQTTSendFailed, status );
1111+
}
1112+
1113+
/**
1114+
* @brief Test MQTT_Connect, with payload in will message but the length is
1115+
* zero.
1116+
*/
1117+
void test_MQTT_Connect_ProperWIllInfoWithPayloadButZeroLength( void )
1118+
{
1119+
MQTTContext_t mqttContext = { 0 };
1120+
MQTTConnectInfo_t connectInfo = { 0 };
1121+
uint32_t timeout = 2;
1122+
bool sessionPresent;
1123+
MQTTStatus_t status;
1124+
TransportInterface_t transport = { 0 };
1125+
MQTTFixedBuffer_t networkBuffer = { 0 };
1126+
size_t remainingLength;
1127+
size_t packetSize;
1128+
MQTTPublishInfo_t willInfo;
1129+
1130+
setupTransportInterface( &transport );
1131+
transport.writev = transportWritevFail;
1132+
setupNetworkBuffer( &networkBuffer );
1133+
1134+
memset( &mqttContext, 0x0, sizeof( mqttContext ) );
1135+
memset( &willInfo, 0, sizeof( MQTTPublishInfo_t ) );
1136+
1137+
willInfo.pTopicName = "MQTTTopic";
1138+
willInfo.topicNameLength = strlen( willInfo.pTopicName );
1139+
willInfo.pPayload = "Payload";
1140+
willInfo.payloadLength = 0;
1141+
1142+
connectInfo.pUserName = "MQTTUser";
1143+
connectInfo.userNameLength = strlen( connectInfo.pUserName );
1144+
connectInfo.pPassword = "NotSafePassword";
1145+
connectInfo.passwordLength = strlen( connectInfo.pPassword );
1146+
1147+
MQTT_Init( &mqttContext, &transport, getTime, eventCallback, &networkBuffer );
1148+
1149+
/* Transport send failed when sending CONNECT. */
1150+
1151+
/* Choose 10 bytes variable header + 1 byte payload for the remaining
1152+
* length of the CONNECT. The packet size needs to be nonzero for this test
1153+
* as that is the amount of bytes used in the call to send the packet. */
1154+
packetSize = 13;
1155+
remainingLength = 11;
1156+
mqttContext.transportInterface.send = transportSendFailure;
1157+
MQTT_SerializeConnectFixedHeader_Stub( MQTT_SerializeConnectFixedHeader_cb );
1158+
MQTT_GetConnectPacketSize_ExpectAnyArgsAndReturn( MQTTSuccess );
1159+
MQTT_GetConnectPacketSize_IgnoreArg_pPacketSize();
1160+
MQTT_GetConnectPacketSize_IgnoreArg_pRemainingLength();
1161+
MQTT_GetConnectPacketSize_ReturnThruPtr_pPacketSize( &packetSize );
1162+
MQTT_GetConnectPacketSize_ReturnThruPtr_pRemainingLength( &remainingLength );
1163+
MQTT_SerializeConnect_IgnoreAndReturn( MQTTSuccess );
1164+
1165+
status = MQTT_Connect( &mqttContext, &connectInfo, &willInfo, timeout, &sessionPresent );
1166+
1167+
TEST_ASSERT_EQUAL_INT( MQTTSendFailed, status );
11111168
}
11121169

11131170
/**

0 commit comments

Comments
 (0)