<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/17919">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">bundled_pjproject:  Add additional multipart search utils<br><br>Added the following APIs:<br>pjsip_multipart_find_part_by_header()<br>pjsip_multipart_find_part_by_header_str()<br>pjsip_multipart_find_part_by_cid_str()<br>pjsip_multipart_find_part_by_cid_uri()<br><br>Change-Id: I6aee3dcf59eb171f93aae0f0564ff907262ef40d<br>---<br>A third-party/pjproject/patches/0160-Additional-multipart-improvements.patch<br>1 file changed, 644 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch b/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch</span><br><span>new file mode 100644</span><br><span>index 0000000..373f9b8</span><br><span>--- /dev/null</span><br><span>+++ b/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch</span><br><span>@@ -0,0 +1,644 @@</span><br><span style="color: hsl(120, 100%, 40%);">+From b7ecff22e77887626fd8e8608c4dd73bc7b7366f Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(120, 100%, 40%);">+From: George Joseph <gjoseph@sangoma.com></span><br><span style="color: hsl(120, 100%, 40%);">+Date: Tue, 18 Jan 2022 06:14:31 -0700</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: [PATCH] Additional multipart improvements</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Added the following APIs:</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip_multipart_find_part_by_header()</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip_multipart_find_part_by_header_str()</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip_multipart_find_part_by_cid_str()</span><br><span style="color: hsl(120, 100%, 40%);">+pjsip_multipart_find_part_by_cid_uri()</span><br><span style="color: hsl(120, 100%, 40%);">+---</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/include/pjsip/sip_multipart.h |  83 ++++++++++</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/src/pjsip/sip_multipart.c     | 223 +++++++++++++++++++++++++++</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/src/test/multipart_test.c     | 225 +++++++++++++++++++++++++++-</span><br><span style="color: hsl(120, 100%, 40%);">+ 3 files changed, 530 insertions(+), 1 deletion(-)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/include/pjsip/sip_multipart.h b/pjsip/include/pjsip/sip_multipart.h</span><br><span style="color: hsl(120, 100%, 40%);">+index 1c05767c5..c6b82b0b4 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/include/pjsip/sip_multipart.h</span><br><span>++++ b/pjsip/include/pjsip/sip_multipart.h</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -153,6 +153,89 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">+                        const pjsip_media_type *content_type,</span><br><span style="color: hsl(120, 100%, 40%);">+                         const pjsip_multipart_part *start);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++/**</span><br><span style="color: hsl(120, 100%, 40%);">++ * Find a body inside multipart bodies which has a header matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ * supplied one. Most useful for finding a part with a specific Content-ID.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param pool            Memory pool to use for temp space.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param mp               The multipart body.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param search_hdr      Header to search for.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param start         If specified, the search will begin at</span><br><span style="color: hsl(120, 100%, 40%);">++ *                     start->next part. Otherwise it will begin at</span><br><span style="color: hsl(120, 100%, 40%);">++ *                    the first part in the multipart bodies.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @return               The first part which has a header matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ *                     specified one, or NULL if not found.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_header(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                               const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    void *search_hdr,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    const pjsip_multipart_part *start);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++/**</span><br><span style="color: hsl(120, 100%, 40%);">++ * Find a body inside multipart bodies which has a header matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ * supplied name and value. Most useful for finding a part with a specific</span><br><span style="color: hsl(120, 100%, 40%);">++ * Content-ID.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param pool           Memory pool to use for temp space.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param mp               The multipart body.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param hdr_name        Header name to search for.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param hdr_value        Header value search for.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param start              If specified, the search will begin at</span><br><span style="color: hsl(120, 100%, 40%);">++ *                     start->next part. Otherwise it will begin at</span><br><span style="color: hsl(120, 100%, 40%);">++ *                    the first part in the multipart bodies.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @return               The first part which has a header matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ *                     specified one, or NULL if not found.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                                   const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    const pj_str_t *hdr_name,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    const pj_str_t *hdr_value,</span><br><span style="color: hsl(120, 100%, 40%);">++                                   const pjsip_multipart_part *start);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++/**</span><br><span style="color: hsl(120, 100%, 40%);">++ * Find a body inside multipart bodies which has a Content-ID value matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ * supplied "cid" URI in pj_str form.  The "cid:" scheme will be assumed if the</span><br><span style="color: hsl(120, 100%, 40%);">++ * URL doesn't start with it.  Enclosing angle brackets will also be handled</span><br><span style="color: hsl(120, 100%, 40%);">++ * correctly if they exist.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param pool       Memory pool to use for temp space.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param mp       The multipart body.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param cid     The "cid" URI to search for in pj_str form.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @return         The first part which has a Content-ID header matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ *                  specified "cid" URI. or NULL if not found.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                           const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                            pj_str_t *cid);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++/**</span><br><span style="color: hsl(120, 100%, 40%);">++ * Find a body inside multipart bodies which has a Content-ID value matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ * supplied "cid" URI.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param pool        Memory pool to use for temp space.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param mp       The multipart body.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param cid     The "cid" URI to search for.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @return                The first part which had a Content-ID header matching the</span><br><span style="color: hsl(120, 100%, 40%);">++ *                  specified "cid" URI. or NULL if not found.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                           const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                            pjsip_other_uri *cid_uri);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+ /**</span><br><span style="color: hsl(120, 100%, 40%);">+  * Parse multipart message.</span><br><span style="color: hsl(120, 100%, 40%);">+  *</span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/src/pjsip/sip_multipart.c b/pjsip/src/pjsip/sip_multipart.c</span><br><span style="color: hsl(120, 100%, 40%);">+index e7d722d2e..9d8be55b0 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/src/pjsip/sip_multipart.c</span><br><span>++++ b/pjsip/src/pjsip/sip_multipart.c</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -19,6 +19,7 @@</span><br><span style="color: hsl(120, 100%, 40%);">+ #include <pjsip/sip_multipart.h></span><br><span style="color: hsl(120, 100%, 40%);">+ #include <pjsip/sip_parser.h></span><br><span style="color: hsl(120, 100%, 40%);">+ #include <pjlib-util/scanner.h></span><br><span style="color: hsl(120, 100%, 40%);">++#include <pjlib-util/string.h></span><br><span style="color: hsl(120, 100%, 40%);">+ #include <pj/assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+ #include <pj/ctype.h></span><br><span style="color: hsl(120, 100%, 40%);">+ #include <pj/errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+@@ -416,6 +417,220 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">+     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++/*</span><br><span style="color: hsl(120, 100%, 40%);">++ * Find a body inside multipart bodies which has the header and value.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                              const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    const pj_str_t *hdr_name,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    const pj_str_t *hdr_value,</span><br><span style="color: hsl(120, 100%, 40%);">++                                   const pjsip_multipart_part *start)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    struct multipart_data *m_data;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_multipart_part *part;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_hdr *found_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t found_hdr_str;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t found_hdr_value;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_size_t expected_hdr_slen;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_size_t buf_size;</span><br><span style="color: hsl(120, 100%, 40%);">++    int hdr_name_len;</span><br><span style="color: hsl(120, 100%, 40%);">++#define REASONABLE_PADDING 32</span><br><span style="color: hsl(120, 100%, 40%);">++#define SEPARATOR_LEN 2</span><br><span style="color: hsl(120, 100%, 40%);">++    /* Must specify mandatory params */</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_ASSERT_RETURN(mp && hdr_name && hdr_value, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* mp must really point to an actual multipart msg body */</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /*</span><br><span style="color: hsl(120, 100%, 40%);">++     * We'll need to "print" each header we find to test it but</span><br><span style="color: hsl(120, 100%, 40%);">++     * allocating a buffer of PJSIP_MAX_URL_SIZE is overkill.</span><br><span style="color: hsl(120, 100%, 40%);">++     * Instead, we'll allocate one large enough to hold the search</span><br><span style="color: hsl(120, 100%, 40%);">++     * header name, the ": " separator, the search hdr value, and</span><br><span style="color: hsl(120, 100%, 40%);">++     * the NULL terminator.  If we can't print the found header</span><br><span style="color: hsl(120, 100%, 40%);">++     * into that buffer then it can't be a match.</span><br><span style="color: hsl(120, 100%, 40%);">++     *</span><br><span style="color: hsl(120, 100%, 40%);">++     * Some header print functions such as generic_int require enough</span><br><span style="color: hsl(120, 100%, 40%);">++     * space to print the maximum possible header length so we'll</span><br><span style="color: hsl(120, 100%, 40%);">++     * add a reasonable amount to the print buffer size.</span><br><span style="color: hsl(120, 100%, 40%);">++     */</span><br><span style="color: hsl(120, 100%, 40%);">++    expected_hdr_slen = hdr_name->slen + SEPARATOR_LEN + hdr_value->slen;</span><br><span style="color: hsl(120, 100%, 40%);">++    buf_size = expected_hdr_slen + REASONABLE_PADDING;</span><br><span style="color: hsl(120, 100%, 40%);">++    found_hdr_str.ptr = pj_pool_alloc(pool, buf_size);</span><br><span style="color: hsl(120, 100%, 40%);">++    found_hdr_str.slen = 0;</span><br><span style="color: hsl(120, 100%, 40%);">++    hdr_name_len = hdr_name->slen + SEPARATOR_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    m_data = (struct multipart_data*)mp->data;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    if (start)</span><br><span style="color: hsl(120, 100%, 40%);">++  part = start->next;</span><br><span style="color: hsl(120, 100%, 40%);">++    else</span><br><span style="color: hsl(120, 100%, 40%);">++    part = m_data->part_head.next;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    while (part != &m_data->part_head) {</span><br><span style="color: hsl(120, 100%, 40%);">++       found_hdr = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++    while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, hdr_name,</span><br><span style="color: hsl(120, 100%, 40%);">++          (found_hdr ? found_hdr->next : NULL))) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++      found_hdr_str.slen = pjsip_hdr_print_on((void*) found_hdr, found_hdr_str.ptr, buf_size);</span><br><span style="color: hsl(120, 100%, 40%);">++     /*</span><br><span style="color: hsl(120, 100%, 40%);">++            * If the buffer was too small (slen = -1) or the result wasn't</span><br><span style="color: hsl(120, 100%, 40%);">++           * the same length as the search header, it can't be a match.</span><br><span style="color: hsl(120, 100%, 40%);">++             */</span><br><span style="color: hsl(120, 100%, 40%);">++          if (found_hdr_str.slen != expected_hdr_slen) {</span><br><span style="color: hsl(120, 100%, 40%);">++           continue;</span><br><span style="color: hsl(120, 100%, 40%);">++        }</span><br><span style="color: hsl(120, 100%, 40%);">++            /*</span><br><span style="color: hsl(120, 100%, 40%);">++            * Set the value overlay to start at the found header value...</span><br><span style="color: hsl(120, 100%, 40%);">++        */</span><br><span style="color: hsl(120, 100%, 40%);">++          found_hdr_value.ptr = found_hdr_str.ptr + hdr_name_len;</span><br><span style="color: hsl(120, 100%, 40%);">++      found_hdr_value.slen = found_hdr_str.slen - hdr_name_len;</span><br><span style="color: hsl(120, 100%, 40%);">++            /* ...and compare it to the supplied header value. */</span><br><span style="color: hsl(120, 100%, 40%);">++        if (pj_strcmp(hdr_value, &found_hdr_value) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++           return part;</span><br><span style="color: hsl(120, 100%, 40%);">++     }</span><br><span style="color: hsl(120, 100%, 40%);">++        }</span><br><span style="color: hsl(120, 100%, 40%);">++    part = part->next;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++    return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++#undef SEPARATOR_LEN</span><br><span style="color: hsl(120, 100%, 40%);">++#undef REASONABLE_PADDING</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_header(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                                const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    void *search_for,</span><br><span style="color: hsl(120, 100%, 40%);">++                                    const pjsip_multipart_part *start)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    struct multipart_data *m_data;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_hdr *search_hdr = search_for;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t search_buf;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* Must specify mandatory params */</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_ASSERT_RETURN(mp && search_hdr, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* mp must really point to an actual multipart msg body */</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /*</span><br><span style="color: hsl(120, 100%, 40%);">++     * Unfortunately, there isn't enough information to determine</span><br><span style="color: hsl(120, 100%, 40%);">++     * the maximum printed size of search_hdr at this point so we</span><br><span style="color: hsl(120, 100%, 40%);">++     * have to allocate a reasonable max.</span><br><span style="color: hsl(120, 100%, 40%);">++     */</span><br><span style="color: hsl(120, 100%, 40%);">++    search_buf.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">++    search_buf.slen = pjsip_hdr_print_on(search_hdr, search_buf.ptr, PJSIP_MAX_URL_SIZE - 1);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (search_buf.slen <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++    /*</span><br><span style="color: hsl(120, 100%, 40%);">++     * Set the header value to start after the header name plus the ":", then</span><br><span style="color: hsl(120, 100%, 40%);">++     * strip leading and trailing whitespace.</span><br><span style="color: hsl(120, 100%, 40%);">++     */</span><br><span style="color: hsl(120, 100%, 40%);">++    search_buf.ptr += (search_hdr->name.slen + 1);</span><br><span style="color: hsl(120, 100%, 40%);">++    search_buf.slen -= (search_hdr->name.slen + 1);</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_strtrim(&search_buf);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return pjsip_multipart_find_part_by_header_str(pool, mp, &search_hdr->name, &search_buf, start);</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++/*</span><br><span style="color: hsl(120, 100%, 40%);">++ * Convert a Content-ID URI to it's corresponding header value.</span><br><span style="color: hsl(120, 100%, 40%);">++ * RFC2392 says...</span><br><span style="color: hsl(120, 100%, 40%);">++ * A "cid" URL is converted to the corresponding Content-ID message</span><br><span style="color: hsl(120, 100%, 40%);">++ * header by removing the "cid:" prefix, converting the % encoded</span><br><span style="color: hsl(120, 100%, 40%);">++ * character(s) to their equivalent US-ASCII characters, and enclosing</span><br><span style="color: hsl(120, 100%, 40%);">++ * the remaining parts with an angle bracket pair, "<" and ">".</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * This implementation will accept URIs with or without the "cid:"</span><br><span style="color: hsl(120, 100%, 40%);">++ * scheme and optional angle brackets.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++static pj_str_t cid_uri_to_hdr_value(pj_pool_t *pool, pj_str_t *cid_uri)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_size_t cid_len = pj_strlen(cid_uri);</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_size_t alloc_len = cid_len + 2 /* for the leading and trailing angle brackets */;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t uri_overlay;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t cid_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t hdr_overlay;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_strassign(&uri_overlay, cid_uri);</span><br><span style="color: hsl(120, 100%, 40%);">++    /* If the URI is already enclosed in angle brackets, remove them. */</span><br><span style="color: hsl(120, 100%, 40%);">++    if (uri_overlay.ptr[0] == '<') {</span><br><span style="color: hsl(120, 100%, 40%);">++       uri_overlay.ptr++;</span><br><span style="color: hsl(120, 100%, 40%);">++   uri_overlay.slen -= 2;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++    /* If the URI starts with the "cid:" scheme, skip over it. */</span><br><span style="color: hsl(120, 100%, 40%);">++    if (pj_strncmp2(&uri_overlay, "cid:", 4) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++    uri_overlay.ptr += 4;</span><br><span style="color: hsl(120, 100%, 40%);">++        uri_overlay.slen -= 4;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++    /* Start building */</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_hdr.ptr = pj_pool_alloc(pool, alloc_len);</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_hdr.ptr[0] = '<';</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_hdr.slen = 1;</span><br><span style="color: hsl(120, 100%, 40%);">++    hdr_overlay.ptr = cid_hdr.ptr + 1;</span><br><span style="color: hsl(120, 100%, 40%);">++    hdr_overlay.slen = 0;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_strcpy_unescape(&hdr_overlay, &uri_overlay);</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_hdr.slen += hdr_overlay.slen;</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_hdr.ptr[cid_hdr.slen] = '>';</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_hdr.slen++;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return cid_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                               const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                            pj_str_t *cid)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    struct multipart_data *m_data;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_multipart_part *part;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_generic_string_hdr *found_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t found_hdr_value;</span><br><span style="color: hsl(120, 100%, 40%);">++    static pj_str_t hdr_name = { "Content-ID", 10};</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t hdr_value;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_ASSERT_RETURN(pool && mp && cid && (pj_strlen(cid) > 0), NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    hdr_value = cid_uri_to_hdr_value(pool, cid);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (pj_strlen(&hdr_value) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    m_data = (struct multipart_data*)mp->data;</span><br><span style="color: hsl(120, 100%, 40%);">++    part = m_data->part_head.next;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    while (part != &m_data->part_head) {</span><br><span style="color: hsl(120, 100%, 40%);">++     found_hdr = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++    while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, &hdr_name,</span><br><span style="color: hsl(120, 100%, 40%);">++     (found_hdr ? found_hdr->next : NULL))) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">++         if (pj_strcmp(&hdr_value, &found_hdr->hvalue) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++         return part;</span><br><span style="color: hsl(120, 100%, 40%);">++     }</span><br><span style="color: hsl(120, 100%, 40%);">++        }</span><br><span style="color: hsl(120, 100%, 40%);">++    part = part->next;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++    return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(120, 100%, 40%);">++pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">++                               const pjsip_msg_body *mp,</span><br><span style="color: hsl(120, 100%, 40%);">++                            pjsip_other_uri *cid_uri)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_ASSERT_RETURN(pool && mp && cid_uri, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    if (pj_strcmp2(&cid_uri->scheme, "cid") != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++    /*</span><br><span style="color: hsl(120, 100%, 40%);">++     * We only need to pass the URI content so we</span><br><span style="color: hsl(120, 100%, 40%);">++     * can do that directly.</span><br><span style="color: hsl(120, 100%, 40%);">++     */</span><br><span style="color: hsl(120, 100%, 40%);">++    return pjsip_multipart_find_part_by_cid_str(pool, mp, &cid_uri->content);</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parse a multipart part. "pct" is parent content-type  */</span><br><span style="color: hsl(120, 100%, 40%);">+ static pjsip_multipart_part *parse_multipart_part(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   char *start,</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -584,6 +799,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">+            (int)boundary.slen, boundary.ptr));</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Build the delimiter:</span><br><span style="color: hsl(120, 100%, 40%);">+      *   delimiter = "--" boundary</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -630,6 +846,8 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">+  if (*curptr=='\r') ++curptr;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (*curptr!='\n') {</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Expecting a newline here */</span><br><span style="color: hsl(120, 100%, 40%);">++       PJ_LOG(2, (THIS_FILE, "Failed to find newline"));</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     ++curptr;</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -645,6 +863,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">+             curptr = pj_strstr(&subbody, &delim);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!curptr) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* We're really expecting end delimiter to be found. */</span><br><span style="color: hsl(120, 100%, 40%);">++          PJ_LOG(2, (THIS_FILE, "Failed to find end-delimiter"));</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -670,9 +889,13 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(120, 100%, 40%);">+        part = parse_multipart_part(pool, start_body, end_body - start_body,</span><br><span style="color: hsl(120, 100%, 40%);">+                              ctype);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (part) {</span><br><span style="color: hsl(120, 100%, 40%);">++      TRACE_((THIS_FILE, "Adding part"));</span><br><span style="color: hsl(120, 100%, 40%);">+         pjsip_multipart_add_part(pool, body, part);</span><br><span style="color: hsl(120, 100%, 40%);">++      } else {</span><br><span style="color: hsl(120, 100%, 40%);">++         PJ_LOG(2, (THIS_FILE, "Failed to add part"));</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">++    TRACE_((THIS_FILE, "pjsip_multipart_parse finished: %p", body));</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+     return body;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/src/test/multipart_test.c b/pjsip/src/test/multipart_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+index 4f16e68bf..97267a290 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/src/test/multipart_test.c</span><br><span>++++ b/pjsip/src/test/multipart_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -28,6 +28,7 @@</span><br><span style="color: hsl(120, 100%, 40%);">+ typedef pj_status_t (*verify_ptr)(pj_pool_t*,pjsip_msg_body*);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body);</span><br><span style="color: hsl(120, 100%, 40%);">++static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ static struct test_t</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -68,7 +69,41 @@ static struct test_t</span><br><span style="color: hsl(120, 100%, 40%);">+               "This is epilogue, which should be ignored too",</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+                 &verify1</span><br><span style="color: hsl(120, 100%, 40%);">++ },</span><br><span style="color: hsl(120, 100%, 40%);">++   {</span><br><span style="color: hsl(120, 100%, 40%);">++            /* Content-type */</span><br><span style="color: hsl(120, 100%, 40%);">++           "multipart", "mixed", "12345",</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++              /* Body: */</span><br><span style="color: hsl(120, 100%, 40%);">++          "This is the prolog, which should be ignored.\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++         "--12345\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++              "Content-Type: text/plain\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++             "Content-ID: <header1@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++              "Content-ID: <\"header1\"@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++                "Content-Length: 13\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++             "has header1\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++          "--12345 \t\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "Content-Type: application/pidf+xml\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "Content-ID: <my header2@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "Content-ID: <my\xffheader2@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++                "Content-Length: 13\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++             "has header2\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++          "--12345\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++              "Content-Type: text/plain\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++             "Content-ID: <my header3@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "Content-ID: <header1@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++              "Content-ID: <my header4@example.org>\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "Content-Length: 13\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++           "\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++             "has header4\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++          "--12345--\r\n"</span><br><span style="color: hsl(120, 100%, 40%);">++            "This is epilogue, which should be ignored too",</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++                &verify2</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ static void init_media_type(pjsip_media_type *mt,</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -87,6 +122,192 @@ static void init_media_type(pjsip_media_type *mt,</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++static int verify_hdr(pj_pool_t *pool, pjsip_msg_body *multipart_body,</span><br><span style="color: hsl(120, 100%, 40%);">++    void *hdr, char *part_body)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_media_type mt;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_multipart_part *part;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t the_body;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    part = pjsip_multipart_find_part_by_header(pool, multipart_body, hdr, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!part) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return -1;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    the_body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(120, 100%, 40%);">++    the_body.slen = part->body->len;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    if (pj_strcmp2(&the_body, part_body) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return -2;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++static int verify_cid_str(pj_pool_t *pool, pjsip_msg_body *multipart_body,</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t cid_url, char *part_body)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_media_type mt;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_multipart_part *part;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t the_body;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    part = pjsip_multipart_find_part_by_cid_str(pool, multipart_body, &cid_url);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!part) {</span><br><span style="color: hsl(120, 100%, 40%);">++    return -3;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    the_body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(120, 100%, 40%);">++    the_body.slen = part->body->len;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    if (pj_strcmp2(&the_body, part_body) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return -4;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++static int verify_cid_uri(pj_pool_t *pool, pjsip_msg_body *multipart_body,</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_other_uri *cid_uri, char *part_body)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_media_type mt;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_multipart_part *part;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_str_t the_body;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    part = pjsip_multipart_find_part_by_cid_uri(pool, multipart_body, cid_uri);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!part) {</span><br><span style="color: hsl(120, 100%, 40%);">++ return -5;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    the_body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(120, 100%, 40%);">++    the_body.slen = part->body->len;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    if (pj_strcmp2(&the_body, part_body) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return -6;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">++    int rcbase = 300;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_other_uri *cid_uri;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_ctype_hdr *ctype_hdr = pjsip_ctype_hdr_create(pool);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    ctype_hdr->media.type = pj_str("application");</span><br><span style="color: hsl(120, 100%, 40%);">++    ctype_hdr->media.subtype = pj_str("pidf+xml");</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_hdr(pool, body, ctype_hdr, "has header2");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("cid:header1@example.org"), "has header1");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++    return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("%22header1%22@example.org"), "has header1");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++  return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:%22header1%22@example.org>",</span><br><span style="color: hsl(120, 100%, 40%);">++  strlen("<cid:%22header1%22@example.org>"), 0));</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_uri(pool, body, cid_uri, "has header1");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++ return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("<cid:my%20header2@example.org>"), "has header2");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++       return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("cid:my%ffheader2@example.org"), "has header2");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++       return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%ffheader2@example.org>",</span><br><span style="color: hsl(120, 100%, 40%);">++   strlen("<cid:my%ffheader2@example.org>"), 0));</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_uri(pool, body, cid_uri, "has header2");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++  return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("cid:my%20header3@example.org"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++       return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("<cid:my%20header4@example.org>"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++       return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%20header4@example.org>",</span><br><span style="color: hsl(120, 100%, 40%);">++   strlen("<cid:my%20header4@example.org>"), 0));</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_uri(pool, body, cid_uri, "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++  return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("<my%20header3@example.org>"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++   return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* These should all fail for malformed or missing URI */</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("cid:"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++       return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str(""), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++  return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("<>"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++  return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("<cid>"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (!rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++       return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /*</span><br><span style="color: hsl(120, 100%, 40%);">++     * This is going to pass but the ' ' in the uri is un-encoded which is invalid</span><br><span style="color: hsl(120, 100%, 40%);">++     * so we should never see it.</span><br><span style="color: hsl(120, 100%, 40%);">++     */</span><br><span style="color: hsl(120, 100%, 40%);">++    rcbase += 10;</span><br><span style="color: hsl(120, 100%, 40%);">++    rc = verify_cid_str(pool, body, pj_str("cid:my header3@example.org"), "has header4");</span><br><span style="color: hsl(120, 100%, 40%);">++    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">++     return (rc - rcbase);</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+ static int verify_part(pjsip_multipart_part *part,</span><br><span style="color: hsl(120, 100%, 40%);">+                 char *h_content_type,</span><br><span style="color: hsl(120, 100%, 40%);">+                 char *h_content_subtype,</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -236,8 +457,10 @@ static int parse_test(void)</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+  pj_strdup2_with_null(pool, &str, p_tests[i].msg);</span><br><span style="color: hsl(120, 100%, 40%);">+         body = pjsip_multipart_parse(pool, str.ptr, str.slen, &ctype, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+-        if (!body)</span><br><span style="color: hsl(120, 100%, 40%);">++   if (!body) {</span><br><span style="color: hsl(120, 100%, 40%);">++     pj_pool_release(pool);</span><br><span style="color: hsl(120, 100%, 40%);">+        return -100;</span><br><span style="color: hsl(120, 100%, 40%);">++     }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+  if (p_tests[i].verify) {</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = p_tests[i].verify(pool, body);</span><br><span style="color: hsl(120, 100%, 40%);">+-- </span><br><span style="color: hsl(120, 100%, 40%);">+2.34.1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/17919">change 17919</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/17919"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I6aee3dcf59eb171f93aae0f0564ff907262ef40d </div>
<div style="display:none"> Gerrit-Change-Number: 17919 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-CC: Stanislav Abramenkov <stas.abramenkov@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>