diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index cbc5ec2320c4d215c937cf1255b7a87280402ac7..c75e50a3badec7076fca11a2ae7a37badf742ed8 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -492,9 +492,13 @@ void ast_pbx_hangup_handler_push(struct ast_channel *chan, const char *handler); * \param callerid pattern to match CallerID, or NULL to match any CallerID * \param application application to run on the extension with that priority level * \param data data to pass to the application - * \param datad + * \param datad a pointer to a function that will deallocate \c data when needed + * or NULL if \c data does not need to be freed. * \param registrar who registered the extension * + * \note On any failure, the function pointed to by \c datap will be called and passed the + * \c data pointer. + * * \retval 0 success * \retval -1 failure */ @@ -520,7 +524,7 @@ int ast_add_extension2(struct ast_context *con, int replace, const char *extensi * \since 12.0.0 * * \note con must be write locked prior to calling. For details about the arguments, - * check ast_add_extension2() + * check ast_add_extension() */ int ast_add_extension2_nolock(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, diff --git a/main/pbx.c b/main/pbx.c index b520f5fc98ebe896d51f06418f9f4fc2d7ffad67..0609240a32fcd3566ee7a29144afe871ae126a6e 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -7346,6 +7346,10 @@ static int ast_add_extension2_lockopt(struct ast_context *con, if (ast_strlen_zero(extension)) { ast_log(LOG_ERROR,"You have to be kidding-- add exten '' to context %s? Figure out a name and call me back. Action ignored.\n", con->name); + /* We always need to deallocate 'data' on failure */ + if (datad) { + datad(data); + } return -1; } @@ -7401,8 +7405,14 @@ static int ast_add_extension2_lockopt(struct ast_context *con, } /* Be optimistic: Build the extension structure first */ - if (!(tmp = ast_calloc(1, length))) + tmp = ast_calloc(1, length); + if (!tmp) { + /* We always need to deallocate 'data' on failure */ + if (datad) { + datad(data); + } return -1; + } if (ast_strlen_zero(label)) /* let's turn empty labels to a null ptr */ label = 0; diff --git a/res/parking/parking_bridge_features.c b/res/parking/parking_bridge_features.c index 5bcdb215cc6decdd7255a5acdfeabe253128d4e9..6863d52e9eb8505f003d20e043c4b17ab8db0e0c 100644 --- a/res/parking/parking_bridge_features.c +++ b/res/parking/parking_bridge_features.c @@ -660,7 +660,6 @@ static int parking_duration_callback(struct ast_bridge_channel *bridge_channel, dial_string_flat, PARK_DIAL_CONTEXT, ast_get_extension_registrar(existing_exten)); } else if (ast_add_extension2_nolock(park_dial_context, 1, dial_string_flat, 1, NULL, NULL, "Dial", duplicate_returnexten, ast_free_ptr, BASE_REGISTRAR, NULL, 0)) { - ast_free(duplicate_returnexten); ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n", dial_string_flat, PARK_DIAL_CONTEXT, returnexten); } diff --git a/res/res_parking.c b/res/res_parking.c index 470396d260017b8ed8bf4a8eff5684720c04a237..cde82d22358a87670d3e3ac1bc0271d0a532cd4e 100644 --- a/res/res_parking.c +++ b/res/res_parking.c @@ -721,7 +721,6 @@ static int parking_add_extension(struct ast_context *context, int replace, const if (ast_add_extension2_nolock(context, replace, extension, priority, NULL, NULL, application, data_duplicate, ast_free_ptr, registrar, NULL, 0)) { - ast_free(data_duplicate); return -1; } diff --git a/res/res_pjsip_config_wizard.c b/res/res_pjsip_config_wizard.c index aec4b58ac055ad74cdfe3650a807fd411cf2343e..e61b7c5cc8a1d427aef3ff520bdb6bdfc5d1444b 100644 --- a/res/res_pjsip_config_wizard.c +++ b/res/res_pjsip_config_wizard.c @@ -475,7 +475,6 @@ static int add_extension(struct ast_context *context, const char *exten, if (ast_add_extension2_nolock(context, 0, exten, priority, NULL, NULL, app, data, free_ptr, BASE_REGISTRAR, NULL, 0)) { - ast_free(data); return -1; }