Compare commits

...

3 Commits

Author SHA1 Message Date
Naveen Albert
381a48b4fa res_cliexec: Remove unnecessary casts to char*.
Resolves: #1436
2025-09-11 14:19:39 +00:00
Ben Ford
6c453da919 rtp_engine.c: Add exception for comfort noise payload.
In a previous commit, a change was made to
ast_rtp_codecs_payload_code_tx_sample_rate to check for differing sample
rates. This ended up returning an invalid payload int for comfort noise.
A check has been added that returns early if the payload is in fact
supposed to be comfort noise.

Fixes: #1340
2025-09-11 14:08:00 +00:00
Naveen Albert
0039de5c35 pbx_variables.c: Create real channel for "dialplan eval function".
"dialplan eval function" has been using a dummy channel for function
evaluation, much like many of the unit tests. However, sometimes, this
can cause issues for functions that are not expecting dummy channels.
As an example, ast_channel_tech(chan) is NULL on such channels, and
ast_channel_tech(chan)->type consequently results in a NULL dereference.
Normally, functions do not worry about this since channels executing
dialplan aren't dummy channels.

While some functions are better about checking for these sorts of edge
cases, use a real channel with a dummy technology to make this CLI
command inherently safe for any dialplan function that could be evaluated
from the CLI.

Resolves: #1434
2025-09-11 12:31:35 +00:00
3 changed files with 58 additions and 9 deletions

View File

@@ -39,6 +39,7 @@
#include "asterisk/module.h"
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/format_cache.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/test.h"
#include "pbx_private.h"
@@ -984,13 +985,19 @@ static char *handle_show_chanvar(struct ast_cli_entry *e, int cmd, struct ast_cl
return CLI_SUCCESS;
}
static const struct ast_channel_tech mock_channel_tech = {
};
static int cli_chan = 0;
/*! \brief CLI support for executing function */
static char *handle_eval_function(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
struct ast_channel *c = NULL;
char *fn, *substituted;
const char *fn, *substituted;
int ret;
char workspace[1024];
RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
switch (cmd) {
case CLI_INIT:
@@ -1010,19 +1017,51 @@ static char *handle_eval_function(struct ast_cli_entry *e, int cmd, struct ast_c
return CLI_SHOWUSAGE;
}
c = ast_dummy_channel_alloc();
if (!c) {
ast_cli(a->fd, "Unable to allocate bogus channel for function evaluation.\n");
if (a->argc != e->args + 1 && a->argc != e->args + 2) {
return CLI_SHOWUSAGE;
}
caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
if (!caps) {
ast_log(LOG_WARNING, "Could not allocate an empty format capabilities structure\n");
return CLI_FAILURE;
}
fn = (char *) a->argv[3];
if (ast_format_cap_append(caps, ast_format_ulaw, 0)) {
ast_log(LOG_WARNING, "Failed to append a ulaw format to capabilities for channel nativeformats\n");
return CLI_FAILURE;
}
if (ast_format_cap_append(caps, ast_format_alaw, 0)) {
ast_log(LOG_WARNING, "Failed to append an alaw format to capabilities for channel nativeformats\n");
return CLI_FAILURE;
}
if (ast_format_cap_append(caps, ast_format_h264, 0)) {
ast_log(LOG_WARNING, "Failed to append an h264 format to capabilities for channel nativeformats\n");
return CLI_FAILURE;
}
c = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, "CLIEval/%d", ++cli_chan);
if (!c) {
ast_cli(a->fd, "Unable to allocate mock channel for application execution.\n");
return CLI_FAILURE;
}
ast_channel_tech_set(c, &mock_channel_tech);
ast_channel_nativeformats_set(c, caps);
ast_channel_set_writeformat(c, ast_format_slin);
ast_channel_set_rawwriteformat(c, ast_format_slin);
ast_channel_set_readformat(c, ast_format_slin);
ast_channel_set_rawreadformat(c, ast_format_slin);
ast_channel_unlock(c);
fn = a->argv[3];
pbx_substitute_variables_helper(c, fn, workspace, sizeof(workspace));
substituted = ast_strdupa(workspace);
workspace[0] = '\0';
ret = ast_func_read(c, substituted, workspace, sizeof(workspace));
c = ast_channel_unref(c);
ast_hangup(c); /* no need to unref separately */
ast_cli(a->fd, "Return Value: %s (%d)\n", ret ? "Failure" : "Success", ret);
ast_cli(a->fd, "Result: %s\n", workspace);

View File

@@ -2135,6 +2135,16 @@ int ast_rtp_codecs_payload_code_tx_sample_rate(struct ast_rtp_codecs *codecs, in
payload = find_static_payload_type(asterisk_format, format, code);
ast_rwlock_unlock(&static_RTP_PT_lock);
/*
* Comfort noise is NOT used as an SDP negotiated format within Asterisk;
* instead, it is used when it is not negotiated. This special case allows
* its payload to be returned when not negotiated, allowing keep alive to
* function as expected.
*/
if (payload == 13 && code == AST_RTP_CN) {
return payload;
}
ast_rwlock_rdlock(&codecs->codecs_lock);
if (payload >= 0 && payload < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)){
type = AST_VECTOR_GET(&codecs->payload_mapping_tx, payload);

View File

@@ -49,7 +49,7 @@ static char *handle_exec(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
{
struct ast_channel *c = NULL;
RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
char *app_name, *app_args;
const char *app_name, *app_args;
int ret = 0;
struct ast_app *app;
@@ -73,8 +73,8 @@ static char *handle_exec(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
return CLI_SHOWUSAGE;
}
app_name = (char *) a->argv[3];
app_args = a->argc == e->args + 2 ? (char *) a->argv[4] : NULL;
app_name = a->argv[3];
app_args = a->argc == e->args + 2 ? a->argv[4] : NULL;
if (!app_name) {
return CLI_FAILURE;