From 1ec76519cf5fa62dba0d8ee8be9c0239ef6adad3 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Wed, 27 May 2026 15:58:12 +0200 Subject: [PATCH] MT#59962 AmSession: do not leak heap allocated `AmDtmfEvent` If the `postDtmfEvent()` doesn't acquire the ownershop over the allocated event, then no one actually takes care to release it. Modify func to return true/false, and react accordingly on the caller's side. Change-Id: If683eeba275d71850f67d961e9a1cdefe3fe6619 --- core/AmDtmfDetector.cpp | 9 ++++++++- core/AmDtmfDetector.h | 2 +- core/AmRtpStream.cpp | 11 +++++++++-- core/AmSession.cpp | 13 +++++++++++-- core/AmSession.h | 2 +- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/core/AmDtmfDetector.cpp b/core/AmDtmfDetector.cpp index 0650d30a..e718b386 100644 --- a/core/AmDtmfDetector.cpp +++ b/core/AmDtmfDetector.cpp @@ -375,7 +375,14 @@ void AmDtmfDetector::reportEvent() if (m_eventPending) { long duration = (m_lastReportTime.tv_sec - m_startTime.tv_sec) * 1000 + (m_lastReportTime.tv_usec - m_startTime.tv_usec) / 1000; - m_dtmfSink->postDtmfEvent(new AmDtmfEvent(m_currentEvent, duration)); + + AmDtmfEvent * dtmf_ptr = new AmDtmfEvent(m_currentEvent, duration); + if (!m_dtmfSink->postDtmfEvent(dtmf_ptr)) + { + WARN("Unable to post DTMF event. Release it.\n"); + delete dtmf_ptr; + } + m_eventPending = false; m_sipEventReceived = false; m_rtpEventReceived = false; diff --git a/core/AmDtmfDetector.h b/core/AmDtmfDetector.h index 74b9d887..e39233aa 100644 --- a/core/AmDtmfDetector.h +++ b/core/AmDtmfDetector.h @@ -387,7 +387,7 @@ class AmRtpDtmfDetector class AmDtmfSink { public: - virtual void postDtmfEvent(AmDtmfEvent *) = 0; + virtual bool postDtmfEvent(AmDtmfEvent *) = 0; virtual ~AmDtmfSink() { } }; diff --git a/core/AmRtpStream.cpp b/core/AmRtpStream.cpp index 30652ce2..390b97a5 100644 --- a/core/AmRtpStream.cpp +++ b/core/AmRtpStream.cpp @@ -672,8 +672,15 @@ void AmRtpStream::recvDtmfPacket(AmRtpPacket* p) { DBG("DTMF: event=%i; e=%i; r=%i; volume=%i; duration=%i; ts=%u session = [%p]\n", dpl->event,dpl->e,dpl->r,dpl->volume,ntohs(dpl->duration),p->timestamp, session); - if (session) - session->postDtmfEvent(new AmRtpDtmfEvent(dpl, getLocalTelephoneEventRate(), p->timestamp)); + + if (session) { + AmDtmfEvent * dtmf_ptr = new AmRtpDtmfEvent(dpl, getLocalTelephoneEventRate(), p->timestamp); + if (!session->postDtmfEvent(dtmf_ptr)) + { + WARN("Unable to post DTMF event. Release it.\n"); + delete dtmf_ptr; + } + } } } diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 38cc9fc3..1b9bdee1 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -677,7 +677,7 @@ void AmSession::setInbandDetector(Dtmf::InbandDetectorType t) m_dtmfDetector.setInbandDetector(t, RTPStream()->getSampleRate()); } -void AmSession::postDtmfEvent(AmDtmfEvent *evt) +bool AmSession::postDtmfEvent(AmDtmfEvent *evt) { if (m_dtmfDetectionEnabled) { @@ -690,7 +690,9 @@ void AmSession::postDtmfEvent(AmDtmfEvent *evt) // post it into our event queue postEvent(evt); } + return true; // the ownership is given further } + return false; // no ownership acquired, caller has to release the heap allocated event } void AmSession::processDtmfEvents() @@ -816,7 +818,14 @@ void AmSession::onSipRequest(const AmSipRequest& req) if (dtmf_body) { string dtmf_body_str(dtmf_body->getPayload()); - postDtmfEvent(new AmSipDtmfEvent(dtmf_body_str)); + + AmDtmfEvent * dtmf_ptr = new AmSipDtmfEvent(dtmf_body_str); + if (!postDtmfEvent(dtmf_ptr)) + { + ILOG_DLG(L_WARN, "Unable to post DTMF event. Release it.\n"); + delete dtmf_ptr; + } + dlg->reply(req, 200, "OK"); } else { dlg->reply(req, 415, "Unsupported Media Type"); diff --git a/core/AmSession.h b/core/AmSession.h index 2d9a61b4..f680ff10 100644 --- a/core/AmSession.h +++ b/core/AmSession.h @@ -466,7 +466,7 @@ public: /** * Entry point for DTMF events */ - void postDtmfEvent(AmDtmfEvent *); + bool postDtmfEvent(AmDtmfEvent *); void setInbandDetector(Dtmf::InbandDetectorType t); bool isDtmfDetectionEnabled() { return m_dtmfDetectionEnabled; }