]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
bridge_channel: Ensure text messages are zero terminated
authorSean Bright <sean.bright@gmail.com>
Wed, 19 Aug 2020 17:29:51 +0000 (13:29 -0400)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Tue, 25 Aug 2020 15:26:56 +0000 (10:26 -0500)
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

include/asterisk/frame.h
main/bridge_channel.c

index f5a5f2cec5180c83ef1df26263ad9d6364e863d2..0e623d33116e64a0fd88adcc1127c29526d4ea04 100644 (file)
@@ -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,
index 251dea7e356e71765f0a6e451110af6bf249fc28..ade98fd4f395033a9b5aedba809b46ada2c64710 100644 (file)
@@ -2375,6 +2375,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.
@@ -2449,7 +2484,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;