Skip to content

Commit 08510aa

Browse files
authored
fix: support zero-length clientId (#331)
Add support for a zero-length clientId field to match the MQTT v3.1.1 spec. Both empty string and NULL client IDs are handled the same when given a length of 0.
1 parent ad72f6a commit 08510aa

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

source/core_mqtt_serializer.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,9 +1706,14 @@ MQTTStatus_t MQTT_GetConnectPacketSize( const MQTTConnectInfo_t * pConnectInfo,
17061706
( void * ) pPacketSize ) );
17071707
status = MQTTBadParameter;
17081708
}
1709-
else if( ( pConnectInfo->clientIdentifierLength == 0U ) || ( pConnectInfo->pClientIdentifier == NULL ) )
1709+
else if( ( pConnectInfo->clientIdentifierLength == 0U ) ^ ( ( pConnectInfo->pClientIdentifier == NULL ) || ( *( pConnectInfo->pClientIdentifier ) == '\0' ) ) )
17101710
{
1711-
LogError( ( "Mqtt_GetConnectPacketSize() client identifier must be set." ) );
1711+
LogError( ( "Client ID length and value mismatch." ) );
1712+
status = MQTTBadParameter;
1713+
}
1714+
else if( ( pConnectInfo->clientIdentifierLength == 0U ) && ( pConnectInfo->cleanSession == false ) )
1715+
{
1716+
LogError( ( "Zero-length client identifier requires cleanSession=true per MQTT 3.1.1." ) );
17121717
status = MQTTBadParameter;
17131718
}
17141719
else if( ( pWillInfo != NULL ) && ( pWillInfo->payloadLength > ( size_t ) UINT16_MAX ) )

test/cbmc/proofs/MQTT_SerializeConnect/MQTT_SerializeConnect_harness.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ void harness()
3939
MQTTStatus_t status = MQTTSuccess;
4040

4141
pConnectInfo = allocateMqttConnectInfo( NULL );
42-
__CPROVER_assume( isValidMqttConnectInfo( pConnectInfo ) );
42+
43+
/* Avoid a malloc(0U) which causes dereference errors */
44+
if( ( pConnectInfo != NULL ) && ( pConnectInfo->clientIdentifierLength == 0U ) )
45+
{
46+
pConnectInfo->pClientIdentifier = NULL;
47+
}
4348

4449
pWillInfo = allocateMqttPublishInfo( NULL );
4550
__CPROVER_assume( isValidMqttPublishInfo( pWillInfo ) );

test/unit-test/core_mqtt_serializer_utest.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,11 +463,59 @@ void test_MQTT_GetConnectPacketSize( void )
463463
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
464464
TEST_ASSERT_EQUAL_INT( MQTTBadParameter, status );
465465

466+
/* Verify NULL client identifier with provided non-zero length fails. */
466467
connectInfo.pClientIdentifier = NULL;
467468
connectInfo.clientIdentifierLength = CLIENT_IDENTIFIER_LENGTH;
469+
connectInfo.cleanSession = true;
468470
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
469471
TEST_ASSERT_EQUAL_INT( MQTTBadParameter, status );
470472

473+
/* Verify empty string client ID with provided non-zero length fails. */
474+
connectInfo.pClientIdentifier = "";
475+
connectInfo.clientIdentifierLength = 99U;
476+
connectInfo.cleanSession = true;
477+
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
478+
TEST_ASSERT_EQUAL_INT( MQTTBadParameter, status );
479+
480+
/* Verify zero-length client identifier must have clean session. */
481+
connectInfo.pClientIdentifier = NULL;
482+
connectInfo.clientIdentifierLength = 0U;
483+
connectInfo.cleanSession = false;
484+
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
485+
TEST_ASSERT_EQUAL_INT( MQTTBadParameter, status );
486+
487+
/* Verify zero-length client identifier must have clean session. */
488+
connectInfo.pClientIdentifier = "";
489+
connectInfo.clientIdentifierLength = 0U;
490+
connectInfo.cleanSession = false;
491+
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
492+
TEST_ASSERT_EQUAL_INT( MQTTBadParameter, status );
493+
494+
/* NULL client ID and client ID length of 0 is treated as zero-length identifier */
495+
connectInfo.pClientIdentifier = NULL;
496+
connectInfo.clientIdentifierLength = 0U;
497+
connectInfo.cleanSession = true;
498+
connectInfo.pUserName = NULL;
499+
connectInfo.pPassword = NULL;
500+
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
501+
TEST_ASSERT_EQUAL_INT( MQTTSuccess, status );
502+
/* Make sure remaining size returned is 12. */
503+
TEST_ASSERT_EQUAL_INT( 12, remainingLength );
504+
/* Make sure packet size is 14. */
505+
TEST_ASSERT_EQUAL_INT( 14, packetSize );
506+
507+
/* Empty string client ID and client ID length of 0 is treated as zero-length identifier */
508+
connectInfo.pClientIdentifier = "";
509+
connectInfo.clientIdentifierLength = 0U;
510+
connectInfo.pUserName = NULL;
511+
connectInfo.pPassword = NULL;
512+
status = MQTT_GetConnectPacketSize( &connectInfo, NULL, &remainingLength, &packetSize );
513+
TEST_ASSERT_EQUAL_INT( MQTTSuccess, status );
514+
/* Make sure remaining size returned is 12. */
515+
TEST_ASSERT_EQUAL_INT( 12, remainingLength );
516+
/* Make sure packet size is 14. */
517+
TEST_ASSERT_EQUAL_INT( 14, packetSize );
518+
471519
/* Test a will message payload length that is too large. */
472520
memset( &connectInfo, 0x0, sizeof( connectInfo ) );
473521
connectInfo.pClientIdentifier = CLIENT_IDENTIFIER;

0 commit comments

Comments
 (0)