Skip to content

Commit 11373d2

Browse files
authored
Handle empty elements in generic array header parsing (Supported, Accept, Allow) (#4655)
1 parent 3a5dfe4 commit 11373d2

File tree

2 files changed

+152
-11
lines changed

2 files changed

+152
-11
lines changed

pjsip/src/pjsip/sip_parser.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,8 @@ PJ_DEF(void) pjsip_parse_end_hdr_imp( pj_scanner *scanner )
17631763
static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
17641764
pj_scanner *scanner)
17651765
{
1766+
pj_str_t elem;
1767+
17661768
/* Some header fields allow empty elements in the value:
17671769
* Accept, Allow, Supported
17681770
*/
@@ -1778,17 +1780,34 @@ static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
17781780
return;
17791781
}
17801782

1781-
pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE,
1782-
&hdr->values[hdr->count]);
1783-
hdr->count++;
1784-
1785-
while ((hdr->count < PJSIP_GENERIC_ARRAY_MAX_COUNT) &&
1786-
(*scanner->curptr == ','))
1783+
/* Parse array elements, skipping any empty elements (for buggy clients).
1784+
* Scanner is configured with PJ_SCAN_AUTOSKIP_WS_HEADER, so whitespace
1785+
* is automatically skipped after getting comma or element.
1786+
*/
1787+
while (hdr->count < PJ_ARRAY_SIZE(hdr->values))
17871788
{
1788-
pj_scan_get_char(scanner);
1789-
pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE,
1790-
&hdr->values[hdr->count]);
1791-
hdr->count++;
1789+
/* Skip any leading/consecutive commas */
1790+
while (*scanner->curptr == ',') {
1791+
pj_scan_get_char(scanner);
1792+
}
1793+
1794+
/* Check for end of header */
1795+
if (pj_scan_is_eof(scanner) ||
1796+
*scanner->curptr == '\r' || *scanner->curptr == '\n')
1797+
{
1798+
break;
1799+
}
1800+
1801+
/* Get element */
1802+
pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, &elem);
1803+
if (elem.slen > 0) {
1804+
hdr->values[hdr->count++] = elem;
1805+
}
1806+
1807+
/* If not followed by comma, we're done */
1808+
if (*scanner->curptr != ',') {
1809+
break;
1810+
}
17921811
}
17931812

17941813
end:

pjsip/src/test/msg_test.c

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,10 @@ static int hdr_test_from(pjsip_hdr *h);
948948
static int hdr_test_proxy_authenticate(pjsip_hdr *h);
949949
static int hdr_test_record_route(pjsip_hdr *h);
950950
static int hdr_test_supported(pjsip_hdr *h);
951+
static int hdr_test_supported_with_leading_comma(pjsip_hdr *h);
952+
static int hdr_test_supported_with_trailing_comma(pjsip_hdr *h);
953+
static int hdr_test_supported_with_multiple_commas(pjsip_hdr *h);
954+
static int hdr_test_supported_with_middle_commas(pjsip_hdr *h);
951955
static int hdr_test_to(pjsip_hdr *h);
952956
static int hdr_test_via(pjsip_hdr *h);
953957
static int hdr_test_via_ipv6_1(pjsip_hdr *h);
@@ -1128,7 +1132,39 @@ struct hdr_test_t
11281132
/* Empty Supported */
11291133
"Supported", "k",
11301134
"",
1131-
&hdr_test_supported,
1135+
&hdr_test_supported
1136+
},
1137+
1138+
{
1139+
/* Supported with leading comma (buggy MizuDroid format) */
1140+
"Supported", "k",
1141+
",outbound",
1142+
&hdr_test_supported_with_leading_comma,
1143+
HDR_FLAG_DONT_PRINT
1144+
},
1145+
1146+
{
1147+
/* Supported with trailing comma */
1148+
"Supported", "k",
1149+
"outbound,",
1150+
&hdr_test_supported_with_trailing_comma,
1151+
HDR_FLAG_DONT_PRINT
1152+
},
1153+
1154+
{
1155+
/* Supported with multiple consecutive commas at beginning */
1156+
"Supported", "k",
1157+
",,,outbound,path",
1158+
&hdr_test_supported_with_multiple_commas,
1159+
HDR_FLAG_DONT_PRINT
1160+
},
1161+
1162+
{
1163+
/* Supported with multiple consecutive commas in middle */
1164+
"Supported", "k",
1165+
"outbound,,,path",
1166+
&hdr_test_supported_with_middle_commas,
1167+
HDR_FLAG_DONT_PRINT
11321168
},
11331169

11341170
{
@@ -1735,6 +1771,92 @@ static int hdr_test_supported(pjsip_hdr *h)
17351771
return 0;
17361772
}
17371773

1774+
/*
1775+
",outbound"
1776+
Test for handling leading comma (buggy MizuDroid format)
1777+
*/
1778+
static int hdr_test_supported_with_leading_comma(pjsip_hdr *h)
1779+
{
1780+
pjsip_supported_hdr *hdr = (pjsip_supported_hdr*)h;
1781+
1782+
if (h->type != PJSIP_H_SUPPORTED)
1783+
return -2330;
1784+
1785+
if (hdr->count != 1)
1786+
return -2331;
1787+
1788+
if (pj_strcmp2(&hdr->values[0], "outbound") != 0)
1789+
return -2332;
1790+
1791+
return 0;
1792+
}
1793+
1794+
/*
1795+
"outbound,"
1796+
Test for handling trailing comma
1797+
*/
1798+
static int hdr_test_supported_with_trailing_comma(pjsip_hdr *h)
1799+
{
1800+
pjsip_supported_hdr *hdr = (pjsip_supported_hdr*)h;
1801+
1802+
if (h->type != PJSIP_H_SUPPORTED)
1803+
return -2340;
1804+
1805+
if (hdr->count != 1)
1806+
return -2341;
1807+
1808+
if (pj_strcmp2(&hdr->values[0], "outbound") != 0)
1809+
return -2342;
1810+
1811+
return 0;
1812+
}
1813+
1814+
/*
1815+
",,,outbound,path"
1816+
Test for handling multiple consecutive commas at beginning
1817+
*/
1818+
static int hdr_test_supported_with_multiple_commas(pjsip_hdr *h)
1819+
{
1820+
pjsip_supported_hdr *hdr = (pjsip_supported_hdr*)h;
1821+
1822+
if (h->type != PJSIP_H_SUPPORTED)
1823+
return -2350;
1824+
1825+
if (hdr->count != 2)
1826+
return -2351;
1827+
1828+
if (pj_strcmp2(&hdr->values[0], "outbound") != 0)
1829+
return -2352;
1830+
1831+
if (pj_strcmp2(&hdr->values[1], "path") != 0)
1832+
return -2353;
1833+
1834+
return 0;
1835+
}
1836+
1837+
/*
1838+
"outbound,,,path"
1839+
Test for handling multiple consecutive commas in middle
1840+
*/
1841+
static int hdr_test_supported_with_middle_commas(pjsip_hdr *h)
1842+
{
1843+
pjsip_supported_hdr *hdr = (pjsip_supported_hdr*)h;
1844+
1845+
if (h->type != PJSIP_H_SUPPORTED)
1846+
return -2360;
1847+
1848+
if (hdr->count != 2)
1849+
return -2361;
1850+
1851+
if (pj_strcmp2(&hdr->values[0], "outbound") != 0)
1852+
return -2362;
1853+
1854+
if (pj_strcmp2(&hdr->values[1], "path") != 0)
1855+
return -2363;
1856+
1857+
return 0;
1858+
}
1859+
17381860
/*
17391861
NAME_ADDR GENERIC_PARAM,
17401862
*/

0 commit comments

Comments
 (0)