From db0fc25b27a637ef3a39d790a9aac48e8bfb6af3 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Thu, 1 Oct 2026 18:50:30 +0300 Subject: [PATCH] sdp: invoke callbacks on invalid replies, too We should always invoke the callbacks, because otherwise the client won't know that something went wrong and will keep waiting. --- bt-embedded/services/sdp.c | 20 ++++------ tests/test_sdp.cpp | 76 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/bt-embedded/services/sdp.c b/bt-embedded/services/sdp.c index 7561c49..aa35060 100644 --- a/bt-embedded/services/sdp.c +++ b/bt-embedded/services/sdp.c @@ -846,17 +846,14 @@ static void on_message_received(BteL2cap *l2cap, BteBufferReader *reader, BteSdpServiceSearchReply reply; reply.error_code = error_code; - if (UNLIKELY(error_code != 0)) { + if (UNLIKELY(error_code != 0 || + !parse_service_search_reply(params, param_len, + &reply, &cont_state))) { reply.total_count = reply.count = 0; reply.has_more = false; reply.handles = NULL; req_complete = true; } else { - bool ok = parse_service_search_reply(params, param_len, - &reply, &cont_state); - if (UNLIKELY(!ok)) { - goto end; - } req_complete = !reply.has_more; } bool wants_more = @@ -868,15 +865,12 @@ static void on_message_received(BteL2cap *l2cap, BteBufferReader *reader, BteSdpServiceAttrReply reply; reply.error_code = error_code; - if (UNLIKELY(error_code != 0)) { + if (UNLIKELY(error_code != 0 || + !parse_service_attr_reply(sdp, params, param_len, + &reply, &cont_state))) { reply.attr_list_de = NULL; req_complete = true; } else { - bool ok = parse_service_attr_reply(sdp, params, param_len, - &reply, &cont_state); - if (UNLIKELY(!ok)) { - goto end; - } req_complete = cont_state[0] == 0; } if (req_complete) { @@ -893,7 +887,7 @@ static void on_message_received(BteL2cap *l2cap, BteBufferReader *reader, } else { send_continuation_request(sdp, cont_state); } -end: + if (params_buffer) bte_free(params_buffer); bte_sdp_client_unref(sdp); /* temp reference */ } diff --git a/tests/test_sdp.cpp b/tests/test_sdp.cpp index f62b804..697dd6f 100644 --- a/tests/test_sdp.cpp +++ b/tests/test_sdp.cpp @@ -215,6 +215,40 @@ TEST_F(TestSdpClient, testServiceSearchFragmented) { ASSERT_TRUE(m_backend.sentData().empty()); } +TEST_F(TestSdpClient, testServiceSearchUnparsable) { + std::vector pattern = { 0x1122, 0x3344, 0x5566 }; + std::vector replies; + bool ok = m_sdp->serviceSearchReq( + pattern, 4, [&](const ServiceSearchReply &reply) { + replies.push_back(reply); + return false; + }); + ASSERT_TRUE(ok); + + uint8_t reqId = m_reqId++; + + /* Verify that our request is as expected */ + Buffer patternDe = { + 0x35, 9, + 0x19, 0x11, 0x22, + 0x19, 0x33, 0x44, + 0x19, 0x55, 0x66, + }; + std::vector expectedData = { + makeServiceSearchReq(reqId, patternDe, 4), + }; + ASSERT_EQ(m_backend.sentData(), expectedData); + + /* Send a reply */ + m_backend.sendData(makeSdpMsg(m_localCid, reqId, 0x03, Buffer{0xff})); + bte_handle_events(); + + std::vector expectedReplies = { + ServiceSearchReply {}, + }; + ASSERT_EQ(replies, expectedReplies); +} + TEST_F(TestSdpClient, testServiceAttrSimple) { Buffer idList { 0x35, 5, @@ -366,3 +400,45 @@ TEST_F(TestSdpClient, testServiceSearchAttrSimple) { }; ASSERT_EQ(replies, expectedReplies); } + +TEST_F(TestSdpClient, testServiceSearchAttrUnparsable) { + Buffer pattern { + 0x35, 6, + 0x19, 0x11, 0x22, + 0x19, 0x33, 0x44, + }; + Buffer idList { + 0x35, 5, + 0x0a, 0x00, 0x00, 0xff, 0xff, + }; + std::vector replies; + uint16_t maxCount = 0x1234; + bool ok = + m_sdp->serviceSearchAttrReq(pattern.data(), maxCount, idList.data(), + [&](const ServiceAttrReply &reply) { + replies.push_back(reply); + }); + ASSERT_TRUE(ok); + + uint8_t reqId = m_reqId++; + + /* Verify that our request is as expected */ + std::vector expectedData = { + makeServiceSearchAttrReq(reqId, pattern, maxCount, idList), + }; + ASSERT_EQ(m_backend.sentData(), expectedData); + + /* Send a reply */ + Buffer attrList = { + 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, + }; + sendServiceSearchAttrRsp(reqId, attrList.size(), attrList); + bte_handle_events(); + + std::vector expectedReplies = { + ServiceAttrReply {}, + }; + ASSERT_EQ(replies, expectedReplies); +}