Skip to content

Fix various spec compliance gaps#504

Open
embhorn wants to merge 30 commits intowolfSSL:masterfrom
embhorn:gh_issues
Open

Fix various spec compliance gaps#504
embhorn wants to merge 30 commits intowolfSSL:masterfrom
embhorn:gh_issues

Conversation

@embhorn
Copy link
Copy Markdown
Member

@embhorn embhorn commented Apr 30, 2026

Thanks to @LiD0209 and @itmanlee for the excellent issue reports

@embhorn embhorn self-assigned this Apr 30, 2026
Copilot AI review requested due to automatic review settings April 30, 2026 22:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets MQTT v3.1.1 compliance for fixed-header reserved flags (notably SUBSCRIBE) by validating the first-byte flag nibble during decode/dispatch and ensuring malformed packets lead to connection close in the broker.

Changes:

  • Add a public helper to validate fixed-header reserved flags (MqttPacket_FixedHeaderFlagsValid) and use it from MqttDecode_FixedHeader.
  • Update broker dispatch to (a) pre-validate fixed-header flags for packet types not run through decoders and (b) close connections when handlers report malformed/protocol errors.
  • Add unit tests covering canonical/invalid fixed-header flag permutations and end-to-end decode rejection for SUBSCRIBE/UNSUBSCRIBE/PUBREL and malformed PUBLISH flags.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
wolfmqtt/mqtt_packet.h Exposes new fixed-header flag validation helper as public API.
src/mqtt_packet.c Implements reserved-flag validation and enforces it in MqttDecode_FixedHeader.
src/mqtt_broker.c Closes connections on malformed packets by validating flags pre-dispatch and honoring handler error returns.
tests/test_mqtt_packet.c Adds coverage for valid/invalid reserved-flag nibbles and malformed PUBLISH QoS/DUP combinations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/mqtt_broker.c
Comment thread tests/test_mqtt_packet.c
Comment thread src/mqtt_packet.c Outdated
Comment thread src/mqtt_packet.c Outdated
@embhorn embhorn changed the title Fix various issues reported in GH Fix various soec compliance gaps Apr 30, 2026
@embhorn embhorn changed the title Fix various soec compliance gaps Fix various spec compliance gaps Apr 30, 2026
@embhorn embhorn requested a review from wolfSSL-Fenrir-bot May 5, 2026 17:30
Copy link
Copy Markdown

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #504

Scan targets checked: wolfmqtt-bugs, wolfmqtt-src

No new issues found in the changed files. ✅

@embhorn embhorn requested a review from wolfSSL-Fenrir-bot May 6, 2026 13:47
Copy link
Copy Markdown

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #504

Scan targets checked: wolfmqtt-bugs, wolfmqtt-src

No new issues found in the changed files. ✅

@embhorn embhorn marked this pull request as ready for review May 6, 2026 14:08
@embhorn embhorn assigned wolfSSL-Bot and unassigned embhorn May 6, 2026
Comment thread src/mqtt_broker.c
* unlike packet IDs, 0 has no protocol significance here. */
broker->next_auto_id = 1;
}
auto_len = XSNPRINTF(auto_id, (int)sizeof(auto_id),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rewrite this section to avoid the XSNPRINTF all together. Its the only use...

Comment thread src/mqtt_broker.c
* values, but this helper is the final boundary — a future caller
* passing a reserved value should fail loudly here rather than emit
* a malformed SUBACK on the wire. */
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the uses of empty braces.

Comment thread src/mqtt_broker.c
/* Returns 1 if packet_id is currently awaiting PUBREL, 0 otherwise. */
static int BrokerInboundQos2_Contains(BrokerClient* bc, word16 packet_id)
{
if (bc == NULL || packet_id == 0) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new functions need to avoid empty braces

Comment thread src/mqtt_broker.c
* gate (especially for QoS 0, where the function-
* level rc is otherwise never overwritten before
* return). */
int sub_rc = MqttEncode_Publish(sub->client->tx_buf,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed declaration. Please fix.

Comment thread src/mqtt_client.c
candidate = client->next_packet_id;

#ifdef WOLFMQTT_MULTITHREAD
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid empty braces.

Comment thread src/mqtt_packet.c
}
}

/* [MQTT-3.9.3-2] Validate a SUBACK return code against the spec-allowed
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No unicode. Replace § with "Section" or remove.

### LOW-9: ASCII-only rule violated: em dashes (U+2014) and section signs (U+00A7) in new comments
- **File:** `src/mqtt_broker.c:multiple, src/mqtt_packet.c:multiple, src/mqtt_client.c:3098, wolfmqtt/mqtt_broker.h:253, wolfmqtt/mqtt_packet.h:678,691,745`
- **Function:** `(many)`
- **Action:** SUGGEST
- **Tag:** convention
- **Confidence:** High

**Description:** The diff introduces dozens of non-ASCII characters in new comments: em dashes (U+2014, encoded 0xE2 0x80 0x94) and section signs (U+00A7, encoded 0xC2 0xA7) in references like `v5 §3.2.2.3.20`. The wolfSSL coding rules require 7-bit ASCII for all committed code, comments, and commit messages. Examples include: src/mqtt_broker.c:252,980,995,2854,2957,3097-3099,3328,3500-3508,3675,3713,3719,3872,3952,4144-4156; src/mqtt_packet.c:214-215,257,293-294,357,520,619,1342-1343,1362,1371,1875-1876,2084-2086,2378-2381,2408,2737,2961,3081; src/mqtt_client.c:3098; wolfmqtt/mqtt_broker.h:253; wolfmqtt/mqtt_packet.h:678,691,745.

**Code:**

/* MQTT 3.1.1 §3.12 / v5 §3.12: PINGREQ is fixed-header-

  • only — Remaining Length MUST be 0. */

**Recommendation:** Replace all em dashes and section signs in the diff with ASCII equivalents.

Comment thread src/mqtt_broker.c
* [MQTT-3.9.3-2] reserved-code rejection branch. The prior prototype
* silences -Wmissing-prototypes; the symbol is intentionally not in
* any public header. */
int BrokerSend_SubAck(BrokerClient* bc, word16 packet_id,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this forward declaration needed? Should it be static or put as WOLFMQTT_LOCAL in header.

Comment thread src/mqtt_broker.c
}
WOLFMQTT_FREE(cur);
if (bc->qos2_pending_count > 0) {
bc->qos2_pending_count--;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider debug log for case where this is "else". Shouldn't happen.

Comment thread src/mqtt_broker.c
* count of accepted clients. */
char auto_id[32];
int auto_len;
unsigned long id_value = (unsigned long)broker->next_auto_id++;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For "auto" consider these options...
(a) only increment after CONNECT acceptance
(b) seed next_auto_id from a CSPRNG at init time, would harden against value enumeration.

Comment thread src/mqtt_packet.c
{
word16 i;
if (topic_name == NULL && len > 0) {
return 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function returns 1 for (NULL, 0, level >= 5), which is inconsistent with MqttEncode_Publish's stricter contract that topic_name == NULL is BAD_ARG. The encoder check fires before this helper, so production is safe, but the helper itself is permissive enough that a future caller could pass NULL believing it is a legal Topic Alias placeholder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment