Merge "ARI: Deleting log channels"
authorJoshua Colp <jcolp@digium.com>
Fri, 7 Aug 2015 15:41:11 +0000 (10:41 -0500)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Fri, 7 Aug 2015 15:41:12 +0000 (10:41 -0500)
res/res_pjsip.c
res/res_pjsip/presence_xml.c
res/res_pjsip_pidf_digium_body_supplement.c
res/res_pjsip_pubsub.c
res/res_rtp_asterisk.c

index 4de0745..25a35c0 100644 (file)
@@ -40,6 +40,8 @@
 #include "asterisk/file.h"
 #include "asterisk/cli.h"
 #include "asterisk/res_pjsip_cli.h"
+#include "asterisk/test.h"
+#include "asterisk/res_pjsip_presence_xml.h"
 
 /*** MODULEINFO
        <depend>pjproject</depend>
@@ -3755,6 +3757,57 @@ static void remove_request_headers(pjsip_endpoint *endpt)
        }
 }
 
+AST_TEST_DEFINE(xml_sanitization_end_null)
+{
+       char sanitized[8];
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "xml_sanitization_end_null";
+               info->category = "/res/res_pjsip/";
+               info->summary = "Ensure XML sanitization works as expected with a long string";
+               info->description = "This test sanitizes a string which exceeds the output\n"
+                       "buffer size. Once done the string is confirmed to be NULL terminated.";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       ast_sip_sanitize_xml("aaaaaaaaaaaa", sanitized, sizeof(sanitized));
+       if (sanitized[7] != '\0') {
+               ast_test_status_update(test, "Sanitized XML string is not null-terminated when it should be\n");
+               return AST_TEST_FAIL;
+       }
+
+       return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(xml_sanitization_exceeds_buffer)
+{
+       char sanitized[8];
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "xml_sanitization_exceeds_buffer";
+               info->category = "/res/res_pjsip/";
+               info->summary = "Ensure XML sanitization does not exceed buffer when output won't fit";
+               info->description = "This test sanitizes a string which before sanitization would\n"
+                       "fit within the output buffer. After sanitization, however, the string would\n"
+                       "exceed the buffer. Once done the string is confirmed to be NULL terminated.";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       ast_sip_sanitize_xml("<><><>&", sanitized, sizeof(sanitized));
+       if (sanitized[7] != '\0') {
+               ast_test_status_update(test, "Sanitized XML string is not null-terminated when it should be\n");
+               return AST_TEST_FAIL;
+       }
+
+       return AST_TEST_PASS;
+}
+
 /*!
  * \internal
  * \brief Reload configuration within a PJSIP thread
@@ -3909,6 +3962,9 @@ static int load_module(void)
        ast_res_pjsip_init_options_handling(0);
        ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
 
+       AST_TEST_REGISTER(xml_sanitization_end_null);
+       AST_TEST_REGISTER(xml_sanitization_exceeds_buffer);
+
        return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -3950,6 +4006,9 @@ static int unload_pjsip(void *data)
 
 static int unload_module(void)
 {
+       AST_TEST_UNREGISTER(xml_sanitization_end_null);
+       AST_TEST_UNREGISTER(xml_sanitization_exceeds_buffer);
+
        /* The thread this is called from cannot call PJSIP/PJLIB functions,
         * so we have to push the work to the threadpool to handle
         */
index 12bfa07..b98ea02 100644 (file)
@@ -30,45 +30,54 @@ void ast_sip_sanitize_xml(const char *input, char *output, size_t len)
 {
        char *copy = ast_strdupa(input);
        char *break_point;
+       size_t remaining = len - 1;
 
        output[0] = '\0';
 
-       while ((break_point = strpbrk(copy, "<>\"&'\n\r"))) {
+       while ((break_point = strpbrk(copy, "<>\"&'\n\r")) && remaining) {
                char to_escape = *break_point;
 
                *break_point = '\0';
-               strncat(output, copy, len);
+               strncat(output, copy, remaining);
+
+               /* The strncat function will write remaining+1 if the string length is
+                * equal to or greater than the size provided to it. We take this into
+                * account by subtracting 1, which ensures that the NULL byte is written
+                * inside of the provided buffer.
+                */
+               remaining = len - strlen(output) - 1;
 
                switch (to_escape) {
                case '<':
-                       strncat(output, "&lt;", len);
+                       strncat(output, "&lt;", remaining);
                        break;
                case '>':
-                       strncat(output, "&gt;", len);
+                       strncat(output, "&gt;", remaining);
                        break;
                case '"':
-                       strncat(output, "&quot;", len);
+                       strncat(output, "&quot;", remaining);
                        break;
                case '&':
-                       strncat(output, "&amp;", len);
+                       strncat(output, "&amp;", remaining);
                        break;
                case '\'':
-                       strncat(output, "&apos;", len);
+                       strncat(output, "&apos;", remaining);
                        break;
                case '\r':
-                       strncat(output, "&#13;", len);
+                       strncat(output, "&#13;", remaining);
                        break;
                case '\n':
-                       strncat(output, "&#10;", len);
+                       strncat(output, "&#10;", remaining);
                        break;
                };
 
                copy = break_point + 1;
+               remaining = len - strlen(output) - 1;
        }
 
        /* Be sure to copy everything after the final bracket */
-       if (*copy) {
-               strncat(output, copy, len);
+       if (*copy && remaining) {
+               strncat(output, copy, remaining);
        }
 }
 
index b6212ea..93e4982 100644 (file)
@@ -40,7 +40,7 @@ static int pidf_supplement_body(void *body, void *data)
 {
        struct ast_sip_exten_state_data *state_data = data;
        pj_xml_node *node;
-       char sanitized[256];
+       char sanitized[1024];
 
        if (ast_strlen_zero(state_data->user_agent) ||
            !strstr(state_data->user_agent, "digium")) {
index 76c9b33..57c85a4 100644 (file)
@@ -561,7 +561,7 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
                expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
                sub_tree->persistence->expires = ast_tvadd(ast_tvnow(), ast_samp2tv(expires, 1));
 
-               ast_copy_string(sub_tree->persistence->packet, rdata->pkt_info.packet,
+               pjsip_msg_print(rdata->msg_info.msg, sub_tree->persistence->packet,
                                sizeof(sub_tree->persistence->packet));
                ast_copy_string(sub_tree->persistence->src_name, rdata->pkt_info.src_name,
                                sizeof(sub_tree->persistence->src_name));
@@ -1338,6 +1338,13 @@ static int subscription_persistence_recreate(void *obj, void *arg, int flags)
                return 0;
        }
 
+       if (rdata.msg_info.msg->type != PJSIP_REQUEST_MSG) {
+               ast_log(LOG_NOTICE, "Endpoint %s persisted a SIP response instead of a subscribe request. Unable to reload subscription.\n",
+                               ast_sorcery_object_get_id(endpoint));
+               ast_sorcery_delete(ast_sip_get_sorcery(), persistence);
+               return 0;
+       }
+
        request_uri = pjsip_uri_get_uri(rdata.msg_info.msg->line.req.uri);
        resource_size = pj_strlen(&request_uri->user) + 1;
        resource = alloca(resource_size);
index 5f21c14..cca1969 100644 (file)
@@ -4517,6 +4517,10 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
        }
 
        payload = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payloadtype);
+       if (!payload) {
+               /* Unknown payload type. */
+               return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
+       }
 
        /* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */
        if (!payload->asterisk_format) {
@@ -4543,10 +4547,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
                /* Even if no frame was returned by one of the above methods,
                 * we may have a frame to return in our frame list
                 */
-               if (!AST_LIST_EMPTY(&frames)) {
-                       return AST_LIST_FIRST(&frames);
-               }
-               return &ast_null_frame;
+               return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
        }
 
        ao2_replace(rtp->lastrxformat, payload->format);