summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2016-02-15 14:37:30 -0700
committerGeorge Joseph <george.joseph@fairview5.com>2016-02-15 15:53:25 -0600
commit34c64707d1aa346fb0e9c7f97e375d22dedf67d9 (patch)
tree826da415fa8aefd1441358dd041a010e5b7ec704
parent9c28acd9dbf5f4c3cbd302df0900880b4339c735 (diff)
res_pjsip_caller_id: Fix segfault when replacing rpid or pai header
If the PJSIP_HEADER dialplan function adds a PAI or RPID header and send_rpid or send_pai is set, res_pjsip_caller_id attemps to retrieve, parse and modify the header added by the dialplan function. Since the header added by the dialplan function is generic string, there are no virtual functions to parse the uri and we get a segfault when we try. Since the modify, was really only an overwrite, we now just delete the old header if it was type PJSIP_H_OTHER and recreate it. This raises a question for another time though: What should happen with duplicate headers? Right now res_pjsip_header_funcs doesn't check for dups so if it's session supplement is loaded after res_pjsip_caller_id's (or any other module that adds headers), there'll be dups in the message. ASTERISK-25337 #close Change-Id: I5e296b52d30f106b822c0eb27c4c2b0e0f71c7fa
-rw-r--r--res/res_pjsip_caller_id.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/res/res_pjsip_caller_id.c b/res/res_pjsip_caller_id.c
index f1908a7d2..db4e17863 100644
--- a/res/res_pjsip_caller_id.c
+++ b/res/res_pjsip_caller_id.c
@@ -511,9 +511,22 @@ static void add_pai_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
*/
old_pai = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_pai_name, NULL);
if (old_pai) {
- modify_id_header(tdata->pool, old_pai, id);
- add_privacy_header(tdata, id);
- return;
+ /* If type is OTHER, then the existing header was most likely
+ * added by the PJSIP_HEADER dial plan function as a simple
+ * name/value pair. We can't pass this to modify_id_header because
+ * there are no virtual functions to get the uri. We could parse
+ * it into a pjsip_fromto_hdr but it isn't worth it since
+ * modify_id_header is just going to overwrite the name and number
+ * anyway. We'll just remove it from the header list instead
+ * and create a new one.
+ */
+ if (old_pai->type == PJSIP_H_OTHER) {
+ pj_list_erase(old_pai);
+ } else {
+ modify_id_header(tdata->pool, old_pai, id);
+ add_privacy_header(tdata, id);
+ return;
+ }
}
pai_hdr = create_new_id_hdr(&pj_pai_name, tdata, id);
@@ -600,9 +613,22 @@ static void add_rpid_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
*/
old_rpid = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_rpid_name, NULL);
if (old_rpid) {
- modify_id_header(tdata->pool, old_rpid, id);
- add_privacy_params(tdata, old_rpid, id);
- return;
+ /* If type is OTHER, then the existing header was most likely
+ * added by the PJSIP_HEADER dial plan function as a simple
+ * name/value pair. We can't pass this to modify_id_header because
+ * there are no virtual functions to get the uri. We could parse
+ * it into a pjsip_fromto_hdr but it isn't worth it since
+ * modify_id_header is just going to overwrite the name and number
+ * anyway. We'll just remove it from the header list instead
+ * and create a new one.
+ */
+ if (old_rpid->type == PJSIP_H_OTHER) {
+ pj_list_erase(old_rpid);
+ } else {
+ modify_id_header(tdata->pool, old_rpid, id);
+ add_privacy_params(tdata, old_rpid, id);
+ return;
+ }
}
rpid_hdr = create_new_id_hdr(&pj_rpid_name, tdata, id);