From: Sean Bright Date: Wed, 19 Aug 2020 17:29:51 +0000 (-0400) Subject: bridge_channel: Ensure text messages are zero terminated X-Git-Tag: 13.37.0-rc1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=179530558da026d6b18cbf42d59fe49c7600fd03;p=thirdparty%2Fasterisk.git bridge_channel: Ensure text messages are zero terminated T.140 data in RTP is not zero terminated, so when we are queuing a text frame on a bridge we need to ensure that we are passing a zero terminated string. ASTERISK-28974 #close Change-Id: Ic10057387ce30b2094613ea67e3ae8c5c431dda3 --- diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index 776040f975..ce7e86890f 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -107,7 +107,10 @@ enum ast_frame_type { AST_FRAME_NULL, /*! Inter Asterisk Exchange private frame type */ AST_FRAME_IAX, - /*! Text messages */ + /*! Text messages. The character data may not be zero-terminated, so + * care should be taken when passing it to functions that expect a + * zero-terminated string. The frame's datalen member should be used + * as it indicates the actual number of bytes available. */ AST_FRAME_TEXT, /*! Image Frames */ AST_FRAME_IMAGE, diff --git a/main/bridge_channel.c b/main/bridge_channel.c index 1a7df87ca2..b6ee820bca 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -2291,6 +2291,41 @@ static void bridge_channel_handle_control(struct ast_bridge_channel *bridge_chan } } +/*! + * \internal + * \brief Ensure text data is zero terminated before sending + * + * \param chan Channel to send text to + * \param f The frame containing the text data to send + * + * \return Nothing + */ +static void sendtext_safe(struct ast_channel *chan, const struct ast_frame *f) +{ + if (f->datalen) { + char *text = f->data.ptr; + + if (text[f->datalen - 1]) { + /* Not zero terminated, we need to allocate */ + text = ast_strndup(text, f->datalen); + if (!text) { + return; + } + } + + ast_sendtext(chan, text); + + if (text != f->data.ptr) { + /* Only free if we allocated */ + ast_free(text); + } + } else { + /* Special case if the frame length is zero (although I + * am not sure this is possible?) */ + ast_sendtext(chan, ""); + } +} + /*! * \internal * \brief Handle bridge channel write frame to channel. @@ -2364,7 +2399,7 @@ static void bridge_channel_handle_write(struct ast_bridge_channel *bridge_channe case AST_FRAME_TEXT: ast_debug(1, "Sending TEXT frame to '%s': %*.s\n", ast_channel_name(bridge_channel->chan), fr->datalen, (char *)fr->data.ptr); - ast_sendtext(bridge_channel->chan, fr->data.ptr); + sendtext_safe(bridge_channel->chan, fr); break; case AST_FRAME_TEXT_DATA: msg = (struct ast_msg_data *)fr->data.ptr;