]> 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)
committerSean Bright <sean.bright@gmail.com>
Mon, 24 Aug 2020 13:14:40 +0000 (09:14 -0400)
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 776040f975952c7615f95f3b2a42639dfb8a7e62..ce7e86890f8a6f7793d235025ee305a7bda617fd 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 1a7df87ca24f6998b258a3ce4ecb9381ab2bc6f0..b6ee820bca5c88bc0978fe91b571fcda3f8822ee 100644 (file)
@@ -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;