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
This commit is contained in:
Sean Bright 2020-08-19 13:29:51 -04:00 committed by Friendly Automation
parent 55358b1276
commit 32b593c325
2 changed files with 40 additions and 2 deletions

View 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,

View 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;